diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000..0fd168e5a --- /dev/null +++ b/.clang-format @@ -0,0 +1,66 @@ +# Generated from CLion C/C++ Code Style settings +BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: None +AlignOperands: Align +AllowAllArgumentsOnNextLine: false +AllowAllConstructorInitializersOnNextLine: false +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: Always +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Always +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterReturnType: None +AlwaysBreakTemplateDeclarations: Yes +BreakBeforeBraces: Custom +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: true +BreakBeforeBinaryOperators: None +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeColon +BreakInheritanceList: BeforeColon +ColumnLimit: 0 +CompactNamespaces: false +ContinuationIndentWidth: 4 +IndentCaseLabels: true +IndentPPDirectives: BeforeHash +IndentWidth: 2 +KeepEmptyLinesAtTheStartOfBlocks: true +MaxEmptyLinesToKeep: 2 +NamespaceIndentation: All +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PointerAlignment: Right +ReflowComments: false +SpaceAfterCStyleCast: true +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 0 +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInContainerLiterals: true +SpacesInParentheses: false +SpacesInSquareBrackets: false +TabWidth: 2 +UseTab: Never diff --git a/.github/actions/prepare_build/action.yml b/.github/actions/prepare_build/action.yml new file mode 100644 index 000000000..5f2c544c1 --- /dev/null +++ b/.github/actions/prepare_build/action.yml @@ -0,0 +1,30 @@ +name: Prepare to build + +inputs: + family: + required: true + type: string + +runs: + using: "composite" + steps: + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Checkout pico-sdk for rp2040 + if: contains(inputs.family, 'rp2040') + uses: actions/checkout@v4 + with: + repository: raspberrypi/pico-sdk + ref: develop + path: pico-sdk + + - name: Get Dependencies + run: | + sudo apt install -y ninja-build + pip install click + python3 tools/get_deps.py ${{ inputs.family }} + echo >> $GITHUB_ENV "PICO_SDK_PATH=$GITHUB_WORKSPACE/pico-sdk" + shell: bash diff --git a/.github/actions/setup_toolchain/action.yml b/.github/actions/setup_toolchain/action.yml new file mode 100644 index 000000000..b59ece116 --- /dev/null +++ b/.github/actions/setup_toolchain/action.yml @@ -0,0 +1,31 @@ +name: Setup Toolchain + +inputs: + toolchain: + required: true + type: string + toolchain_url: + required: false + type: string + +runs: + using: "composite" + steps: + - name: Install ARM GCC + if: inputs.toolchain == 'arm-gcc' + uses: carlosperate/arm-none-eabi-gcc-action@v1 + with: + release: '12.3.Rel1' + + - name: Pull ESP-IDF docker + if: inputs.toolchain == 'esp-idf' + run: docker pull espressif/idf:latest + shell: bash + + - name: Download Toolchain + if: >- + inputs.toolchain != 'arm-gcc' && + inputs.toolchain != 'esp-idf' + uses: ./.github/actions/setup_toolchain/download + with: + toolchain_url: ${{ inputs.toolchain_url }} diff --git a/.github/actions/setup_toolchain/download/action.yml b/.github/actions/setup_toolchain/download/action.yml new file mode 100644 index 000000000..db85e9027 --- /dev/null +++ b/.github/actions/setup_toolchain/download/action.yml @@ -0,0 +1,29 @@ +name: Download Toolchain + +inputs: + toolchain_url: + required: true + type: string + +runs: + using: "composite" + steps: + - name: Cache Toolchain + uses: actions/cache@v4 + id: cache-toolchain + with: + path: ~/cache/toolchain + key: ${{ runner.os }}-${{ inputs.toolchain_url }} + + - name: Install Toolchain + if: steps.cache-toolchain.outputs.cache-hit != 'true' + run: | + mkdir -p ~/cache/toolchain + wget --progress=dot:mega ${{ inputs.toolchain_url }} -O toolchain.tar.gz + tar -C ~/cache/toolchain -xaf toolchain.tar.gz + shell: bash + + - name: Set Toolchain Path + run: | + echo >> $GITHUB_PATH `echo ~/cache/toolchain/*/bin` + shell: bash diff --git a/.github/workflows/build_aarch64.yml b/.github/workflows/build_aarch64.yml deleted file mode 100644 index 6ac7ad015..000000000 --- a/.github/workflows/build_aarch64.yml +++ /dev/null @@ -1,84 +0,0 @@ -name: Build AArch64 - -on: - workflow_dispatch: - push: - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - '.github/workflows/build_aarch64.yml' - pull_request: - branches: [ master ] - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - '.github/workflows/build_aarch64.yml' - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - # --------------------------------------- - # Build AARCH64 family - # --------------------------------------- - build-arm: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - family: - # Alphabetical order - - 'broadcom_64bit' - steps: - - name: Setup Python - uses: actions/setup-python@v4 - with: - python-version: '3.x' - - - name: Checkout TinyUSB - uses: actions/checkout@v3 - - - name: Checkout hathach/linkermap - uses: actions/checkout@v3 - with: - repository: hathach/linkermap - path: linkermap - - - name: Set Toolchain URL - run: echo >> $GITHUB_ENV TOOLCHAIN_URL=https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz - - - name: Cache Toolchain - uses: actions/cache@v3 - id: cache-toolchain - with: - path: ~/cache/ - key: ${{ runner.os }}-21-11-02-${{ env.TOOLCHAIN_URL }} - - - name: Install Toolchain - if: steps.cache-toolchain.outputs.cache-hit != 'true' - run: | - mkdir -p ~/cache/toolchain - wget --progress=dot:mega $TOOLCHAIN_URL -O toolchain.tar.gz - tar -C ~/cache/toolchain -xaf toolchain.tar.gz - - - name: Set Toolchain Path - run: echo >> $GITHUB_PATH `echo ~/cache/toolchain/*/bin` - - - name: Get Dependencies - run: python3 tools/get_deps.py ${{ matrix.family }} - - - name: Build - run: python3 tools/build_family.py ${{ matrix.family }} - - - name: Linker Map - run: | - pip install linkermap/ - for ex in `ls -d examples/device/*/`; do \ - find ${ex} -name *.map -print -quit | \ - xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"'; \ - done diff --git a/.github/workflows/build_arm.yml b/.github/workflows/build_arm.yml deleted file mode 100644 index 2621e7372..000000000 --- a/.github/workflows/build_arm.yml +++ /dev/null @@ -1,81 +0,0 @@ -name: Build ARM - -on: - workflow_dispatch: - push: - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - '.github/workflows/build_arm.yml' - pull_request: - branches: [ master ] - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - '.github/workflows/build_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 - - 'broadcom_32bit' - - 'kinetis_k32l2' - - 'lpc11 lpc13 lpc15 lpc17' - - 'lpc51 lpc54' - - 'mm32 msp432e4' - - 'nrf' - - 'samd11 samd21' - - 'samd51 same5x' - - 'saml2x' - - 'stm32f2 stm32f3' - - 'stm32l0 stm32u5 stm32wb' - - 'tm4c123 xmc4000' - 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: Checkout TinyUSB - uses: actions/checkout@v3 - - - name: Checkout hathach/linkermap - uses: actions/checkout@v3 - with: - repository: hathach/linkermap - path: linkermap - - - name: Get Dependencies - run: python3 tools/get_deps.py ${{ matrix.family }} - - - name: Build - run: python3 tools/build_family.py ${{ matrix.family }} - - - name: Linker Map - run: | - pip install linkermap/ - # find -quit to only print linkermap of 1 board per example - for ex in `ls -d examples/*/*/` - do - find ${ex} -name *.map -print -quit | xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"' - done diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml new file mode 100644 index 000000000..b62a0e9bd --- /dev/null +++ b/.github/workflows/build_cmake.yml @@ -0,0 +1,93 @@ +name: Build + +on: + workflow_dispatch: + push: + paths: + - 'src/**' + - 'examples/**' + - 'lib/**' + - 'hw/**' + - 'tools/get_deps.py' + - 'tools/build.py' + - '.github/actions/**' + - '.github/workflows/build_cmake.yml' + - '.github/workflows/ci_set_matrix.py' + pull_request: + branches: [ master ] + paths: + - 'src/**' + - 'examples/**' + - 'lib/**' + - 'hw/**' + - 'tools/get_deps.py' + - 'tools/build.py' + - '.github/actions/**' + - '.github/workflows/build_cmake.yml' + - '.github/workflows/ci_set_matrix.py' +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + set-matrix: + runs-on: ubuntu-latest + outputs: + json: ${{ steps.set-matrix-json.outputs.matrix }} + steps: + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Checkout TinyUSB + uses: actions/checkout@v4 + + - name: Generate matrix json + id: set-matrix-json + run: | + MATRIX_JSON=$(python .github/workflows/ci_set_matrix.py) + echo "matrix=$MATRIX_JSON" + echo "matrix=$MATRIX_JSON" >> $GITHUB_OUTPUT + + # --------------------------------------- + # Build CMake + # --------------------------------------- + cmake: + needs: set-matrix + uses: ./.github/workflows/build_family.yml + strategy: + fail-fast: false + matrix: + toolchain: + - 'aarch64-gcc' + - 'arm-clang' + - 'arm-gcc' + - 'msp430-gcc' + - 'riscv-gcc' + with: + build-system: 'cmake' + toolchain: ${{ matrix.toolchain }} + toolchain_url: ${{ fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].toolchain_url }} + build-family: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }} + + # --------------------------------------- + # Build Make + # --------------------------------------- + make: + needs: set-matrix + uses: ./.github/workflows/build_family.yml + strategy: + fail-fast: false + matrix: + toolchain: + - 'aarch64-gcc' + #- 'arm-clang' + - 'arm-gcc' + - 'msp430-gcc' + - 'riscv-gcc' + with: + build-system: 'make' + toolchain: ${{ matrix.toolchain }} + toolchain_url: ${{ fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].toolchain_url }} + build-family: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }} diff --git a/.github/workflows/build_esp.yml b/.github/workflows/build_esp.yml index 29585cb36..66fa8548e 100644 --- a/.github/workflows/build_esp.yml +++ b/.github/workflows/build_esp.yml @@ -8,6 +8,7 @@ on: - 'examples/**' - 'lib/**' - 'hw/**' + - 'test/hil/**' - '.github/workflows/build_esp.yml' pull_request: branches: [ master ] @@ -16,6 +17,7 @@ on: - 'examples/**' - 'lib/**' - 'hw/**' + - 'test/hil/**' - '.github/workflows/build_esp.yml' concurrency: @@ -29,39 +31,79 @@ jobs: fail-fast: false matrix: board: - # Alphabetical order # ESP32-S2 - - 'espressif_saola_1' + - 'espressif_kaluga_1' # ESP32-S3 - #- 'espressif_s3_devkitm' - # S3 compile error with "dangerous relocation: call8: call target out of range: memcpy" - + - 'espressif_s3_devkitm' steps: - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.x' - - name: Pull ESP-IDF docker - run: docker pull espressif/idf:latest - - name: Checkout TinyUSB - uses: actions/checkout@v3 + uses: actions/checkout@v4 - - name: Checkout hathach/linkermap - uses: actions/checkout@v3 + - name: Setup Toolchain + uses: ./.github/actions/setup_toolchain with: - repository: hathach/linkermap - path: linkermap + toolchain: 'esp-idf' - name: Build - run: docker run --rm -v $PWD:/project -w /project espressif/idf:latest python3 tools/build_esp32.py ${{ matrix.board }} + run: docker run --rm -v $PWD:/project -w /project espressif/idf:v5.1.1 python3 tools/build.py -b ${{ matrix.board }} - - name: Linker Map - run: | - pip install linkermap/ - # find -quit to only print linkermap of 1 board per example - for ex in `ls -d examples/device/*/` - do - find ${ex} -maxdepth 3 -name *.map -print -quit | xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"' - done + - name: Upload Artifacts for Hardware Testing + if: matrix.board == 'espressif_s3_devkitm' && github.repository_owner == 'hathach' + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.board }} + path: | + cmake-build/cmake-build-${{ matrix.board }}/*/*/bootloader/bootloader.bin + cmake-build/cmake-build-${{ matrix.board }}/*/*/*.bin + cmake-build/cmake-build-${{ matrix.board }}/*/*/partition_table/partition-table.bin + cmake-build/cmake-build-${{ matrix.board }}/*/*/config.env + cmake-build/cmake-build-${{ matrix.board }}/*/*/flash_args + + # --------------------------------------- + # Hardware in the loop (HIL) + # Current self-hosted instance is running on an RPI4. For attached hardware checkout hil_pi4.json + # --------------------------------------- + hil-test: + # run only with hathach's commit due to limited resource on RPI4 + if: github.repository_owner == 'hathach' + needs: build-esp + runs-on: [self-hosted, esp32s3, hardware-in-the-loop] + strategy: + fail-fast: false + matrix: + board: + - 'espressif_s3_devkitm' + steps: + - name: Clean workspace + run: | + echo "Cleaning up previous run" + rm -rf "${{ github.workspace }}" + mkdir -p "${{ github.workspace }}" + + # USB bus on rpi4 is not stable, reset it before testing + - name: Reset USB bus + run: | + lsusb + lsusb -t + # reset VIA Labs 2.0 hub + sudo usbreset 001/002 + + - name: Checkout test/hil + uses: actions/checkout@v4 + with: + sparse-checkout: test/hil + + - name: Download Artifacts + uses: actions/download-artifact@v4 + with: + name: ${{ matrix.board }} + path: cmake-build/cmake-build-${{ matrix.board }} + + - name: Test on actual hardware + run: | + python3 test/hil/hil_test.py --board ${{ matrix.board }} pi4_esp32.json diff --git a/.github/workflows/build_family.yml b/.github/workflows/build_family.yml new file mode 100644 index 000000000..2e89267a3 --- /dev/null +++ b/.github/workflows/build_family.yml @@ -0,0 +1,64 @@ +name: Build family + +on: + workflow_call: + inputs: + build-system: + required: true + type: string + toolchain: + required: true + type: string + toolchain_url: + required: true + type: string + build-family: + required: true + type: string + +jobs: + family: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + family: ${{ fromJSON(inputs.build-family) }} + steps: + - name: Checkout TinyUSB + uses: actions/checkout@v4 + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Setup Toolchain + uses: ./.github/actions/setup_toolchain + with: + toolchain: ${{ inputs.toolchain }} + toolchain_url: ${{ inputs.toolchain_url }} + + - name: Checkout pico-sdk for rp2040 + if: contains(matrix.family, 'rp2040') + uses: actions/checkout@v4 + with: + repository: raspberrypi/pico-sdk + ref: develop + path: pico-sdk + + - name: Get Dependencies + run: | + sudo apt install -y ninja-build + pip install click + python3 tools/get_deps.py ${{ matrix.family }} + + - name: Build + run: | + OPTION="" + if [[ "${{ inputs.toolchain }}" == *"clang"* ]]; then + OPTION="--toolchain clang" + fi + echo "OPTION=$OPTION" + python tools/build.py -s ${{ inputs.build-system }} $OPTION ${{ matrix.family }} + env: + PICO_SDK_PATH: ${{ github.workspace }}/pico-sdk diff --git a/.github/workflows/build_iar.yml b/.github/workflows/build_iar.yml index 454ad12fe..c4a7f96b7 100644 --- a/.github/workflows/build_iar.yml +++ b/.github/workflows/build_iar.yml @@ -8,6 +8,8 @@ on: - 'examples/**' - 'lib/**' - 'hw/**' + - 'tools/get_deps.py' + - 'test/hil/**' - '.github/workflows/build_iar.yml' pull_request: branches: [ master ] @@ -16,6 +18,8 @@ on: - 'examples/**' - 'lib/**' - 'hw/**' + - 'tools/get_deps.py' + - 'test/hil/**' - '.github/workflows/build_iar.yml' concurrency: @@ -24,6 +28,7 @@ concurrency: jobs: cmake: + if: github.repository_owner == 'hathach' runs-on: [self-hosted, Linux, X64, hifiphile] strategy: fail-fast: false @@ -32,7 +37,7 @@ jobs: # Alphabetical order # Note: bundle multiple families into a matrix since there is only one self-hosted instance can # run IAR build. Too many matrix can hurt due to setup/teardown overhead. - - 'stm32f0 stm32f1 stm32f7 stm32g0 stm32g4 stm32h7 stm32l4' + - 'lpc43 stm32f0 stm32f1 stm32f7 stm32g0 stm32g4 stm32l4' steps: - name: Clean workspace run: | @@ -41,90 +46,14 @@ jobs: mkdir -p "${{ github.workspace }}" - name: Checkout TinyUSB - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Get Dependencies run: python3 tools/get_deps.py ${{ matrix.family }} - name: Build - run: python3 tools/build_cmake.py ${{ matrix.family }} -DTOOLCHAIN=iar -DCMAKE_BUILD_TYPE=MinSizeRel + run: python3 tools/build.py --toolchain iar ${{ matrix.family }} - # Upload binaries for hardware test with self-hosted - - name: Prepare stm32l412nucleo Artifacts - if: contains(matrix.family, 'stm32l4') - working-directory: ${{github.workspace}}/cmake-build/cmake-build-stm32l412nucleo + - name: Test on actual hardware (hardware in the loop) run: | - find device/ -name "*.elf" -exec mv {} ../../ \; - - - name: Upload Artifacts for stm32l412nucleo - if: contains(matrix.family, 'stm32l4') && github.repository_owner == 'hathach' - uses: actions/upload-artifact@v3 - with: - name: stm32l4 - path: | - *.elf - - # --------------------------------------- - # Hardware in the loop (HIL) - # Current self-hosted instance is running on an EPYC 7232 server hosted by HiFiPhile user - # - STM32L412 Nucleo with on-board jlink as ttyACM0 - # --------------------------------------- - hw-stm32l412nucleo-test: - needs: cmake - runs-on: [self-hosted, Linux, X64, hifiphile] - - steps: - - name: Clean workspace - run: | - echo "Cleaning up previous run" - rm -rf "${{ github.workspace }}" - mkdir -p "${{ github.workspace }}" - - - name: Download stm32l4 Artifacts - uses: actions/download-artifact@v3 - with: - name: stm32l4 - - - name: Create flash.sh - run: | - echo > flash.sh 'echo halt > flash.jlink' - echo >> flash.sh 'echo r >> flash.jlink' - echo >> flash.sh 'echo loadfile $1 >> flash.jlink' - echo >> flash.sh 'echo r >> flash.jlink' - echo >> flash.sh 'echo go >> flash.jlink' - echo >> flash.sh 'echo exit >> flash.jlink' - echo >> flash.sh 'cmdout=$(JLinkExe -USB 774470029 -device stm32l412kb -if swd -JTAGConf -1,-1 -speed auto -NoGui 1 -ExitOnError 1 -CommandFile flash.jlink)' - echo >> flash.sh 'if (( $? )) ; then echo $cmdout ; fi' - chmod +x flash.sh - - - name: Test cdc_dual_ports - run: | - ./flash.sh cdc_dual_ports.elf - while (! ([ -e /dev/ttyACM1 ] && [ -e /dev/ttyACM2 ])) && [ $SECONDS -le 10 ]; do :; done - test -e /dev/ttyACM1 && echo "ttyACM1 exists" - test -e /dev/ttyACM2 && echo "ttyACM2 exists" - - # Debian does not auto mount usb drive. skip this test for now - - name: Test cdc_msc - if: false - run: | - ./flash.sh cdc_msc.elf - readme='/media/pi/TinyUSB MSC/README.TXT' - while (! ([ -e /dev/ttyACM1 ] && [ -f "$readme" ])) && [ $SECONDS -le 10 ]; do :; done - test -e /dev/ttyACM1 && echo "ttyACM1 exists" - test -f "$readme" && echo "$readme exists" - cat "$readme" - - - name: Test dfu - run: | - ./flash.sh dfu.elf - while (! (dfu-util -l | grep "Found DFU")) && [ $SECONDS -le 10 ]; do :; done - dfu-util -d cafe -a 0 -U dfu0 - dfu-util -d cafe -a 1 -U dfu1 - grep "TinyUSB DFU! - Partition 0" dfu0 - grep "TinyUSB DFU! - Partition 1" dfu1 - - - name: Test dfu_runtime - run: | - ./flash.sh dfu_runtime.elf - while (! (dfu-util -l | grep "Found Runtime")) && [ $SECONDS -le 10 ]; do :; done + python3 test/hil/hil_test.py hfp.json diff --git a/.github/workflows/build_msp430.yml b/.github/workflows/build_msp430.yml deleted file mode 100644 index c62056940..000000000 --- a/.github/workflows/build_msp430.yml +++ /dev/null @@ -1,83 +0,0 @@ -name: Build MSP430 - -on: - workflow_dispatch: - push: - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - '.github/workflows/build_msp430.yml' - pull_request: - branches: [ master ] - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - '.github/workflows/build_msp430.yml' - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - build-msp430: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - family: - # Alphabetical order - - 'msp430' - - steps: - - name: Setup Python - uses: actions/setup-python@v4 - with: - python-version: '3.x' - - - name: Checkout TinyUSB - uses: actions/checkout@v3 - - - name: Checkout hathach/linkermap - uses: actions/checkout@v3 - with: - repository: hathach/linkermap - path: linkermap - - - name: Set Toolchain URL - run: echo >> $GITHUB_ENV TOOLCHAIN_URL=http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSPGCC/9_2_0_0/export/msp430-gcc-9.2.0.50_linux64.tar.bz2 - - - name: Cache Toolchain - uses: actions/cache@v3 - id: cache-toolchain - with: - path: ~/cache/ - key: ${{ runner.os }}-21-03-04-${{ env.TOOLCHAIN_URL }} - - - name: Install Toolchain - if: steps.cache-toolchain.outputs.cache-hit != 'true' - run: | - mkdir -p ~/cache/toolchain - wget --progress=dot:mega $TOOLCHAIN_URL -O toolchain.tar.bz2 - tar -C ~/cache/toolchain -xaf toolchain.tar.bz2 - - - name: Set Toolchain Path - run: echo >> $GITHUB_PATH `echo ~/cache/toolchain/*/bin` - - - name: Get Dependencies - run: python3 tools/get_deps.py ${{ matrix.family }} - - - name: Build - run: python3 tools/build_family.py ${{ matrix.family }} - - - name: Linker Map - run: | - pip install linkermap/ - # find -quit to only print linkermap of 1 board per example - for ex in `ls -d examples/device/*/` - do - find ${ex} -name *.map -print -quit | xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"' - done diff --git a/.github/workflows/build_renesas.yml b/.github/workflows/build_renesas.yml index 66b98a71b..8c83bdbbf 100644 --- a/.github/workflows/build_renesas.yml +++ b/.github/workflows/build_renesas.yml @@ -8,6 +8,7 @@ on: - 'examples/**' - 'lib/**' - 'hw/**' + - 'tools/get_deps.py' - '.github/workflows/build_renesas.yml' pull_request: branches: [ master ] @@ -16,6 +17,7 @@ on: - 'examples/**' - 'lib/**' - 'hw/**' + - 'tools/get_deps.py' - '.github/workflows/build_renesas.yml' concurrency: @@ -33,24 +35,18 @@ jobs: - 'rx' steps: - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.x' - name: Checkout TinyUSB - uses: actions/checkout@v3 - - - name: Checkout hathach/linkermap - uses: actions/checkout@v3 - with: - repository: hathach/linkermap - path: linkermap + uses: actions/checkout@v4 - name: Set Toolchain URL run: echo >> $GITHUB_ENV TOOLCHAIN_URL=http://gcc-renesas.com/downloads/get.php?f=rx/8.3.0.202004-gnurx/gcc-8.3.0.202004-GNURX-ELF.run - name: Cache Toolchain - uses: actions/cache@v3 + uses: actions/cache@v4 id: cache-toolchain with: path: ~/cache/ @@ -68,16 +64,9 @@ jobs: run: echo >> $GITHUB_PATH `echo ~/cache/toolchain/*/bin` - name: Get Dependencies - run: python3 tools/get_deps.py ${{ matrix.family }} + run: | + pip install click + python3 tools/get_deps.py ${{ matrix.family }} - name: Build - run: python3 tools/build_family.py ${{ matrix.family }} - - - name: Linker Map - run: | - pip install linkermap/ - # find -quit to only print linkermap of 1 board per example - for ex in `ls -d examples/device/*/` - do - find ${ex} -name *.map -print -quit | xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"' - done + run: python3 tools/build.py -s make ${{ matrix.family }} diff --git a/.github/workflows/build_riscv.yml b/.github/workflows/build_riscv.yml deleted file mode 100644 index 8ec549072..000000000 --- a/.github/workflows/build_riscv.yml +++ /dev/null @@ -1,84 +0,0 @@ -name: Build RISC-V - -on: - workflow_dispatch: - push: - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - '.github/workflows/build_riscv.yml' - pull_request: - branches: [ master ] - paths: - - 'src/**' - - 'examples/**' - - 'lib/**' - - 'hw/**' - - '.github/workflows/build_riscv.yml' - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - build-riscv: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - family: - # Alphabetical order - - 'ch32v307' - - 'fomu' - - 'gd32vf103' - steps: - - name: Setup Python - uses: actions/setup-python@v4 - with: - python-version: '3.x' - - - name: Checkout TinyUSB - uses: actions/checkout@v3 - - - name: Checkout hathach/linkermap - uses: actions/checkout@v3 - with: - repository: hathach/linkermap - path: linkermap - - - name: Set Toolchain URL - run: echo >> $GITHUB_ENV TOOLCHAIN_URL=https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack/releases/download/v10.1.0-1.1/xpack-riscv-none-embed-gcc-10.1.0-1.1-linux-x64.tar.gz - - - name: Cache Toolchain - uses: actions/cache@v3 - id: cache-toolchain - with: - path: ~/cache/ - key: ${{ runner.os }}-21-03-04-${{ env.TOOLCHAIN_URL }} - - - name: Install Toolchain - if: steps.cache-toolchain.outputs.cache-hit != 'true' - run: | - mkdir -p ~/cache/toolchain - wget --progress=dot:mega $TOOLCHAIN_URL -O toolchain.tar.gz - tar -C ~/cache/toolchain -xaf toolchain.tar.gz - - - name: Set Toolchain Path - run: echo >> $GITHUB_PATH `echo ~/cache/toolchain/*/bin` - - - name: Get Dependencies - run: python3 tools/get_deps.py ${{ matrix.family }} - - - name: Build - run: python3 tools/build_family.py ${{ matrix.family }} - - - name: Linker Map - run: | - pip install linkermap/ - # find -quit to only print linkermap of 1 board per example - for ex in `ls -d examples/device/*/` - do - find ${ex} -name *.map -print -quit | xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"' - done diff --git a/.github/workflows/build_win_mac.yml b/.github/workflows/build_win_mac.yml index cb879a705..35328aa32 100644 --- a/.github/workflows/build_win_mac.yml +++ b/.github/workflows/build_win_mac.yml @@ -35,7 +35,7 @@ jobs: steps: - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.x' @@ -45,10 +45,12 @@ jobs: release: '10.3-2021.10' - name: Checkout TinyUSB - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Get Dependencies - run: python3 tools/get_deps.py stm32f4 + run: | + pip install click + python3 tools/get_deps.py stm32f4 - name: Build - run: python3 tools/build_family.py stm32f4 stm32f411disco + run: python3 tools/build.py -s make stm32f2 diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py new file mode 100644 index 000000000..2a17be6a1 --- /dev/null +++ b/.github/workflows/ci_set_matrix.py @@ -0,0 +1,51 @@ +import json + +# toolchain, url +toolchain_list = { + "aarch64-gcc": "https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz", + "arm-clang": "https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/releases/download/release-17.0.1/LLVMEmbeddedToolchainForArm-17.0.1-Linux-x86_64.tar.xz", + "arm-gcc": "", + "msp430-gcc": "http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSPGCC/9_2_0_0/export/msp430-gcc-9.2.0.50_linux64.tar.bz2", + "riscv-gcc": "https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack/releases/download/v10.1.0-1.1/xpack-riscv-none-embed-gcc-10.1.0-1.1-linux-x64.tar.gz", +} + +# family: [supported toolchain] +family_list = { + "broadcom_32bit": ["arm-gcc"], + "broadcom_64bit": ["aarch64-gcc"], + "ch32v307 fomu gd32vf103": ["riscv-gcc"], + "imxrt": ["arm-gcc", "arm-clang"], + "kinetis_k kinetis_kl kinetis_k32l2": ["arm-gcc", "arm-clang"], + "lpc11 lpc13 lpc15": ["arm-gcc"], + "lpc17 lpc18 lpc40 lpc43": ["arm-gcc", "arm-clang"], + "lpc51 lpc54 lpc55": ["arm-gcc", "arm-clang"], + "mcx": ["arm-gcc"], + "mm32": ["arm-gcc"], + "msp430": ["msp430-gcc"], + "msp432e4 tm4c": ["arm-gcc"], + "nrf": ["arm-gcc", "arm-clang"], + "ra": ["arm-gcc"], + "rp2040": ["arm-gcc"], + "samd11 samd21 saml2x": ["arm-gcc", "arm-clang"], + "samd5x_e5x samg": ["arm-gcc", "arm-clang"], + "stm32f0 stm32f1 stm32f2 stm32f3": ["arm-gcc", "arm-clang"], + "stm32f4": ["arm-gcc", "arm-clang"], + "stm32f7": ["arm-gcc", "arm-clang"], + "stm32g0 stm32g4 stm32h5": ["arm-gcc", "arm-clang"], + "stm32h7": ["arm-gcc", "arm-clang"], + "stm32l4 stm32u5 stm32wb": ["arm-gcc", "arm-clang"], + "xmc4000": ["arm-gcc"], +} + + +def set_matrix_json(): + matrix = {} + for toolchain in toolchain_list.keys(): + filtered_families = [family for family, supported_toolchain in family_list.items() if + toolchain in supported_toolchain] + matrix[toolchain] = {"family": filtered_families, "toolchain_url": toolchain_list[toolchain]} + print(json.dumps(matrix)) + + +if __name__ == '__main__': + set_matrix_json() diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml index 4c4b12a6b..faa0f911c 100644 --- a/.github/workflows/cifuzz.yml +++ b/.github/workflows/cifuzz.yml @@ -12,6 +12,7 @@ on: - '**.h' jobs: Fuzzing: + if: false runs-on: ubuntu-latest steps: - name: Build Fuzzers @@ -20,14 +21,16 @@ jobs: with: oss-fuzz-project-name: 'tinyusb' language: c++ + - name: Run Fuzzers uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master with: oss-fuzz-project-name: 'tinyusb' language: c++ fuzz-seconds: 600 + - name: Upload Crash - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: failure() && steps.build.outcome == 'success' with: name: artifacts diff --git a/.github/workflows/cmake_arm.yml b/.github/workflows/cmake_arm.yml deleted file mode 100644 index 8eeae928c..000000000 --- a/.github/workflows/cmake_arm.yml +++ /dev/null @@ -1,160 +0,0 @@ -name: CMake ARM - -on: - workflow_dispatch: - 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' - - 'kinetis_kl' - - 'lpc18 lpc40 lpc43' - - 'lpc55' - - 'mcx' - - 'ra' - - 'rp2040' - - 'stm32f0' - - 'stm32f1' - - 'stm32f4' - - 'stm32f7' - - 'stm32g0' - - 'stm32g4' - - 'stm32h7' - - 'stm32l4' - 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: Checkout pico-sdk for rp2040 - if: matrix.family == 'rp2040' - uses: actions/checkout@v3 - with: - repository: raspberrypi/pico-sdk - ref: develop - path: pico-sdk - - - name: Get Dependencies - run: python3 tools/get_deps.py ${{ matrix.family }} - - - name: Build - run: python tools/build_cmake.py ${{ matrix.family }} -DCMAKE_BUILD_TYPE=MinSizeRel - env: - # for rp2040, there is no harm if defined for other families - PICO_SDK_PATH: ${{ github.workspace }}/pico-sdk - - # Upload binaries for hardware test with self-hosted - - name: Prepare rp2040 Artifacts - if: contains(matrix.family, 'rp2040') && github.repository_owner == 'hathach' - working-directory: ${{github.workspace}}/cmake-build/cmake-build-raspberry_pi_pico - run: | - find device/ -name "*.elf" -exec mv {} ../../ \; - # find host/ -name "*.elf" -exec mv {} ../../ \; - # find dual/ -name "*.elf" -exec mv {} ../../ \; - - - name: Upload Artifacts for rp2040 - if: contains(matrix.family,'rp2040') && github.repository_owner == 'hathach' - uses: actions/upload-artifact@v3 - with: - name: rp2040 - path: | - *.elf - - # --------------------------------------- - # Hardware in the loop (HIL) - # Current self-hosted instance is running on an RPI4 with - # - pico + pico-probe connected via USB - # - pico-probe is /dev/ttyACM0 - # --------------------------------------- - hw-rp2040-test: - # run only with hathach's commit due to limited resource on RPI4 - if: github.repository_owner == 'hathach' - needs: build-arm - runs-on: [self-hosted, Linux, ARM64, rp2040] - - steps: - - name: Clean workspace - run: | - echo "Cleaning up previous run" - rm -rf "${{ github.workspace }}" - mkdir -p "${{ github.workspace }}" - - - name: Download rp2040 Artifacts - uses: actions/download-artifact@v3 - with: - name: rp2040 - - - name: Create flash.sh - run: | - echo > flash.sh 'cmdout=$(openocd -f "interface/cmsis-dap.cfg" -f "target/rp2040.cfg" -c "adapter speed 5000" -c "program $1 reset exit")' - echo >> flash.sh 'if (( $? )) ; then echo $cmdout ; fi' - chmod +x flash.sh - - - name: Test cdc_dual_ports - run: | - ./flash.sh cdc_dual_ports.elf - while (! ([ -e /dev/ttyACM1 ] && [ -e /dev/ttyACM2 ])) && [ $SECONDS -le 10 ]; do :; done - test -e /dev/ttyACM1 && echo "ttyACM1 exists" - test -e /dev/ttyACM2 && echo "ttyACM2 exists" - - - name: Test cdc_msc - run: | - ./flash.sh cdc_msc.elf - readme='/media/pi/TinyUSB MSC/README.TXT' - while (! ([ -e /dev/ttyACM1 ] && [ -f "$readme" ])) && [ $SECONDS -le 10 ]; do :; done - test -e /dev/ttyACM1 && echo "ttyACM1 exists" - test -f "$readme" && echo "$readme exists" - cat "$readme" - - - name: Test dfu - run: | - ./flash.sh dfu.elf - while (! (dfu-util -l | grep "Found DFU")) && [ $SECONDS -le 10 ]; do :; done - dfu-util -d cafe -a 0 -U dfu0 - dfu-util -d cafe -a 1 -U dfu1 - grep "TinyUSB DFU! - Partition 0" dfu0 - grep "TinyUSB DFU! - Partition 1" dfu1 - - - name: Test dfu_runtime - run: | - ./flash.sh dfu_runtime.elf - while (! (dfu-util -l | grep "Found Runtime")) && [ $SECONDS -le 10 ]; do :; done diff --git a/.github/workflows/codeql-buildscript.sh b/.github/workflows/codeql-buildscript.sh new file mode 100644 index 000000000..272b55d22 --- /dev/null +++ b/.github/workflows/codeql-buildscript.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +FAMILY=stm32l4 +pip install click +python3 tools/get_deps.py $FAMILY +python3 tools/build.py -s make $FAMILY diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 000000000..1f7b60b9c --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,137 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ 'master' ] + paths: + - 'src/**' + - 'examples/**' + - 'lib/**' + - 'hw/**' + - '.github/workflows/codeql.yml' + pull_request: + branches: [ 'master' ] + paths: + - 'src/**' + - 'examples/**' + - 'lib/**' + - 'hw/**' + - '.github/workflows/codeql.yml' + schedule: + - cron: '0 0 * * *' + +jobs: + analyze: + name: Analyze + # Runner size impacts CodeQL analysis time. To learn more, please see: + # - https://gh.io/recommended-hardware-resources-for-running-codeql + # - https://gh.io/supported-runners-and-hardware-resources + # - https://gh.io/using-larger-runners + # Consider using larger runners for possible analysis time improvements. + runs-on: ubuntu-latest + timeout-minutes: 360 + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'c-cpp' ] + # CodeQL supports [ 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' ] + # Use only 'java-kotlin' to analyze code written in Java, Kotlin or both + # Use only 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install ARM GCC + uses: carlosperate/arm-none-eabi-gcc-action@v1 + with: + release: '11.2-2022.02' + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + queries: security-and-quality + + + # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift). + # If this step fails, then you should remove it and run the build manually (see below) + #- name: Autobuild + # uses: github/codeql-action/autobuild@v2 + + # ℹī¸ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + + - run: | + ./.github/workflows/codeql-buildscript.sh + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" + upload: false + id: step1 + + # Filter out rules with low severity or high false positive rate + # Also filter out warnings in third-party code + - name: Filter out unwanted errors and warnings + uses: advanced-security/filter-sarif@v1 + with: + patterns: | + -**:cpp/path-injection + -**:cpp/world-writable-file-creation + -**:cpp/poorly-documented-function + -**:cpp/potentially-dangerous-function + -**:cpp/use-of-goto + -**:cpp/integer-multiplication-cast-to-long + -**:cpp/comparison-with-wider-type + -**:cpp/leap-year/* + -**:cpp/ambiguously-signed-bit-field + -**:cpp/suspicious-pointer-scaling + -**:cpp/suspicious-pointer-scaling-void + -**:cpp/unsigned-comparison-zero + -**/third*party/** + -**/3rd*party/** + -**/external/** + input: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif + output: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif + + - name: Upload SARIF + uses: github/codeql-action/upload-sarif@v2 + with: + sarif_file: ${{ steps.step1.outputs.sarif-output }} + category: "/language:${{matrix.language}}" + + - name: Archive CodeQL results + uses: actions/upload-artifact@v4 + with: + name: codeql-results + path: ${{ steps.step1.outputs.sarif-output }} + retention-days: 5 diff --git a/.github/workflows/fail_on_error.py b/.github/workflows/fail_on_error.py new file mode 100755 index 000000000..29791742b --- /dev/null +++ b/.github/workflows/fail_on_error.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 + +import json +import sys + +# Return whether SARIF file contains error-level results +def codeql_sarif_contain_error(filename): + with open(filename, 'r') as f: + s = json.load(f) + + for run in s.get('runs', []): + rules_metadata = run['tool']['driver']['rules'] + if not rules_metadata: + rules_metadata = run['tool']['extensions'][0]['rules'] + + for res in run.get('results', []): + if 'ruleIndex' in res: + rule_index = res['ruleIndex'] + elif 'rule' in res and 'index' in res['rule']: + rule_index = res['rule']['index'] + else: + continue + try: + rule_level = rules_metadata[rule_index]['defaultConfiguration']['level'] + except IndexError as e: + print(e, rule_index, len(rules_metadata)) + else: + if rule_level == 'error': + return True + return False + +if __name__ == "__main__": + if codeql_sarif_contain_error(sys.argv[1]): + sys.exit(1) diff --git a/.github/workflows/hil_test.yml b/.github/workflows/hil_test.yml new file mode 100644 index 000000000..024ab969d --- /dev/null +++ b/.github/workflows/hil_test.yml @@ -0,0 +1,125 @@ +name: Hardware Test + +on: + workflow_dispatch: + push: + paths: + - 'src/**' + - 'examples/**' + - 'lib/**' + - 'hw/**' + - 'test/hil/**' + - 'tools/get_deps.py' + - '.github/actions/**' + - '.github/workflows/hil_test.yml' + pull_request: + branches: [ master ] + paths: + - 'src/**' + - 'examples/**' + - 'lib/**' + - 'hw/**' + - 'test/hil/**' + - 'tools/get_deps.py' + - '.github/actions/**' + - '.github/workflows/hil_test.yml' +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + build: + if: github.repository_owner == 'hathach' + runs-on: ubuntu-latest + outputs: + BOARD_LIST: ${{ steps.parse_hil_json.outputs.BOARD_LIST }} + steps: + - name: Checkout TinyUSB + uses: actions/checkout@v4 + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Install ARM GCC + uses: carlosperate/arm-none-eabi-gcc-action@v1 + with: + release: '12.3.Rel1' + + - name: Parse HIL json + id: parse_hil_json + run: | + sudo apt install -y jq + BOARD_LIST=$(jq -r '.boards[] | "-b " + .name' test/hil/pi4.json | tr '\n' ' ') + echo "BOARD_LIST=$BOARD_LIST" + echo >> $GITHUB_ENV "BOARD_LIST=$BOARD_LIST" + echo >> $GITHUB_OUTPUT "BOARD_LIST=$BOARD_LIST" + + - name: Checkout pico-sdk for rp2040 + uses: actions/checkout@v4 + with: + repository: raspberrypi/pico-sdk + ref: develop + path: pico-sdk + + - name: Get Dependencies + run: | + pip install click + sudo apt install -y ninja-build + python3 tools/get_deps.py $BOARD_LIST + + - name: Build + run: | + python tools/build.py $BOARD_LIST + env: + PICO_SDK_PATH: ${{ github.workspace }}/pico-sdk + + - name: Upload Artifacts for Hardware Testing + uses: actions/upload-artifact@v4 + with: + name: hil_pi4 + path: | + cmake-build/cmake-build-*/*/*/*.elf + cmake-build/cmake-build-*/*/*/*.bin + + # --------------------------------------- + # Hardware in the loop (HIL) + # Current self-hosted instance is running on an RPI4. For attached hardware checkout hil_pi4.json + # --------------------------------------- + hil-pi4: + if: github.repository_owner == 'hathach' + needs: build + runs-on: [self-hosted, rp2040, nrf52840, hardware-in-the-loop] + env: + BOARD_LIST: ${{ needs.build.outputs.BOARD_LIST }} + steps: + - name: Clean workspace + run: | + echo "Cleaning up previous run" + rm -rf "${{ github.workspace }}" + mkdir -p "${{ github.workspace }}" + + # USB bus on rpi4 is not stable, reset it before testing + - name: Reset USB bus + run: | + lsusb + lsusb -t + # reset VIA Labs 2.0 hub + sudo usbreset 001/002 + + - name: Checkout TinyUSB + uses: actions/checkout@v4 + with: + sparse-checkout: test/hil + + - name: Download Artifacts + uses: actions/download-artifact@v4 + with: + name: hil_pi4 + path: cmake-build + + - name: Test on actual hardware + run: | + echo "BOARD_LIST=$BOARD_LIST" + python3 test/hil/hil_test.py $BOARD_LIST pi4.json diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml new file mode 100644 index 000000000..c3cc59d0d --- /dev/null +++ b/.github/workflows/labeler.yml @@ -0,0 +1,73 @@ +name: Labeler + +on: + issues: + types: [opened] + pull_request_target: + types: [opened] + +jobs: + label-priority: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - name: Label New Issue or PR + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + let label = ''; + let username = ''; + let issueOrPrNumber = 0; + + if (context.eventName === 'issues') { + username = context.payload.issue.user.login; + issueOrPrNumber = context.payload.issue.number; + } else if (context.eventName === 'pull_request_target') { + username = context.payload.pull_request.user.login; + issueOrPrNumber = context.payload.pull_request.number; + } + + // Check if an Adafruit member + try { + const adafruitResponse = await github.rest.orgs.checkMembershipForUser({ + org: 'adafruit', + username: username + }); + + if (adafruitResponse.status === 204) { + console.log('Adafruit Member'); + label = 'Prio Urgent'; + } + } catch (error) { + console.log('Not an Adafruit member'); + } + + // Check if a contributor + if (label == '') { + try { + const collaboratorResponse = await github.rest.repos.checkCollaborator({ + owner: context.repo.owner, + repo: context.repo.repo, + username: username + }); + + if (collaboratorResponse.status === 204) { + console.log('Contributor'); + label = 'Prio Higher'; + } + } catch (error) { + console.log('Not a contributor'); + } + } + + if (label !== '') { + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issueOrPrNumber, + labels: [label] + }); + } diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index f984954d9..6b3151702 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Setup Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.x' @@ -25,7 +25,7 @@ jobs: ruby-version: '3.0' - name: Checkout TinyUSB - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Get Dependencies run: | @@ -38,6 +38,7 @@ jobs: - name: Build Fuzzer run: | + pip install click export CC=clang export CXX=clang++ fuzz_harness=$(ls -d test/fuzz/device/*/) diff --git a/.github/workflows/trigger.yml b/.github/workflows/trigger.yml index 33e3db859..cf40ac955 100644 --- a/.github/workflows/trigger.yml +++ b/.github/workflows/trigger.yml @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Push to tinyusb_src run: | diff --git a/.gitignore b/.gitignore index c665d6c73..56ae7600f 100644 --- a/.gitignore +++ b/.gitignore @@ -57,6 +57,7 @@ hw/mcu/st/cmsis_device_f4 hw/mcu/st/cmsis_device_f7 hw/mcu/st/cmsis_device_g0 hw/mcu/st/cmsis_device_g4 +hw/mcu/st/cmsis_device_h5 hw/mcu/st/cmsis_device_h7 hw/mcu/st/cmsis_device_l0 hw/mcu/st/cmsis_device_l1 @@ -72,6 +73,7 @@ hw/mcu/st/stm32f4xx_hal_driver hw/mcu/st/stm32f7xx_hal_driver hw/mcu/st/stm32g0xx_hal_driver hw/mcu/st/stm32g4xx_hal_driver +hw/mcu/st/stm32h5xx_hal_driver hw/mcu/st/stm32h7xx_hal_driver hw/mcu/st/stm32l0xx_hal_driver hw/mcu/st/stm32l1xx_hal_driver @@ -81,6 +83,7 @@ hw/mcu/st/stm32u5xx_hal_driver hw/mcu/st/stm32wbxx_hal_driver hw/mcu/ti hw/mcu/wch/ch32v307 +hw/mcu/wch/ch32f20x lib/CMSIS_5 lib/FreeRTOS-Kernel lib/lwip diff --git a/.idea/.gitignore b/.idea/.gitignore index 73f69e095..b0811f163 100644 --- a/.idea/.gitignore +++ b/.idea/.gitignore @@ -6,3 +6,5 @@ /dataSources.local.xml # Editor-based HTTP Client requests /httpRequests/ +# GitHub Copilot persisted chat sessions +/copilot/chatSessions diff --git a/.idea/cmake.xml b/.idea/cmake.xml index 76143ba10..bb13a0466 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -2,55 +2,134 @@ - + + + + + - - - - + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/kl25.xml b/.idea/runConfigurations/kl25.xml index a08c20d44..96c208dde 100644 --- a/.idea/runConfigurations/kl25.xml +++ b/.idea/runConfigurations/kl25.xml @@ -1,6 +1,6 @@ - - + + diff --git a/.idea/runConfigurations/lpc1857.xml b/.idea/runConfigurations/lpc1857.xml index 7525f51f7..a4764b9d6 100644 --- a/.idea/runConfigurations/lpc1857.xml +++ b/.idea/runConfigurations/lpc1857.xml @@ -1,6 +1,6 @@ - - + + diff --git a/.idea/runConfigurations/lpc4088.xml b/.idea/runConfigurations/lpc4088.xml index 7b32b2b85..9da975ef3 100644 --- a/.idea/runConfigurations/lpc4088.xml +++ b/.idea/runConfigurations/lpc4088.xml @@ -1,6 +1,6 @@ - - + + diff --git a/.idea/runConfigurations/lpc54628.xml b/.idea/runConfigurations/lpc54628.xml new file mode 100644 index 000000000..0c3877e94 --- /dev/null +++ b/.idea/runConfigurations/lpc54628.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/lpc55s69.xml b/.idea/runConfigurations/lpc55s69.xml new file mode 100644 index 000000000..2fa127d33 --- /dev/null +++ b/.idea/runConfigurations/lpc55s69.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/mcx947.xml b/.idea/runConfigurations/mcx947.xml index 77dec59f8..12180a996 100644 --- a/.idea/runConfigurations/mcx947.xml +++ b/.idea/runConfigurations/mcx947.xml @@ -1,6 +1,6 @@ - - + + diff --git a/.idea/runConfigurations/nrf52840.xml b/.idea/runConfigurations/nrf52840.xml index 084669c39..8e48a2b97 100644 --- a/.idea/runConfigurations/nrf52840.xml +++ b/.idea/runConfigurations/nrf52840.xml @@ -1,6 +1,6 @@ - - + + diff --git a/.idea/runConfigurations/nrf5340.xml b/.idea/runConfigurations/nrf5340.xml index 98fe39d80..646f2d38c 100644 --- a/.idea/runConfigurations/nrf5340.xml +++ b/.idea/runConfigurations/nrf5340.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/ra4m1.xml b/.idea/runConfigurations/ra4m1.xml index 561b509a2..72bc63d9b 100644 --- a/.idea/runConfigurations/ra4m1.xml +++ b/.idea/runConfigurations/ra4m1.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/ra6m1.xml b/.idea/runConfigurations/ra6m1.xml index 099510c60..ca8c7245a 100644 --- a/.idea/runConfigurations/ra6m1.xml +++ b/.idea/runConfigurations/ra6m1.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/ra6m5.xml b/.idea/runConfigurations/ra6m5.xml index 0cffac135..ecbdb21b7 100644 --- a/.idea/runConfigurations/ra6m5.xml +++ b/.idea/runConfigurations/ra6m5.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/rp2040.xml b/.idea/runConfigurations/rp2040.xml index 51ae689be..da5a8f1ee 100644 --- a/.idea/runConfigurations/rp2040.xml +++ b/.idea/runConfigurations/rp2040.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/rt1010.xml b/.idea/runConfigurations/rt1010.xml index 63df076b1..f415c0676 100644 --- a/.idea/runConfigurations/rt1010.xml +++ b/.idea/runConfigurations/rt1010.xml @@ -1,5 +1,5 @@ - + diff --git a/.idea/runConfigurations/rt1060.xml b/.idea/runConfigurations/rt1060.xml index 147f197a2..cc75aa62c 100644 --- a/.idea/runConfigurations/rt1060.xml +++ b/.idea/runConfigurations/rt1060.xml @@ -1,6 +1,6 @@ - - + + diff --git a/.idea/runConfigurations/samd21g18.xml b/.idea/runConfigurations/samd21g18.xml new file mode 100644 index 000000000..f8aa6009d --- /dev/null +++ b/.idea/runConfigurations/samd21g18.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/samd51j19.xml b/.idea/runConfigurations/samd51j19.xml new file mode 100644 index 000000000..694ea7dfd --- /dev/null +++ b/.idea/runConfigurations/samd51j19.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/stlink.xml b/.idea/runConfigurations/stlink.xml index 7e9166d90..628f7910d 100644 --- a/.idea/runConfigurations/stlink.xml +++ b/.idea/runConfigurations/stlink.xml @@ -1,6 +1,6 @@ - - + + diff --git a/.idea/runConfigurations/stm32g474.xml b/.idea/runConfigurations/stm32g474.xml index 2e4c4b82a..6d65e83c7 100644 --- a/.idea/runConfigurations/stm32g474.xml +++ b/.idea/runConfigurations/stm32g474.xml @@ -1,6 +1,6 @@ - - + + diff --git a/.idea/runConfigurations/stm32h743.xml b/.idea/runConfigurations/stm32h743.xml index f0ab6e9e7..aeaf9fb53 100644 --- a/.idea/runConfigurations/stm32h743.xml +++ b/.idea/runConfigurations/stm32h743.xml @@ -1,6 +1,6 @@ - - + + diff --git a/.idea/runConfigurations/uno_r4.xml b/.idea/runConfigurations/uno_r4.xml index e9e1ebb8d..98bf91812 100644 --- a/.idea/runConfigurations/uno_r4.xml +++ b/.idea/runConfigurations/uno_r4.xml @@ -1,6 +1,6 @@ - - + + diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4071ec326..bba217cc9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,9 @@ repos: exclude: | (?x)^( .idea/| - hw/bsp/mcx/sdk/ + hw/bsp/mcx/sdk/| + docs/contributing/code_of_conduct.rst| + docs/info/contributors.rst ) - id: forbid-submodules diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst index 50a33ae33..085f8082a 100644 --- a/CONTRIBUTORS.rst +++ b/CONTRIBUTORS.rst @@ -200,6 +200,8 @@ Notable contributors - Add new DCD port for Microchip SAMx7x - Add IAR compiler support - Improve UAC2, CDC, DFU class driver +- Improve stm32_fsdev, chipidea_ci_hs, lpc_ip3511 DCD +- Host IAR Build CI & hardware in the loop (HITL) test `Full contributors list `__ diff --git a/README.rst b/README.rst index 78e8d87b0..8c3145d33 100644 --- a/README.rst +++ b/README.rst @@ -1,14 +1,24 @@ +|Build Status| |Documentation Status| |Fuzzing Status| |License| + +Sponsors +======== + +TinyUSB is funded by: Adafruit. Purchasing products from them helps to support this project. + +.. figure:: docs/assets/adafruit_logo.svg + :alt: Adafruit Logo + :target: https://www.adafruit.com + +TinyUSB Project +=============== + .. figure:: docs/assets/logo.svg :alt: TinyUSB -|Build Status| |Documentation Status| |Fuzzing Status| |License| - TinyUSB is an open-source cross-platform USB Host/Device stack for embedded system, designed to be memory-safe with no dynamic allocation and thread-safe with all interrupt events are deferred then handled in -the non-ISR task function. - -Please take a look at the online `documentation `__. +the non-ISR task function. Check out the online `documentation `__ for more details. .. figure:: docs/assets/stack.svg :width: 500px @@ -16,51 +26,30 @@ Please take a look at the online `documentation `__. :: - . - ├── docs # Documentation - ├── examples # Sample with Makefile build support - ├── hw - │ ├── bsp # Supported boards source files - │ └── mcu # Low level mcu core & peripheral drivers - ├── lib # Sources from 3rd party such as freeRTOS, fatfs ... - ├── src # All sources files for TinyUSB stack itself. - ├── test # Unit tests for the stack - └── tools # Files used internally + . + ├── docs # Documentation + ├── examples # Examples with make and cmake build system + ├── hw + │ ├── bsp # Supported boards source files + │ └── mcu # Low level mcu core & peripheral drivers + ├── lib # Sources from 3rd party such as freeRTOS, fatfs ... + ├── src # All sources files for TinyUSB stack itself. + ├── test # Tests: unit test, fuzzing, hardware test + └── tools # Files used internally -Supported MCUs -============== -The stack supports the following MCUs: +Getting started +=============== -- **Allwinner:** F1C100s/F1C200s -- **Broadcom:** BCM2837, BCM2711 -- **Dialog:** DA1469x -- **Espressif:** ESP32-S2, ESP32-S3 -- **GigaDevice:** GD32VF103 -- **Infineon:** XMC4500 -- **MicroChip:** SAMD11, SAMD21, SAMD51, SAME5x, SAMG55, SAML21, SAML22, SAME7x -- **NordicSemi:** nRF52833, nRF52840, nRF5340 -- **Nuvoton:** NUC120, NUC121/NUC125, NUC126, NUC505 -- **NXP:** +See the `online documentation `_ for information about using TinyUSB and how it is implemented. - - iMX RT Series: RT10xx, RT11xx - - Kinetis: KL25, K32L2 - - LPC Series: 11u, 13, 15, 17, 18, 40, 43, 51u, 54, 55 +We use `GitHub Discussions `_ as our forum. It is a great place to ask questions and advice from the community or to discuss your TinyUSB-based projects. -- **Raspberry Pi:** RP2040 -- **Renesas:** +For bugs and feature requests, please `raise an issue `_ and follow the templates there. - - RX Series: 63N, 65N, 72N - - RA Series: RA4M1, RA4M3 +Check out `Getting Started`_ guide for adding TinyUSB to your project or building the examples. If you are new to TinyUSB, we recommend starting with the `cdc_msc` example. -- **Silabs:** EFM32GG -- **Sony:** CXD56 -- **ST:** STM32 series: F0, F1, F2, F3, F4, F7, H7, G0, G4, L0, L1, L4, L4+, WB -- **TI:** MSP430, MSP432E4, TM4C123 -- **ValentyUSB:** eptri -- **WCH:** CH32V307 - -Here is the list of `Supported Devices`_ that can be used with provided examples. +See `Porting`_ guide for adding support for new MCUs and boards. Device Stack ============ @@ -87,8 +76,12 @@ Host Stack - Human Interface Device (HID): Keyboard, Mouse, Generic - Mass Storage Class (MSC) +- Communication Device Class: CDC-ACM +- Vendor serial over USB: FTDI, CP210x - Hub with multiple-level support +Similar to the Device Stack, if you have a special requirement, `usbh_app_driver_get_cb()` can be used to write your own class driver without modifying the stack. + TypeC PD Stack ============== @@ -106,6 +99,76 @@ TinyUSB is completely thread-safe by pushing all Interrupt Service Request (ISR) - `RT-Thread `_: `repo `_ - **Mynewt** Due to the newt package build system, Mynewt examples are better to be on its `own repo `_ +Supported CPUs +============== + +Following CPUs are supported, check out `Supported Devices`_ for comprehensive list of driver, features for each CPU. + ++--------------+------------------------------------------------------------+ +| Manufacturer | Family | ++==============+============================================================+ +| Allwinner | F1C100s/F1C200s | ++--------------+------------------------------------------------------------+ +| Analog | MAX3421E (usb host shield) | ++--------------+------------------------------------------------------------+ +| Brigetek | FT90x | ++--------------+------------------------------------------------------------+ +| Broadcom | BCM2711, BCM2837 | ++--------------+------------------------------------------------------------+ +| Dialog | DA1469x | ++--------------+------------------------------------------------------------+ +| Espressif | ESP32 S2, S3 | ++--------------+------------------------------------------------------------+ +| GigaDevice | GD32VF103 | ++--------------+------------------------------------------------------------+ +| Infineon | XMC4500 | ++--------------+-----+------------------------------------------------------+ +| MicroChip | SAM | D11, D21, D51, E5x, G55, L2x, E7x, S7x, V7x | +| +-----+------------------------------------------------------+ +| | PIC | 24, 32mm, 32mk, 32mx, 32mz, dsPIC33 | ++--------------+-----+------------------------------------------------------+ +| Mind Montion | mm32 | ++--------------+------------------------------------------------------------+ +| NordicSemi | nRF52833, nRF52840, nRF5340 | ++--------------+------------------------------------------------------------+ +| Nuvoton | NUC 120, 121, 125, 126, 505 | ++--------------+---------+--------------------------------------------------+ +| NXP | iMXRT | RT10xx, RT11xx | +| +---------+--------------------------------------------------+ +| | Kinetis | KL, K32L2 | +| +---------+--------------------------------------------------+ +| | LPC | 11u, 13, 15, 17, 18, 40, 43, 51u, 54, 55 | +| +---------+--------------------------------------------------+ +| | MCX | A15, N9 | ++--------------+---------+--------------------------------------------------+ +| Raspberry Pi | RP2040 | ++--------------+-----+------------------------------------------------------+ +| Renesas | RX | 63N, 65N, 72N | ++--------------+-----+------------------------------------------------------+ +| | RA | 4M1, 4M3, 6M1, 6M5 | ++--------------+-----+------------------------------------------------------+ +| Silabs | EFM32GG12 | ++--------------+------------------------------------------------------------+ +| Sony | CXD56 | ++--------------+------------------------------------------------------------+ +| ST STM32 | F0, F1, F2, F3, F4, F7, H7, G0, G4, L0, L1, L4, L4+ U5, WB | ++--------------+------------------------------------------------------------+ +| TI | MSP430, MSP432E4, TM4C123 | ++--------------+------------------------------------------------------------+ +| ValentyUSB | eptri | ++--------------+------------------------------------------------------------+ +| WCH | CH32F20x, CH32V307, | ++--------------+------------------------------------------------------------+ + +License +======= + +All TinyUSB sources in the ``src`` folder are licensed under MIT +license, the `Full license is here `__. However, each file can be +individually licensed especially those in ``lib`` and ``hw/mcu`` folder. +Please make sure you understand all the license term for files you use +in your project. + Docs ==== @@ -128,16 +191,6 @@ Docs - `Structure`_ - `Porting`_ -License -======= - -All TinyUSB sources in the ``src`` folder are licensed under MIT -license, the `Full license is here `__. However, each file can be -individually licensed especially those in ``lib`` and ``hw/mcu`` folder. -Please make sure you understand all the license term for files you use -in your project. - - .. |Build Status| image:: https://github.com/hathach/tinyusb/actions/workflows/cmake_arm.yml/badge.svg :target: https://github.com/hathach/tinyusb/actions .. |Documentation Status| image:: https://readthedocs.org/projects/tinyusb/badge/?version=latest diff --git a/SConscript b/SConscript new file mode 100644 index 000000000..b5043f437 --- /dev/null +++ b/SConscript @@ -0,0 +1,11 @@ +# RT-Thread building script for bridge + +import os +from building import * + +objs = [] +cwd = GetCurrentDir() + +objs = objs + SConscript(cwd + '/lib/rt-thread/SConscript') + +Return('objs') diff --git a/docs/assets/adafruit_logo.svg b/docs/assets/adafruit_logo.svg new file mode 100644 index 000000000..cafd5a10e --- /dev/null +++ b/docs/assets/adafruit_logo.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + diff --git a/docs/contributing/code_of_conduct.rst b/docs/contributing/code_of_conduct.rst index 82627099f..b52bf14c5 120000 --- a/docs/contributing/code_of_conduct.rst +++ b/docs/contributing/code_of_conduct.rst @@ -1 +1 @@ -../../CODE_OF_CONDUCT.rst +../../CODE_OF_CONDUCT.rst \ No newline at end of file diff --git a/docs/info/changelog.rst b/docs/info/changelog.rst index c6c02d181..b359ebb44 100644 --- a/docs/info/changelog.rst +++ b/docs/info/changelog.rst @@ -2,6 +2,148 @@ Changelog ********* +0.16.0 +====== + +- New controller driver: MAX3421e (usb host shield), rusb2 (Renesas USB2.0), ChipIdea fullspeed +- New MCUs: MCXn9, nRF5340, STM32: G0, G4, L5, U575, U5A5, RA6m5, CH32F20x +- Add initial TypeC PowerDelivery support with STM32G4 +- Remove submodules and use python script to manage repo dependencies #1947 +- Add CMake support for most families and boards, move build file from tools/ to examples/build_system +- Add ETM trace support with JTrace for nrf52840, nrf5340, mcb1857, stm32h743eval, ra6m5 +- [osal] Make it possible to override the osal_task_delay() in osal_none +- Add CDC+UAC2 composite device example +- Enhance Hardware-in-the-loop (HIL) testing with more boards: rp2040, stm32l412nucleo, stm32f746disco, lpcxpresso43s67 + +Controller Driver (DCD & HCD) +----------------------------- + +- Add new ISO endpoint API: dcd_edpt_iso_alloc() and dcd_edpt_iso_activate() +- Remove legacy driver st/synopsys + +- EHCI + + - [iMXRT] Add dache clean/invalidate when memory is in cacheable memory + - Fix portsc write issue which cause problem with enumeration + - Fix an issue when doing port reset write to portsc + - Fix port change detect is not recognized when power on with attached device + - Fix xfer failed with disconnected device as stalled + - Fix error on EHCI causes xfer error in non-queued qhd which cause memory fault + - Un-roll recursive hub removal with usbh queue + - Fix issue when removing queue head + - Implement hcd_edpt_abort_xfer() + - use standard USB complete interrupt instead of custom chipidea async/period interrupt to be more compatible with other ehci implementation + - refactor usb complete & error isr processing, merge, update. Fix EHCI QHD reuses QTD on wrong endpoint + - Improve bus reset, fix send_setup() not carried out if halted previously + - Fix clear qhd halted bit if not caused by STALL protocol to allow for next transfer + +- ChipIdea Highspeed + + - Fix control transfer issue when previous status and new setup complete in the same isr frame + - [imxrt] Add dcache support for cache region + +- ChipIdea Fullspeed + + - Generalize ChipIdea Fullspeed driver for mcxn9 (port 0), kinetis + +- nrf + + - Fix DMA race condition with ISO OUT transfer #1946 + - Add support for nRF5340 with pca10095 board + +- Renesas rusb2 + + - Generalize rusb2 driver for ra, rx mcus + - rework both dcd and hcd for better multiple ports support + - Add support for board with HS USB port: ra6m5 port1 + +- rp2040 + + - [dcd] Make writes to SIE_CTRL aware of concurrent access + - [hcd] add hcd_frame_number(), hcd_edpt_abort_xfer() for pio-usb host + +- stm32 fsdev: + + - Add STM32L5 support + - Implement dcd_edpt_iso_alloc() and dcd_edpt_iso_activate() + +- OHCI + + - Allows configurable root hub ports, handles SMM mode (Ref OHCI spec 5.1.1.3.3) and Bios mode (Ref OHCI spec 5.1.1.3.4) + - Fix FrameIntervalToggle must be toggled after we write the FrameInterval (Ref OHCI Spec 7.3.1) + - Wait PowerOnToPowerGoodTime after we enable power of the RH ports (Ref OHCI Spec 7.4.1) + - Generate port interrupts for devices already connected during init. + - Fix issue when removing queue head + - Disable MIE during IRQ processing and clear HccaDoneHead on completion as per OCHI Spec Page 80 + +Device Stack +------------ + +- Add optional hooks tud_event_hook_cb() +- Audio (UAC2) + + - Fix feedback EP buffer alignment. + - Fix encoding, update example + - Improve IN transfer + +- Bluetooth + + - Add historical EP compatibility for Bluetooth HCI + +- CDC + + - Fix line_coding alignment + - Fix typo in cdc line coding enum + +- MIDI + + - Fix stream_write() always writes system messages to cable 0 + - Fix incorrect NOTE_ON, NOTE_OFF definitions + +- USBTMC: Fix tmc488 bit order + +- Vendor: fix read()/write() race condition + +- Video (UVC) + + - Add the capability for video class to handle a bulk endpoint in the streaming interface. + +Host Stack +---------- + +- USBH + + - Add new APIs: tuh_interface_set(), tuh_task_event_ready(), tuh_edpt_abort_xfer(), tuh_rhport_reset_bus(), tuh_rhport_is_active() + - Fix issue when device generate multiple attach/detach/attach when plugging in + - Prefer application callback over built-in driver on transfer complete event + - Correct hcd_edpt_clear_stall() API signature + - Separate bus reset delay and contact debouncing delay in enumeration + - Support usbh_app_driver_get_cb() for application drivers + - Fix usbh enumeration removal race condition + - Add optional hooks tuh_event_hook_cb() + +- CDC + + - Breaking: change tuh_cdc_itf_get_info() to use tuh_itf_info_t instead of tuh_cdc_info_t + - Fix cdc host enumeration issue when device does not support line request + - Add support for vendor usb2uart serial: ftdi, cp210x, ch9102f + - Improve sync control API e.g tuh_cdc_set_control_line_state(), tuh_cdc_set_line_coding() + +- HID + + - Add new APIs tuh_hid_send_report(), tuh_hid_itf_get_info(), tuh_hid_receive_ready(), tuh_hid_send_ready(), tuh_hid_set_default_protocol() + - Change meaning of CFG_TUH_HID to total number of HID interfaces supported. Previously CFG_TUH_HID is max number of interfaces per device which is rather limited and consume more resources than needed. + +- HUB + + - Fix handling of empty "status change" interrupt + - Fix issue with hub status_change is not aligned + +- MSC + + - Fix bug in tuh_msc_ready() + - Fix host msc get maxlun not using aligned section memory + 0.15.0 ====== diff --git a/docs/info/contributors.rst b/docs/info/contributors.rst index 02608919f..b3748ccb5 120000 --- a/docs/info/contributors.rst +++ b/docs/info/contributors.rst @@ -1 +1 @@ -../../CONTRIBUTORS.rst +../../CONTRIBUTORS.rst \ No newline at end of file diff --git a/docs/reference/dependencies.rst b/docs/reference/dependencies.rst index 130527e2c..6ba6692e9 100644 --- a/docs/reference/dependencies.rst +++ b/docs/reference/dependencies.rst @@ -4,61 +4,61 @@ Dependencies MCU low-level peripheral driver and external libraries for building TinyUSB examples -======================================== ============================================================== ======================================== -Path Project Commit -======================================== ============================================================== ======================================== -hw/mcu/allwinner https://github.com/hathach/allwinner_driver.git 8e5e89e8e132c0fd90e72d5422e5d3d68232b756 -hw/mcu/bridgetek/ft9xx/ft90x-sdk https://github.com/BRTSG-FOSS/ft90x-sdk.git 91060164afe239fcb394122e8bf9eb24d3194eb1 -hw/mcu/broadcom https://github.com/adafruit/broadcom-peripherals.git 08370086080759ed54ac1136d62d2ad24c6fa267 -hw/mcu/gd/nuclei-sdk https://github.com/Nuclei-Software/nuclei-sdk.git 7eb7bfa9ea4fbeacfafe1d5f77d5a0e6ed3922e7 -hw/mcu/infineon/mtb-xmclib-cat3 https://github.com/Infineon/mtb-xmclib-cat3.git daf5500d03cba23e68c2f241c30af79cd9d63880 -hw/mcu/microchip https://github.com/hathach/microchip_driver.git 9e8b37e307d8404033bb881623a113931e1edf27 -hw/mcu/mindmotion/mm32sdk https://github.com/hathach/mm32sdk.git 0b79559eb411149d36e073c1635c620e576308d4 -hw/mcu/nordic/nrfx https://github.com/NordicSemiconductor/nrfx.git 281cc2e178fd9a470d844b3afdea9eb322a0b0e8 -hw/mcu/nuvoton https://github.com/majbthrd/nuc_driver.git 2204191ec76283371419fbcec207da02e1bc22fa -hw/mcu/nxp/lpcopen https://github.com/hathach/nxp_lpcopen.git 43c45c85405a5dd114fff0ea95cca62837740c13 -hw/mcu/nxp/mcux-sdk https://github.com/NXPmicro/mcux-sdk.git ae2ab01d9d70ad00cd0e935c2552bd5f0e5c0294 -hw/mcu/nxp/nxp_sdk https://github.com/hathach/nxp_sdk.git 845c8fc49b6fb660f06a5c45225494eacb06f00c -hw/mcu/raspberry_pi/Pico-PIO-USB https://github.com/sekigon-gonnoc/Pico-PIO-USB.git c3715ce94b6f6391856de56081d4d9b3e98fa93d -hw/mcu/renesas/fsp https://github.com/renesas/fsp.git 8dc14709f2a6518b43f71efad70d900b7718d9f1 -hw/mcu/renesas/rx https://github.com/kkitayam/rx_device.git 706b4e0cf485605c32351e2f90f5698267996023 -hw/mcu/silabs/cmsis-dfp-efm32gg12b https://github.com/cmsis-packs/cmsis-dfp-efm32gg12b.git f1c31b7887669cb230b3ea63f9b56769078960bc -hw/mcu/sony/cxd56/spresense-exported-sdk https://github.com/sonydevworld/spresense-exported-sdk.git 2ec2a1538362696118dc3fdf56f33dacaf8f4067 -hw/mcu/st/cmsis_device_f0 https://github.com/STMicroelectronics/cmsis_device_f0.git 2fc25ee22264bc27034358be0bd400b893ef837e -hw/mcu/st/cmsis_device_f1 https://github.com/STMicroelectronics/cmsis_device_f1.git 6601104a6397299b7304fd5bcd9a491f56cb23a6 -hw/mcu/st/cmsis_device_f2 https://github.com/STMicroelectronics/cmsis_device_f2.git 182fcb3681ce116816feb41b7764f1b019ce796f -hw/mcu/st/cmsis_device_f3 https://github.com/STMicroelectronics/cmsis_device_f3.git 5e4ee5ed7a7b6c85176bb70a9fd3c72d6eb99f1b -hw/mcu/st/cmsis_device_f4 https://github.com/STMicroelectronics/cmsis_device_f4.git 2615e866fa48fe1ff1af9e31c348813f2b19e7ec -hw/mcu/st/cmsis_device_f7 https://github.com/STMicroelectronics/cmsis_device_f7.git fc676ef1ad177eb874eaa06444d3d75395fc51f4 -hw/mcu/st/cmsis_device_g0 https://github.com/STMicroelectronics/cmsis_device_g0.git 08258b28ee95f50cb9624d152a1cbf084be1f9a5 -hw/mcu/st/cmsis_device_g4 https://github.com/STMicroelectronics/cmsis_device_g4.git ce822adb1dc552b3aedd13621edbc7fdae124878 -hw/mcu/st/cmsis_device_h7 https://github.com/STMicroelectronics/cmsis_device_h7.git 60dc2c913203dc8629dc233d4384dcc41c91e77f -hw/mcu/st/cmsis_device_l0 https://github.com/STMicroelectronics/cmsis_device_l0.git 06748ca1f93827befdb8b794402320d94d02004f -hw/mcu/st/cmsis_device_l1 https://github.com/STMicroelectronics/cmsis_device_l1.git 7f16ec0a1c4c063f84160b4cc6bf88ad554a823e -hw/mcu/st/cmsis_device_l4 https://github.com/STMicroelectronics/cmsis_device_l4.git 6ca7312fa6a5a460b5a5a63d66da527fdd8359a6 -hw/mcu/st/cmsis_device_l5 https://github.com/STMicroelectronics/cmsis_device_l5.git d922865fc0326a102c26211c44b8e42f52c1e53d -hw/mcu/st/cmsis_device_u5 https://github.com/STMicroelectronics/cmsis_device_u5.git bc00f3c9d8a4e25220f84c26d414902cc6bdf566 -hw/mcu/st/cmsis_device_wb https://github.com/STMicroelectronics/cmsis_device_wb.git 9c5d1920dd9fabbe2548e10561d63db829bb744f -hw/mcu/st/stm32f0xx_hal_driver https://github.com/STMicroelectronics/stm32f0xx_hal_driver.git 0e95cd88657030f640a11e690a8a5186c7712ea5 -hw/mcu/st/stm32f1xx_hal_driver https://github.com/STMicroelectronics/stm32f1xx_hal_driver.git 1dd9d3662fb7eb2a7f7d3bc0a4c1dc7537915a29 -hw/mcu/st/stm32f2xx_hal_driver https://github.com/STMicroelectronics/stm32f2xx_hal_driver.git c75ace9b908a9aca631193ebf2466963b8ea33d0 -hw/mcu/st/stm32f3xx_hal_driver https://github.com/STMicroelectronics/stm32f3xx_hal_driver.git 1761b6207318ede021706e75aae78f452d72b6fa -hw/mcu/st/stm32f4xx_hal_driver https://github.com/STMicroelectronics/stm32f4xx_hal_driver.git 04e99fbdabd00ab8f370f377c66b0a4570365b58 -hw/mcu/st/stm32f7xx_hal_driver https://github.com/STMicroelectronics/stm32f7xx_hal_driver.git f7ffdf6bf72110e58b42c632b0a051df5997e4ee -hw/mcu/st/stm32g0xx_hal_driver https://github.com/STMicroelectronics/stm32g0xx_hal_driver.git 5b53e6cee664a82b16c86491aa0060e2110c00cb -hw/mcu/st/stm32g4xx_hal_driver https://github.com/STMicroelectronics/stm32g4xx_hal_driver.git 8b4518417706d42eef5c14e56a650005abf478a8 -hw/mcu/st/stm32h7xx_hal_driver https://github.com/STMicroelectronics/stm32h7xx_hal_driver.git d8461b980b59b1625207d8c4f2ce0a9c2a7a3b04 -hw/mcu/st/stm32l0xx_hal_driver https://github.com/STMicroelectronics/stm32l0xx_hal_driver.git fbdacaf6f8c82a4e1eb9bd74ba650b491e97e17b -hw/mcu/st/stm32l1xx_hal_driver https://github.com/STMicroelectronics/stm32l1xx_hal_driver.git 44efc446fa69ed8344e7fd966e68ed11043b35d9 -hw/mcu/st/stm32l4xx_hal_driver https://github.com/STMicroelectronics/stm32l4xx_hal_driver.git aee3d5bf283ae5df87532b781bdd01b7caf256fc -hw/mcu/st/stm32l5xx_hal_driver https://github.com/STMicroelectronics/stm32l5xx_hal_driver.git 675c32a75df37f39d50d61f51cb0dcf53f07e1cb -hw/mcu/st/stm32u5xx_hal_driver https://github.com/STMicroelectronics/stm32u5xx_hal_driver.git 2e1d4cdb386e33391cb261dfff4fefa92e4aa35a -hw/mcu/st/stm32wbxx_hal_driver https://github.com/STMicroelectronics/stm32wbxx_hal_driver.git 2c5f06638be516c1b772f768456ba637f077bac8 -hw/mcu/ti https://github.com/hathach/ti_driver.git 143ed6cc20a7615d042b03b21e070197d473e6e5 -hw/mcu/wch/ch32v307 https://github.com/openwch/ch32v307.git 17761f5cf9dbbf2dcf665b7c04934188add20082 -lib/CMSIS_5 https://github.com/ARM-software/CMSIS_5.git 20285262657d1b482d132d20d755c8c330d55c1f -lib/FreeRTOS-Kernel https://github.com/FreeRTOS/FreeRTOS-Kernel.git def7d2df2b0506d3d249334974f51e427c17a41c -lib/lwip https://github.com/lwip-tcpip/lwip.git 159e31b689577dbf69cf0683bbaffbd71fa5ee10 -lib/sct_neopixel https://github.com/gsteiert/sct_neopixel.git e73e04ca63495672d955f9268e003cffe168fcd8 -tools/uf2 https://github.com/microsoft/uf2.git 19615407727073e36d81bf239c52108ba92e7660 -======================================== ============================================================== ======================================== +======================================== ============================================================== ======================================== ======================================================================================================================================================================================================= +Local Path Repo Commit Required by +======================================== ============================================================== ======================================== ======================================================================================================================================================================================================= +hw/mcu/allwinner https://github.com/hathach/allwinner_driver.git 8e5e89e8e132c0fd90e72d5422e5d3d68232b756 fc100s +hw/mcu/bridgetek/ft9xx/ft90x-sdk https://github.com/BRTSG-FOSS/ft90x-sdk.git 91060164afe239fcb394122e8bf9eb24d3194eb1 brtmm90x +hw/mcu/broadcom https://github.com/adafruit/broadcom-peripherals.git 08370086080759ed54ac1136d62d2ad24c6fa267 broadcom_32bit broadcom_64bit +hw/mcu/gd/nuclei-sdk https://github.com/Nuclei-Software/nuclei-sdk.git 7eb7bfa9ea4fbeacfafe1d5f77d5a0e6ed3922e7 gd32vf103 +hw/mcu/infineon/mtb-xmclib-cat3 https://github.com/Infineon/mtb-xmclib-cat3.git daf5500d03cba23e68c2f241c30af79cd9d63880 xmc4000 +hw/mcu/microchip https://github.com/hathach/microchip_driver.git 9e8b37e307d8404033bb881623a113931e1edf27 sam3x samd11 samd21 samd51 same5x same7x saml2x samg +hw/mcu/mindmotion/mm32sdk https://github.com/hathach/mm32sdk.git 0b79559eb411149d36e073c1635c620e576308d4 mm32 +hw/mcu/nordic/nrfx https://github.com/NordicSemiconductor/nrfx.git 2527e3c8449cfd38aee41598e8af8492f410ed15 nrf +hw/mcu/nuvoton https://github.com/majbthrd/nuc_driver.git 2204191ec76283371419fbcec207da02e1bc22fa nuc +hw/mcu/nxp/lpcopen https://github.com/hathach/nxp_lpcopen.git 84e0bd3e43910aaf71eefd62075cf57495418312 lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 +hw/mcu/nxp/mcux-sdk https://github.com/hathach/mcux-sdk.git 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 d00a10a8c425d0d40f81b87169102944b01f3bb3 rp2040 +hw/mcu/renesas/fsp https://github.com/renesas/fsp.git d52e5a6a59b7c638da860c2bb309b6e78e752ff8 ra +hw/mcu/renesas/rx https://github.com/kkitayam/rx_device.git 706b4e0cf485605c32351e2f90f5698267996023 rx +hw/mcu/silabs/cmsis-dfp-efm32gg12b https://github.com/cmsis-packs/cmsis-dfp-efm32gg12b.git f1c31b7887669cb230b3ea63f9b56769078960bc efm32 +hw/mcu/sony/cxd56/spresense-exported-sdk https://github.com/sonydevworld/spresense-exported-sdk.git 2ec2a1538362696118dc3fdf56f33dacaf8f4067 spresense +hw/mcu/st/cmsis_device_f0 https://github.com/STMicroelectronics/cmsis_device_f0.git 2fc25ee22264bc27034358be0bd400b893ef837e stm32f0 +hw/mcu/st/cmsis_device_f1 https://github.com/STMicroelectronics/cmsis_device_f1.git 6601104a6397299b7304fd5bcd9a491f56cb23a6 stm32f1 +hw/mcu/st/cmsis_device_f2 https://github.com/STMicroelectronics/cmsis_device_f2.git 182fcb3681ce116816feb41b7764f1b019ce796f stm32f2 +hw/mcu/st/cmsis_device_f3 https://github.com/STMicroelectronics/cmsis_device_f3.git 5e4ee5ed7a7b6c85176bb70a9fd3c72d6eb99f1b stm32f3 +hw/mcu/st/cmsis_device_f4 https://github.com/STMicroelectronics/cmsis_device_f4.git 2615e866fa48fe1ff1af9e31c348813f2b19e7ec stm32f4 +hw/mcu/st/cmsis_device_f7 https://github.com/STMicroelectronics/cmsis_device_f7.git fc676ef1ad177eb874eaa06444d3d75395fc51f4 stm32f7 +hw/mcu/st/cmsis_device_g0 https://github.com/STMicroelectronics/cmsis_device_g0.git 3a23e1224417f3f2d00300ecd620495e363f2094 stm32g0 +hw/mcu/st/cmsis_device_g4 https://github.com/STMicroelectronics/cmsis_device_g4.git ce822adb1dc552b3aedd13621edbc7fdae124878 stm32g4 +hw/mcu/st/cmsis_device_h7 https://github.com/STMicroelectronics/cmsis_device_h7.git 60dc2c913203dc8629dc233d4384dcc41c91e77f stm32h7 +hw/mcu/st/cmsis_device_l0 https://github.com/STMicroelectronics/cmsis_device_l0.git 06748ca1f93827befdb8b794402320d94d02004f stm32l0 +hw/mcu/st/cmsis_device_l1 https://github.com/STMicroelectronics/cmsis_device_l1.git 7f16ec0a1c4c063f84160b4cc6bf88ad554a823e stm32l1 +hw/mcu/st/cmsis_device_l4 https://github.com/STMicroelectronics/cmsis_device_l4.git 6ca7312fa6a5a460b5a5a63d66da527fdd8359a6 stm32l4 +hw/mcu/st/cmsis_device_l5 https://github.com/STMicroelectronics/cmsis_device_l5.git d922865fc0326a102c26211c44b8e42f52c1e53d stm32l5 +hw/mcu/st/cmsis_device_u5 https://github.com/STMicroelectronics/cmsis_device_u5.git 06d7edade7167b0eafdd550bf77cfc4fa98eae2e stm32u5 +hw/mcu/st/cmsis_device_wb https://github.com/STMicroelectronics/cmsis_device_wb.git 9c5d1920dd9fabbe2548e10561d63db829bb744f stm32wb +hw/mcu/st/stm32f0xx_hal_driver https://github.com/STMicroelectronics/stm32f0xx_hal_driver.git 0e95cd88657030f640a11e690a8a5186c7712ea5 stm32f0 +hw/mcu/st/stm32f1xx_hal_driver https://github.com/STMicroelectronics/stm32f1xx_hal_driver.git 1dd9d3662fb7eb2a7f7d3bc0a4c1dc7537915a29 stm32f1 +hw/mcu/st/stm32f2xx_hal_driver https://github.com/STMicroelectronics/stm32f2xx_hal_driver.git c75ace9b908a9aca631193ebf2466963b8ea33d0 stm32f2 +hw/mcu/st/stm32f3xx_hal_driver https://github.com/STMicroelectronics/stm32f3xx_hal_driver.git 1761b6207318ede021706e75aae78f452d72b6fa stm32f3 +hw/mcu/st/stm32f4xx_hal_driver https://github.com/STMicroelectronics/stm32f4xx_hal_driver.git 04e99fbdabd00ab8f370f377c66b0a4570365b58 stm32f4 +hw/mcu/st/stm32f7xx_hal_driver https://github.com/STMicroelectronics/stm32f7xx_hal_driver.git f7ffdf6bf72110e58b42c632b0a051df5997e4ee stm32f7 +hw/mcu/st/stm32g0xx_hal_driver https://github.com/STMicroelectronics/stm32g0xx_hal_driver.git e911b12c7f67084d7f6b76157a4c0d4e2ec3779c stm32g0 +hw/mcu/st/stm32g4xx_hal_driver https://github.com/STMicroelectronics/stm32g4xx_hal_driver.git 8b4518417706d42eef5c14e56a650005abf478a8 stm32g4 +hw/mcu/st/stm32h7xx_hal_driver https://github.com/STMicroelectronics/stm32h7xx_hal_driver.git d8461b980b59b1625207d8c4f2ce0a9c2a7a3b04 stm32h7 +hw/mcu/st/stm32l0xx_hal_driver https://github.com/STMicroelectronics/stm32l0xx_hal_driver.git fbdacaf6f8c82a4e1eb9bd74ba650b491e97e17b stm32l0 +hw/mcu/st/stm32l1xx_hal_driver https://github.com/STMicroelectronics/stm32l1xx_hal_driver.git 44efc446fa69ed8344e7fd966e68ed11043b35d9 stm32l1 +hw/mcu/st/stm32l4xx_hal_driver https://github.com/STMicroelectronics/stm32l4xx_hal_driver.git aee3d5bf283ae5df87532b781bdd01b7caf256fc stm32l4 +hw/mcu/st/stm32l5xx_hal_driver https://github.com/STMicroelectronics/stm32l5xx_hal_driver.git 675c32a75df37f39d50d61f51cb0dcf53f07e1cb stm32l5 +hw/mcu/st/stm32u5xx_hal_driver https://github.com/STMicroelectronics/stm32u5xx_hal_driver.git 4d93097a67928e9377e655ddd14622adc31b9770 stm32u5 +hw/mcu/st/stm32wbxx_hal_driver https://github.com/STMicroelectronics/stm32wbxx_hal_driver.git 2c5f06638be516c1b772f768456ba637f077bac8 stm32wb +hw/mcu/ti https://github.com/hathach/ti_driver.git 143ed6cc20a7615d042b03b21e070197d473e6e5 msp430 msp432e4 tm4c123 +hw/mcu/wch/ch32f20x https://github.com/openwch/ch32f20x.git 77c4095087e5ed2c548ec9058e655d0b8757663b ch32f20x +hw/mcu/wch/ch32v307 https://github.com/openwch/ch32v307.git 17761f5cf9dbbf2dcf665b7c04934188add20082 ch32v307 +lib/CMSIS_5 https://github.com/ARM-software/CMSIS_5.git 20285262657d1b482d132d20d755c8c330d55c1f imxrt kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx mm32 msp432e4 nrf ra saml2xstm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h7 stm32l0 stm32l1 stm32l4 stm32l5 stm32u5 stm32wb +lib/FreeRTOS-Kernel https://github.com/FreeRTOS/FreeRTOS-Kernel.git 4ff01a7a4a51f53b44496aefee1e3c0071b7b173 all +lib/lwip https://github.com/lwip-tcpip/lwip.git 159e31b689577dbf69cf0683bbaffbd71fa5ee10 all +lib/sct_neopixel https://github.com/gsteiert/sct_neopixel.git e73e04ca63495672d955f9268e003cffe168fcd8 lpc55 +tools/uf2 https://github.com/microsoft/uf2.git 19615407727073e36d81bf239c52108ba92e7660 all +======================================== ============================================================== ======================================== ======================================================================================================================================================================================================= diff --git a/docs/reference/getting_started.rst b/docs/reference/getting_started.rst index 1f41cb888..3db3fa206 100644 --- a/docs/reference/getting_started.rst +++ b/docs/reference/getting_started.rst @@ -5,8 +5,7 @@ Getting Started Add TinyUSB to your project --------------------------- -It is relatively simple to incorporate tinyusb to your (existing) project - +It is relatively simple to incorporate tinyusb to your project * Copy or ``git submodule`` this repo into your project in a subfolder. Let's say it is *your_project/tinyusb* * Add all the .c in the ``tinyusb/src`` folder to your project @@ -46,6 +45,26 @@ For your convenience, TinyUSB contains a handful of examples for both host and d Some ports will also require a port-specific SDK (e.g. RP2040) or binary (e.g. Sony Spresense) to build examples. They are out of scope for tinyusb, you should download/install it first according to its manufacturer guide. +Dependencies +^^^^^^^^^^^^ + +The hardware code is located in ``hw/bsp`` folder, and is organized by family/boards. e.g raspberry_pi_pico is located in ``hw/bsp/rp2040/boards/raspberry_pi_pico`` where FAMILY=rp2040 and BOARD=raspberry_pi_pico. Before building, we firstly need to download dependencies such as: MCU low-level peripheral driver and external libraries e.g FreeRTOS (required by some examples). We can do that by either ways: + +1. Run ``tools/get_deps.py {FAMILY}`` script to download all dependencies for a family as follow. Note: For TinyUSB developer to download all dependencies, use FAMILY=all. + +.. code-block:: + + $ python tools/get_deps.py rp2040 + +2. Or run the ``get-deps`` target in one of the example folder as follow. + +.. code-block:: + + $ cd examples/device/cdc_msc + $ make BOARD=raspberry_pi_pico get-deps + +You only need to do this once per family. Check out `complete list of dependencies and their designated path here `_ + Build ^^^^^ @@ -55,19 +74,12 @@ To build example, first change directory to an example folder. $ cd examples/device/cdc_msc -Before building, we firstly need to download dependencies such as: MCU low-level peripheral driver and external libraries e.g FreeRTOS (required by some examples). Run the ``get-deps`` target in one of the example folder as follow. You only need to do this once per mcu. Check out `complete list of dependencies and their designated path here `_ - -.. code-block:: - - $ make BOARD=raspberry_pi_pico get-deps - -Then compile with ``make BOARD=[board_name] all``\ , for example +Then compile with ``make BOARD={board_name} all`` , for example .. code-block:: $ make BOARD=raspberry_pi_pico all -Note: ``BOARD`` can be found as directory name in ``hw/bsp``\ , either in its family/boards or directly under bsp (no family). Note: some examples especially those that uses Vendor class (e.g webUSB) may requires udev permission on Linux (and/or macOS) to access usb device. It depends on your OS distro, typically copy ``99-tinyusb.rules`` and reload your udev is good to go .. code-block:: @@ -75,8 +87,8 @@ Note: some examples especially those that uses Vendor class (e.g webUSB) may req $ cp examples/device/99-tinyusb.rules /etc/udev/rules.d/ $ sudo udevadm control --reload-rules && sudo udevadm trigger -Port Selection -~~~~~~~~~~~~~~ +RootHub Port Selection +~~~~~~~~~~~~~~~~~~~~~~ If a board has several ports, one port is chosen by default in the individual board.mk file. Use option ``PORT=x`` To choose another port. For example to select the HS port of a STM32F746Disco board, use: @@ -166,7 +178,10 @@ Some board use uf2 bootloader for drag & drop in to mass storage device, uf2 can $ make BOARD=feather_nrf52840_express all uf2 IAR Support -^^^^^^^^^^^ +----------- + +Use project connection +^^^^^^^^^^^^^^^^^^^^^^ IAR Project Connection files are provided to import TinyUSB stack into your project. @@ -179,19 +194,19 @@ IAR Project Connection files are provided to import TinyUSB stack into your proj - `STM32L0xx_HAL_Driver` is only needed to run examples, TinyUSB stack itself doesn't rely on MCU's SDKs. -* Open `Tools -> Configure Custom Argument Variables` (Switch to `Global` tab if you want to do it for all your projects) +* Open ``Tools -> Configure Custom Argument Variables`` (Switch to `Global` tab if you want to do it for all your projects) Click `New Group ...`, name it to `TUSB`, Click `Add Variable ...`, name it to `TUSB_DIR`, change it's value to the path of your TinyUSB stack, for example `C:\\tinyusb` Import stack only ~~~~~~~~~~~~~~~~~ -1. Open `Project -> Add project Connection ...`, click `OK`, choose `tinyusb\\tools\\iar_template.ipcf`. +1. Open ``Project -> Add project Connection ...``, click `OK`, choose `tinyusb\\tools\\iar_template.ipcf`. Run examples ~~~~~~~~~~~~ -1. (Python3 is needed) Run `iar_gen.py` to generate .ipcf files of examples: +1. (Python3 is needed) Run ``iar_gen.py`` to generate .ipcf files of examples: .. code-block:: @@ -200,3 +215,15 @@ Run examples 2. Open `Project -> Add project Connection ...`, click `OK`, choose `tinyusb\\examples\\(.ipcf of example)`. For example `C:\\tinyusb\\examples\\device\\cdc_msc\\iar_cdc_msc.ipcf` + +Native CMake support (9.50.1+) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +With 9.50.1 release, IAR added experimental native CMake support (strangely not mentioned in public release note). Now it's possible to import CMakeLists.txt then build and debug as a normal project. + +Following these steps: + +1. Add IAR compiler binary path to system ``PATH`` environment variable, such as ``C:\Program Files\IAR Systems\Embedded Workbench 9.2\arm\bin``. +2. Create new project in IAR, in Tool chain dropdown menu, choose CMake for Arm then Import ``CMakeLists.txt`` from chosen example directory. +3. Set up board option in ``Option - CMake/CMSIS-TOOLBOX - CMake``, for example :code:`-DBOARD=stm32f439nucleo -DTOOLCHAIN=iar`, **Uncheck 'Override tools in env'**. +4. (For debug only) Choose correct CPU model in ``Option - General Options - Target``, to profit register and memory view. diff --git a/docs/reference/index.rst b/docs/reference/index.rst index a9663ee7d..9ecdf619b 100644 --- a/docs/reference/index.rst +++ b/docs/reference/index.rst @@ -4,44 +4,69 @@ Reference .. figure:: ../assets/stack.svg :width: 1600px - :alt: stackup + :alt: TinyUSB + +:: + + . + ├── docs # Documentation + ├── examples # Examples with make and cmake build system + ├── hw + │ ├── bsp # Supported boards source files + │ └── mcu # Low level mcu core & peripheral drivers + ├── lib # Sources from 3rd party such as freeRTOS, fatfs ... + ├── src # All sources files for TinyUSB stack itself. + ├── test # Tests: unit test, fuzzing, hardware test + └── tools # Files used internally - representation of the TinyUSB stack. Device Stack ============ -Supports multiple device configurations by dynamically changing usb descriptors. Low power functions such like suspend, resume, and remote wakeup. Following device classes are supported: +Supports multiple device configurations by dynamically changing USB descriptors, low power functions such like suspend, resume, and remote wakeup. The following device classes are supported: - Audio Class 2.0 (UAC2) - Bluetooth Host Controller Interface (BTH HCI) -- Communication Class (CDC) -- Device Firmware Update (DFU): DFU mode (WIP) and Runtinme +- Communication Device Class (CDC) +- Device Firmware Update (DFU): DFU mode (WIP) and Runtime - Human Interface Device (HID): Generic (In & Out), Keyboard, Mouse, Gamepad etc ... - Mass Storage Class (MSC): with multiple LUNs - Musical Instrument Digital Interface (MIDI) -- Network with RNDIS, CDC-ECM (work in progress) -- USB Test and Measurement Class (USBTMC) +- Network with RNDIS, Ethernet Control Model (ECM), Network Control Model (NCM) +- Test and Measurement Class (USBTMC) +- Video class 1.5 (UVC): work in progress - Vendor-specific class support with generic In & Out endpoints. Can be used with MS OS 2.0 compatible descriptor to load winUSB driver without INF file. - `WebUSB `__ with vendor-specific class -If you have special need, `usbd_app_driver_get_cb()` can be used to write your own class driver without modifying the stack. Here is how RPi team add their reset interface `raspberrypi/pico-sdk#197 `__ +If you have a special requirement, `usbd_app_driver_get_cb()` can be used to write your own class driver without modifying the stack. Here is how the RPi team added their reset interface `raspberrypi/pico-sdk#197 `_ Host Stack ========== - Human Interface Device (HID): Keyboard, Mouse, Generic - Mass Storage Class (MSC) -- Hub currently only supports 1 level of hub (due to my laziness) +- Communication Device Class: CDC-ACM +- Vendor serial over USB: FTDI, CP210x +- Hub with multiple-level support + +Similar to the Device Stack, if you have a special requirement, `usbh_app_driver_get_cb()` can be used to write your own class driver without modifying the stack. + +TypeC PD Stack +============== + +- Power Delivery 3.0 (PD3.0) with USB Type-C support (WIP) +- Super early stage, only for testing purpose +- Only support STM32 G4 OS Abstraction layer ==================== -TinyUSB is completely thread-safe by pushing all ISR events into a central queue, then process it later in the non-ISR context task function. It also uses semaphore/mutex to access shared resources such as CDC FIFO. Therefore the stack needs to use some of OS's basic APIs. Following OSes are already supported out of the box. +TinyUSB is completely thread-safe by pushing all Interrupt Service Request (ISR) events into a central queue, then processing them later in the non-ISR context task function. It also uses semaphore/mutex to access shared resources such as Communication Device Class (CDC) FIFO. Therefore the stack needs to use some of the OS's basic APIs. Following OSes are already supported out of the box. - **No OS** - **FreeRTOS** -- **Mynewt** Due to the newt package build system, Mynewt examples are better to be on its `own repo `__ +- `RT-Thread `_: `repo `_ +- **Mynewt** Due to the newt package build system, Mynewt examples are better to be on its `own repo `_ License ======= diff --git a/docs/reference/supported.rst b/docs/reference/supported.rst index aed64782c..7e7be25a4 100644 --- a/docs/reference/supported.rst +++ b/docs/reference/supported.rst @@ -8,6 +8,12 @@ Supported MCUs +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ | Manufacturer | Family | Device | Host | Highspeed | Driver | Note | +==============+=======================+========+======+===========+===================+==============+ +| Allwinner | F1C100s/F1C200s | ✔ | | ✔ | sunxi | musb variant | ++--------------+-----------------------+--------+------+-----------+-------------------+--------------+ +| Analog | MAX3421E | | ✔ | ✖ | max3421 | via SPI | ++--------------+-----------------------+--------+------+-----------+-------------------+--------------+ +| Brigetek | FT90x | ✔ | | ✔ | ft9xx | | ++--------------+-----------------------+--------+------+-----------+-------------------+--------------+ | Broadcom | BCM2711, BCM2837 | ✔ | | ✔ | dwc2 | | +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ | Dialog | DA1469x | ✔ | ✖ | ✖ | da146xx | | @@ -17,36 +23,46 @@ Supported MCUs | GigaDevice | GD32VF103 | ✔ | | ✖ | dwc2 | | +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ | Infineon | XMC4500 | ✔ | | ✖ | dwc2 | | -+--------------+-----------------------+--------+------+-----------+-------------------+--------------+ -| MicroChip | SAM D11, D21 | ✔ | | ✖ | samd | | -| +-----------------------+--------+------+-----------+-------------------+--------------+ -| | SAM D51, E5x | ✔ | | ✖ | samd | | -| +-----------------------+--------+------+-----------+-------------------+--------------+ -| | SAM G55 | ✔ | | ✖ | samg | | -| +-----------------------+--------+------+-----------+-------------------+--------------+ -| | SAM L21, L22 | ✔ | | ✖ | samd | | -| +-----------------------+--------+------+-----------+-------------------+--------------+ -| | SAM E70,S70,V70,V71 | ✔ | | ✔ | samx7x | | -+--------------+-----------------------+--------+------+-----------+-------------------+--------------+ ++--------------+-----+-----------------+--------+------+-----------+-------------------+--------------+ +| MicroChip | SAM | D11, D21 | ✔ | | ✖ | samd | | +| | +-----------------+--------+------+-----------+-------------------+--------------+ +| | | D51, E5x | ✔ | | ✖ | samd | | +| | +-----------------+--------+------+-----------+-------------------+--------------+ +| | | G55 | ✔ | | ✖ | samg | | +| | +-----------------+--------+------+-----------+-------------------+--------------+ +| | | L21, L22 | ✔ | | ✖ | samd | | +| | +-----------------+--------+------+-----------+-------------------+--------------+ +| | | E70,S70,V70,V71 | ✔ | | ✔ | samx7x | | +| +-----+-----------------+--------+------+-----------+-------------------+--------------+ +| | PIC | 24 | ✔ | | | pic | ci_fs variant| +| | +-----------------+--------+------+-----------+-------------------+--------------+ +| | | 32 mm, mk, mx | ✔ | | | pic | ci_fs variant| +| | +-----------------+--------+------+-----------+-------------------+--------------+ +| | | dsPIC33 | ✔ | | | pic | ci_fs variant| +| | +-----------------+--------+------+-----------+-------------------+--------------+ +| | | 32mz | ✔ | | | pic32mz | musb variant | ++--------------+-----+-----------------+--------+------+-----------+-------------------+--------------+ +| Mind Montion | mm32 | ✔ | | ✖ | mm32f327x_otg | ci_fs variant| ++--------------+-----+-----------------+--------+------+-----------+-------------------+--------------+ | NordicSemi | nRF52833, nRF52840 | ✔ | ✖ | ✖ | nrf5x | | | +-----------------------+--------+------+-----------+-------------------+--------------+ | | nRF5340 | ✔ | ✖ | ✖ | nrf5x | | +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ -| Nuvoton | NUC120 | ✔ | ✖ | ✖ | | | +| Nuvoton | NUC120 | ✔ | ✖ | ✖ | nuc120 | | | +-----------------------+--------+------+-----------+-------------------+--------------+ -| | NUC121/NUC125 | ✔ | ✖ | ✖ | | | +| | NUC121/NUC125 | ✔ | ✖ | ✖ | nuc121 | | | +-----------------------+--------+------+-----------+-------------------+--------------+ -| | NUC126 | ✔ | ✖ | ✖ | | | +| | NUC126 | ✔ | ✖ | ✖ | nuc121 | | | +-----------------------+--------+------+-----------+-------------------+--------------+ -| | NUC505 | ✔ | | ✔ | | | +| | NUC505 | ✔ | | ✔ | nuc505 | | +--------------+---------+-------------+--------+------+-----------+-------------------+--------------+ | NXP | iMXRT | RT10xx | ✔ | ✔ | ✔ | ci_hs | | | | +-------------+--------+------+-----------+-------------------+--------------+ | | | RT11xx | ✔ | ✔ | ✔ | ci_hs | | | +---------+-------------+--------+------+-----------+-------------------+--------------+ -| | Kinetis | KL25 | ✔ | ⚠ | ✖ | | | +| | Kinetis | KL | ✔ | ⚠ | ✖ | ci_fs, khci | | | | +-------------+--------+------+-----------+-------------------+--------------+ -| | | K32L2 | ✔ | | ✖ | | | +| | | K32L2 | ✔ | | ✖ | khci | ci_fs variant| | +---------+-------------+--------+------+-----------+-------------------+--------------+ | | LPC | 11u, 13, 15 | ✔ | ✖ | ✖ | lpc_ip3511 | | | | +-------------+--------+------+-----------+-------------------+--------------+ @@ -59,12 +75,16 @@ Supported MCUs | | | 54 | ✔ | | ✔ | lpc_ip3511 | | | | +-------------+--------+------+-----------+-------------------+--------------+ | | | 55 | ✔ | | ✔ | lpc_ip3511 | | +| +---------+-------------+--------+------+-----------+-------------------+--------------+ +| | MCX | N9 | ✔ | | ✔ | ci_fs, ci_hs | | +--------------+---------+-------------+--------+------+-----------+-------------------+--------------+ | Raspberry Pi | RP2040 | ✔ | ✔ | ✖ | rp2040, pio_usb | | +--------------+-----+-----------------+--------+------+-----------+-------------------+--------------+ | Renesas | RX | 63N, 65N, 72N | ✔ | ✔ | ✖ | rusb2 | | | +-----+-----------------+--------+------+-----------+-------------------+--------------+ -| | RA | XXX | ✔ | ✔ | | rusb2 | | +| | RA | 4M1, 4M3, 6M1 | ✔ | ✔ | ✖ | rusb2 | | +| | +-----------------+--------+------+-----------+-------------------+--------------+ +| | | 6M5 | ✔ | ✔ | ✔ | rusb2 | | +--------------+-----+-----------------+--------+------+-----------+-------------------+--------------+ | Silabs | EFM32GG12 | ✔ | | ✖ | dwc2 | | +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ @@ -96,7 +116,7 @@ Supported MCUs | +----+------------------+--------+------+-----------+-------------------+--------------+ | | L4+ | ✔ | | | dwc2 | | | +-----------------------+--------+------+-----------+-------------------+--------------+ -| | U5 | ⚠ | | | dwc2 | | +| | U5 | ✔ | | ✔ | dwc2 | | | +-----------------------+--------+------+-----------+-------------------+--------------+ | | WBx5 | ✔ | | | stm32_fsdev | | +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ @@ -109,6 +129,8 @@ Supported MCUs | ValentyUSB | eptri | ✔ | ✖ | ✖ | eptri | | +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ | WCH | CH32V307 | ✔ | | ✔ | ch32v307 | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ +| | CH32F20x | ✔ | | ✔ | ch32f205 | | +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ @@ -278,7 +300,6 @@ LPC 18-43 - `Embedded Artists LPC4357 Developer Kit `__ - `Keil MCB1800 Evaluation Board `__ - `LPCXpresso18S37 Development Board `__ -- `NGX LPC4330-Xplorer `__ LPC 51 ^^^^^^ @@ -415,4 +436,5 @@ Tomu WCH --- -- `CH32V307V-R1-1v0 ` +- `CH32V307V-R1-1v0 `__ +- `CH32F205R-R0-1v0 `__ diff --git a/examples/build_system/cmake/cpu/arm1176jzf-s.cmake b/examples/build_system/cmake/cpu/arm1176jzf-s.cmake new file mode 100644 index 000000000..8029e3987 --- /dev/null +++ b/examples/build_system/cmake/cpu/arm1176jzf-s.cmake @@ -0,0 +1,21 @@ +if (TOOLCHAIN STREQUAL "gcc") + set(TOOLCHAIN_COMMON_FLAGS + -mcpu=arm1176jzf-s + -ffreestanding + ) + # set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "clang") + set(TOOLCHAIN_COMMON_FLAGS + --target=arm-none-eabi + -mcpu=arm1176jzf-s + -mfpu=none + -mfloat-abi=soft + -ffreestanding + ) + #set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "iar") + message(FATAL_ERROR "IAR not supported") + +endif () diff --git a/examples/build_system/cmake/cpu/arm926ej-s.cmake b/examples/build_system/cmake/cpu/arm926ej-s.cmake new file mode 100644 index 000000000..c19b9f8a8 --- /dev/null +++ b/examples/build_system/cmake/cpu/arm926ej-s.cmake @@ -0,0 +1,21 @@ +if (TOOLCHAIN STREQUAL "gcc") + set(TOOLCHAIN_COMMON_FLAGS + -mcpu=arm926ej-s + -ffreestanding + ) + # set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "clang") + set(TOOLCHAIN_COMMON_FLAGS + --target=arm-none-eabi + -mcpu=arm926ej-s + -mfpu=none + -mfloat-abi=soft + -ffreestanding + ) + #set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "iar") + message(FATAL_ERROR "IAR not supported") + +endif () diff --git a/examples/build_system/cmake/cpu/cortex-a53.cmake b/examples/build_system/cmake/cpu/cortex-a53.cmake new file mode 100644 index 000000000..dde8c0a0c --- /dev/null +++ b/examples/build_system/cmake/cpu/cortex-a53.cmake @@ -0,0 +1,17 @@ +if (TOOLCHAIN STREQUAL "gcc") + set(TOOLCHAIN_COMMON_FLAGS + -mcpu=cortex-a53 + ) + # set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "clang") + set(TOOLCHAIN_COMMON_FLAGS + --target=arm-none-eabi + -mcpu=cortex-a53 + ) + #set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "iar") + message(FATAL_ERROR "IAR not supported") + +endif () diff --git a/examples/build_system/cmake/cpu/cortex-a72.cmake b/examples/build_system/cmake/cpu/cortex-a72.cmake new file mode 100644 index 000000000..a44324234 --- /dev/null +++ b/examples/build_system/cmake/cpu/cortex-a72.cmake @@ -0,0 +1,17 @@ +if (TOOLCHAIN STREQUAL "gcc") + set(TOOLCHAIN_COMMON_FLAGS + -mcpu=cortex-a72 + ) + # set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "clang") + set(TOOLCHAIN_COMMON_FLAGS + --target=arm-none-eabi + -mcpu=cortex-a72 + ) + #set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "iar") + message(FATAL_ERROR "IAR not supported") + +endif () diff --git a/tools/cmake/cpu/cortex-m0.cmake b/examples/build_system/cmake/cpu/cortex-m0.cmake similarity index 65% rename from tools/cmake/cpu/cortex-m0.cmake rename to examples/build_system/cmake/cpu/cortex-m0.cmake index bc2257048..62019d90d 100644 --- a/tools/cmake/cpu/cortex-m0.cmake +++ b/examples/build_system/cmake/cpu/cortex-m0.cmake @@ -4,14 +4,19 @@ if (TOOLCHAIN STREQUAL "gcc") -mcpu=cortex-m0plus -mfloat-abi=soft ) + set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") +elseif (TOOLCHAIN STREQUAL "clang") + set(TOOLCHAIN_COMMON_FLAGS + --target=arm-none-eabi + -mcpu=cortex-m0 + ) set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS --cpu cortex-m0 ) - set(FREERTOS_PORT IAR_ARM_CM0 CACHE INTERNAL "") endif () diff --git a/tools/cmake/cpu/cortex-m0plus.cmake b/examples/build_system/cmake/cpu/cortex-m0plus.cmake similarity index 65% rename from tools/cmake/cpu/cortex-m0plus.cmake rename to examples/build_system/cmake/cpu/cortex-m0plus.cmake index bc2257048..ddf0f16af 100644 --- a/tools/cmake/cpu/cortex-m0plus.cmake +++ b/examples/build_system/cmake/cpu/cortex-m0plus.cmake @@ -4,14 +4,19 @@ if (TOOLCHAIN STREQUAL "gcc") -mcpu=cortex-m0plus -mfloat-abi=soft ) + set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") +elseif (TOOLCHAIN STREQUAL "clang") + set(TOOLCHAIN_COMMON_FLAGS + --target=arm-none-eabi + -mcpu=cortex-m0plus + ) set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS --cpu cortex-m0 ) - set(FREERTOS_PORT IAR_ARM_CM0 CACHE INTERNAL "") endif () diff --git a/examples/build_system/cmake/cpu/cortex-m23.cmake b/examples/build_system/cmake/cpu/cortex-m23.cmake new file mode 100644 index 000000000..00382ed9b --- /dev/null +++ b/examples/build_system/cmake/cpu/cortex-m23.cmake @@ -0,0 +1,22 @@ +if (TOOLCHAIN STREQUAL "gcc") + set(TOOLCHAIN_COMMON_FLAGS + -mthumb + -mcpu=cortex-m23 + -mfloat-abi=soft + ) + set(FREERTOS_PORT GCC_ARM_CM23_NTZ_NONSECURE CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "clang") + set(TOOLCHAIN_COMMON_FLAGS + --target=arm-none-eabi + -mcpu=cortex-m23 + ) + set(FREERTOS_PORT GCC_ARM_CM23_NTZ_NONSECURE CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "iar") + set(TOOLCHAIN_COMMON_FLAGS + --cpu cortex-m23 + ) + set(FREERTOS_PORT IAR_ARM_CM23_NTZ_NONSECURE CACHE INTERNAL "") + +endif () diff --git a/tools/cmake/cpu/cortex-m3.cmake b/examples/build_system/cmake/cpu/cortex-m3.cmake similarity index 63% rename from tools/cmake/cpu/cortex-m3.cmake rename to examples/build_system/cmake/cpu/cortex-m3.cmake index f6f5a62f8..27888604e 100644 --- a/tools/cmake/cpu/cortex-m3.cmake +++ b/examples/build_system/cmake/cpu/cortex-m3.cmake @@ -3,14 +3,19 @@ if (TOOLCHAIN STREQUAL "gcc") -mthumb -mcpu=cortex-m3 ) + set(FREERTOS_PORT GCC_ARM_CM3 CACHE INTERNAL "") +elseif (TOOLCHAIN STREQUAL "clang") + set(TOOLCHAIN_COMMON_FLAGS + --target=arm-none-eabi + -mcpu=cortex-m3 + ) set(FREERTOS_PORT GCC_ARM_CM3 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS --cpu cortex-m3 ) - set(FREERTOS_PORT IAR_ARM_CM3 CACHE INTERNAL "") endif () diff --git a/examples/build_system/cmake/cpu/cortex-m33-nodsp-nofp.cmake b/examples/build_system/cmake/cpu/cortex-m33-nodsp-nofp.cmake new file mode 100644 index 000000000..51fd70b0e --- /dev/null +++ b/examples/build_system/cmake/cpu/cortex-m33-nodsp-nofp.cmake @@ -0,0 +1,18 @@ +if (TOOLCHAIN STREQUAL "gcc") + set(TOOLCHAIN_COMMON_FLAGS + -mthumb + -mcpu=cortex-m33+nodsp + -mfloat-abi=soft + ) + set(FREERTOS_PORT GCC_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "clang") + message(FATAL_ERROR "Clang is not supported for this target") + +elseif (TOOLCHAIN STREQUAL "iar") + set(TOOLCHAIN_COMMON_FLAGS + --cpu cortex-m33+nodsp + ) + set(FREERTOS_PORT IAR_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "") + +endif () diff --git a/tools/cmake/cpu/cortex-m33.cmake b/examples/build_system/cmake/cpu/cortex-m33.cmake similarity index 54% rename from tools/cmake/cpu/cortex-m33.cmake rename to examples/build_system/cmake/cpu/cortex-m33.cmake index 7ebaf1748..d56d07ebc 100644 --- a/tools/cmake/cpu/cortex-m33.cmake +++ b/examples/build_system/cmake/cpu/cortex-m33.cmake @@ -5,7 +5,14 @@ if (TOOLCHAIN STREQUAL "gcc") -mfloat-abi=hard -mfpu=fpv5-sp-d16 ) + set(FREERTOS_PORT GCC_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "") +elseif (TOOLCHAIN STREQUAL "clang") + set(TOOLCHAIN_COMMON_FLAGS + --target=arm-none-eabi + -mcpu=cortex-m33 + -mfpu=fpv5-sp-d16 + ) set(FREERTOS_PORT GCC_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "iar") @@ -13,7 +20,6 @@ elseif (TOOLCHAIN STREQUAL "iar") --cpu cortex-m33 --fpu VFPv5-SP ) - - set(FREERTOS_PORT IAR_ARM_CM4F CACHE INTERNAL "") + set(FREERTOS_PORT IAR_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "") endif () diff --git a/tools/cmake/cpu/cortex-m4.cmake b/examples/build_system/cmake/cpu/cortex-m4.cmake similarity index 63% rename from tools/cmake/cpu/cortex-m4.cmake rename to examples/build_system/cmake/cpu/cortex-m4.cmake index 4e9bc242d..9cdadc6f8 100644 --- a/tools/cmake/cpu/cortex-m4.cmake +++ b/examples/build_system/cmake/cpu/cortex-m4.cmake @@ -5,7 +5,16 @@ if (TOOLCHAIN STREQUAL "gcc") -mfloat-abi=hard -mfpu=fpv4-sp-d16 ) + if (NOT DEFINED FREERTOS_PORT) + set(FREERTOS_PORT GCC_ARM_CM4F CACHE INTERNAL "") + endif () +elseif (TOOLCHAIN STREQUAL "clang") + set(TOOLCHAIN_COMMON_FLAGS + --target=arm-none-eabi + -mcpu=cortex-m4 + -mfpu=fpv4-sp-d16 + ) if (NOT DEFINED FREERTOS_PORT) set(FREERTOS_PORT GCC_ARM_CM4F CACHE INTERNAL "") endif () @@ -13,7 +22,7 @@ if (TOOLCHAIN STREQUAL "gcc") elseif (TOOLCHAIN STREQUAL "iar") set(TOOLCHAIN_COMMON_FLAGS --cpu cortex-m4 - --fpu VFPv4 + --fpu VFPv4_sp ) if (NOT DEFINED FREERTOS_PORT) diff --git a/examples/build_system/cmake/cpu/cortex-m7-fpsp.cmake b/examples/build_system/cmake/cpu/cortex-m7-fpsp.cmake new file mode 100644 index 000000000..b10f00fc2 --- /dev/null +++ b/examples/build_system/cmake/cpu/cortex-m7-fpsp.cmake @@ -0,0 +1,25 @@ +if (TOOLCHAIN STREQUAL "gcc") + set(TOOLCHAIN_COMMON_FLAGS + -mthumb + -mcpu=cortex-m7 + -mfloat-abi=hard + -mfpu=fpv5-sp-d16 + ) + set(FREERTOS_PORT GCC_ARM_CM7 CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "clang") + set(TOOLCHAIN_COMMON_FLAGS + --target=arm-none-eabi + -mcpu=cortex-m7 + -mfpu=fpv5-sp-d16 + ) + set(FREERTOS_PORT GCC_ARM_CM7 CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "iar") + set(TOOLCHAIN_COMMON_FLAGS + --cpu cortex-m7 + --fpu VFPv5_sp + ) + set(FREERTOS_PORT IAR_ARM_CM7 CACHE INTERNAL "") + +endif () diff --git a/tools/cmake/cpu/cortex-m7.cmake b/examples/build_system/cmake/cpu/cortex-m7.cmake similarity index 65% rename from tools/cmake/cpu/cortex-m7.cmake rename to examples/build_system/cmake/cpu/cortex-m7.cmake index 3e5f7f44b..b41dfded5 100644 --- a/tools/cmake/cpu/cortex-m7.cmake +++ b/examples/build_system/cmake/cpu/cortex-m7.cmake @@ -5,7 +5,14 @@ if (TOOLCHAIN STREQUAL "gcc") -mfloat-abi=hard -mfpu=fpv5-d16 ) + set(FREERTOS_PORT GCC_ARM_CM7 CACHE INTERNAL "") +elseif (TOOLCHAIN STREQUAL "clang") + set(TOOLCHAIN_COMMON_FLAGS + --target=arm-none-eabi + -mcpu=cortex-m7 + -mfpu=fpv5-d16 + ) set(FREERTOS_PORT GCC_ARM_CM7 CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "iar") @@ -13,7 +20,6 @@ elseif (TOOLCHAIN STREQUAL "iar") --cpu cortex-m7 --fpu VFPv5_D16 ) - set(FREERTOS_PORT IAR_ARM_CM7 CACHE INTERNAL "") endif () diff --git a/examples/build_system/cmake/cpu/msp430.cmake b/examples/build_system/cmake/cpu/msp430.cmake new file mode 100644 index 000000000..584ec5741 --- /dev/null +++ b/examples/build_system/cmake/cpu/msp430.cmake @@ -0,0 +1,10 @@ +if (TOOLCHAIN STREQUAL "gcc") + set(FREERTOS_PORT GCC_MSP430F449 CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "clang") + message(FATAL_ERROR "Clang is not supported for this target") + +elseif (TOOLCHAIN STREQUAL "iar") + set(FREERTOS_PORT IAR_MSP430 CACHE INTERNAL "") + +endif () diff --git a/examples/build_system/cmake/cpu/rv32i-ilp32.cmake b/examples/build_system/cmake/cpu/rv32i-ilp32.cmake new file mode 100644 index 000000000..b4889e6ff --- /dev/null +++ b/examples/build_system/cmake/cpu/rv32i-ilp32.cmake @@ -0,0 +1,19 @@ +if (TOOLCHAIN STREQUAL "gcc") + set(TOOLCHAIN_COMMON_FLAGS + -march=rv32i + -mabi=ilp32 + ) + set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "clang") + set(TOOLCHAIN_COMMON_FLAGS + -march=rv32i + -mabi=ilp32 + ) + set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "iar") + message(FATAL_ERROR "IAR not supported") + set(FREERTOS_PORT IAR_RISC_V CACHE INTERNAL "") + +endif () diff --git a/examples/build_system/cmake/cpu/rv32imac-ilp32.cmake b/examples/build_system/cmake/cpu/rv32imac-ilp32.cmake new file mode 100644 index 000000000..dd1bc0af7 --- /dev/null +++ b/examples/build_system/cmake/cpu/rv32imac-ilp32.cmake @@ -0,0 +1,18 @@ +if (TOOLCHAIN STREQUAL "gcc") + set(TOOLCHAIN_COMMON_FLAGS + -march=rv32imac + -mabi=ilp32 + ) + set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "clang") + set(TOOLCHAIN_COMMON_FLAGS + -march=rv32imac + -mabi=ilp32 + ) + set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "iar") + message(FATAL_ERROR "IAR not supported") + set(FREERTOS_PORT IAR_RISC_V CACHE INTERNAL "") +endif () diff --git a/examples/build_system/cmake/toolchain/aarch64_gcc.cmake b/examples/build_system/cmake/toolchain/aarch64_gcc.cmake new file mode 100644 index 000000000..2d30a0b71 --- /dev/null +++ b/examples/build_system/cmake/toolchain/aarch64_gcc.cmake @@ -0,0 +1,21 @@ +if (NOT DEFINED CMAKE_C_COMPILER) + set(CMAKE_C_COMPILER "aarch64-none-elf-gcc") +endif () + +if (NOT DEFINED CMAKE_CXX_COMPILER) + set(CMAKE_CXX_COMPILER "aarch64-none-elf-g++") +endif () + +set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) +set(CMAKE_SIZE "aarch64-none-elf-size" CACHE FILEPATH "") +set(CMAKE_OBJCOPY "aarch64-none-elf-objcopy" CACHE FILEPATH "") +set(CMAKE_OBJDUMP "aarch64-none-elf-objdump" CACHE FILEPATH "") + +include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) + +get_property(IS_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE) +if (IS_IN_TRY_COMPILE) + set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -nostdlib") + set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -nostdlib") + cmake_print_variables(CMAKE_C_LINK_FLAGS) +endif () diff --git a/examples/build_system/cmake/toolchain/arm_clang.cmake b/examples/build_system/cmake/toolchain/arm_clang.cmake new file mode 100644 index 000000000..754d672fd --- /dev/null +++ b/examples/build_system/cmake/toolchain/arm_clang.cmake @@ -0,0 +1,21 @@ +if (NOT DEFINED CMAKE_C_COMPILER) + set(CMAKE_C_COMPILER "clang") +endif () + +if (NOT DEFINED CMAKE_CXX_COMPILER) + set(CMAKE_CXX_COMPILER "clang++") +endif () + +set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) +set(CMAKE_SIZE "llvm-size" CACHE FILEPATH "") +set(CMAKE_OBJCOPY "llvm-objcopy" CACHE FILEPATH "") +set(CMAKE_OBJDUMP "llvm-objdump" CACHE FILEPATH "") + +include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) + +get_property(IS_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE) +if (IS_IN_TRY_COMPILE) + set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -nostdlib") + set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -nostdlib") + cmake_print_variables(CMAKE_C_LINK_FLAGS) +endif () diff --git a/examples/build_system/cmake/toolchain/arm_gcc.cmake b/examples/build_system/cmake/toolchain/arm_gcc.cmake new file mode 100644 index 000000000..d3d73c629 --- /dev/null +++ b/examples/build_system/cmake/toolchain/arm_gcc.cmake @@ -0,0 +1,21 @@ +if (NOT DEFINED CMAKE_C_COMPILER) + set(CMAKE_C_COMPILER "arm-none-eabi-gcc") +endif () + +if (NOT DEFINED CMAKE_CXX_COMPILER) + set(CMAKE_CXX_COMPILER "arm-none-eabi-g++") +endif () + +set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) +set(CMAKE_SIZE "arm-none-eabi-size" CACHE FILEPATH "") +set(CMAKE_OBJCOPY "arm-none-eabi-objcopy" CACHE FILEPATH "") +set(CMAKE_OBJDUMP "arm-none-eabi-objdump" CACHE FILEPATH "") + +include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) + +get_property(IS_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE) +if (IS_IN_TRY_COMPILE) + set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -nostdlib") + set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -nostdlib") + cmake_print_variables(CMAKE_C_LINK_FLAGS) +endif () diff --git a/examples/build_system/cmake/toolchain/arm_iar.cmake b/examples/build_system/cmake/toolchain/arm_iar.cmake new file mode 100644 index 000000000..6d2219ca8 --- /dev/null +++ b/examples/build_system/cmake/toolchain/arm_iar.cmake @@ -0,0 +1,17 @@ +if (NOT DEFINED CMAKE_C_COMPILER) + set(CMAKE_C_COMPILER "iccarm") +endif() + +if (NOT DEFINED CMAKE_CXX_COMPILER) + set(CMAKE_CXX_COMPILER "iccarm") +endif() + +if (NOT DEFINED CMAKE_ASM_COMPILER) + set(CMAKE_ASM_COMPILER "iasmarm") +endif() + +set(CMAKE_SIZE "size" CACHE FILEPATH "") +set(CMAKE_OBJCOPY "ielftool" CACHE FILEPATH "") +set(CMAKE_OBJDUMP "iefdumparm" CACHE FILEPATH "") + +include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) diff --git a/examples/build_system/cmake/toolchain/common.cmake b/examples/build_system/cmake/toolchain/common.cmake new file mode 100644 index 000000000..688715914 --- /dev/null +++ b/examples/build_system/cmake/toolchain/common.cmake @@ -0,0 +1,64 @@ +include(CMakePrintHelpers) + +# ---------------------------------------------------------------------------- +# Common +# ---------------------------------------------------------------------------- +set(CMAKE_SYSTEM_NAME Generic) +set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE) + +# Look for includes and libraries only in the target system prefix. +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + +# pass TOOLCHAIN_CPU to +set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES CMAKE_SYSTEM_PROCESSOR) +include(${CMAKE_CURRENT_LIST_DIR}/../cpu/${CMAKE_SYSTEM_PROCESSOR}.cmake) + +# ---------------------------------------------------------------------------- +# Compile flags +# ---------------------------------------------------------------------------- +if (TOOLCHAIN STREQUAL "gcc") + list(APPEND TOOLCHAIN_COMMON_FLAGS + -fdata-sections + -ffunction-sections + -fsingle-precision-constant + -fno-strict-aliasing + ) + list(APPEND TOOLCHAIN_EXE_LINKER_FLAGS + -Wl,--print-memory-usage + -Wl,--gc-sections + -Wl,--cref + ) + +elseif (TOOLCHAIN STREQUAL "iar") + #list(APPEND TOOLCHAIN_COMMON_FLAGS) + list(APPEND TOOLCHAIN_EXE_LINKER_FLAGS + --diag_suppress=Li065 + ) + +elseif (TOOLCHAIN STREQUAL "clang") + list(APPEND TOOLCHAIN_COMMON_FLAGS + -fdata-sections + -ffunction-sections + -fno-strict-aliasing + ) + list(APPEND TOOLCHAIN_EXE_LINKER_FLAGS + -Wl,--print-memory-usage + -Wl,--gc-sections + -Wl,--cref + ) +endif () + +# join the toolchain flags into a single string +list(JOIN TOOLCHAIN_COMMON_FLAGS " " TOOLCHAIN_COMMON_FLAGS) +foreach (LANG IN ITEMS C CXX ASM) + set(CMAKE_${LANG}_FLAGS_INIT ${TOOLCHAIN_COMMON_FLAGS}) + # optimization flags for LOG, LOGGER ? + #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) diff --git a/examples/build_system/cmake/toolchain/msp430_gcc.cmake b/examples/build_system/cmake/toolchain/msp430_gcc.cmake new file mode 100644 index 000000000..73368adba --- /dev/null +++ b/examples/build_system/cmake/toolchain/msp430_gcc.cmake @@ -0,0 +1,15 @@ +if (NOT DEFINED CMAKE_C_COMPILER) + set(CMAKE_C_COMPILER "msp430-elf-gcc") +endif () + +if (NOT DEFINED CMAKE_CXX_COMPILER) + set(CMAKE_CXX_COMPILER "msp430-elf-g++") +endif () + +set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) + +set(CMAKE_SIZE "msp430-elf-size" CACHE FILEPATH "") +set(CMAKE_OBJCOPY "msp430-elf-objcopy" CACHE FILEPATH "") +set(CMAKE_OBJDUMP "msp430-elf-objdump" CACHE FILEPATH "") + +include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) diff --git a/examples/build_system/cmake/toolchain/riscv_gcc.cmake b/examples/build_system/cmake/toolchain/riscv_gcc.cmake new file mode 100644 index 000000000..904b27294 --- /dev/null +++ b/examples/build_system/cmake/toolchain/riscv_gcc.cmake @@ -0,0 +1,21 @@ +if (NOT DEFINED CMAKE_C_COMPILER) + set(CMAKE_C_COMPILER "riscv-none-embed-gcc") +endif () + +if (NOT DEFINED CMAKE_CXX_COMPILER) + set(CMAKE_CXX_COMPILER "riscv-none-embed-g++") +endif () + +set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) +set(CMAKE_SIZE "riscv-none-embed-size" CACHE FILEPATH "") +set(CMAKE_OBJCOPY "riscv-none-embed-objcopy" CACHE FILEPATH "") +set(CMAKE_OBJDUMP "riscv-none-embed-objdump" CACHE FILEPATH "") + +include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) + +get_property(IS_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE) +if (IS_IN_TRY_COMPILE) + set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -nostdlib") + set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -nostdlib") + cmake_print_variables(CMAKE_C_LINK_FLAGS) +endif () diff --git a/tools/make/cpu/arm1176.mk b/examples/build_system/make/cpu/arm1176jzf-s.mk similarity index 100% rename from tools/make/cpu/arm1176.mk rename to examples/build_system/make/cpu/arm1176jzf-s.mk diff --git a/examples/build_system/make/cpu/arm926ej-s.mk b/examples/build_system/make/cpu/arm926ej-s.mk new file mode 100644 index 000000000..5b84f514f --- /dev/null +++ b/examples/build_system/make/cpu/arm926ej-s.mk @@ -0,0 +1,9 @@ +ifeq ($(TOOLCHAIN),gcc) + CFLAGS += \ + -mcpu=arm926ej-s \ + +else ifeq ($(TOOLCHAIN),iar) + #CFLAGS += --cpu cortex-a53 + #ASFLAGS += --cpu cortex-a53 + +endif diff --git a/tools/make/cpu/cortex-a53.mk b/examples/build_system/make/cpu/cortex-a53.mk similarity index 100% rename from tools/make/cpu/cortex-a53.mk rename to examples/build_system/make/cpu/cortex-a53.mk diff --git a/tools/make/cpu/cortex-a72.mk b/examples/build_system/make/cpu/cortex-a72.mk similarity index 100% rename from tools/make/cpu/cortex-a72.mk rename to examples/build_system/make/cpu/cortex-a72.mk diff --git a/tools/make/cpu/cortex-m0.mk b/examples/build_system/make/cpu/cortex-m0.mk similarity index 67% rename from tools/make/cpu/cortex-m0.mk rename to examples/build_system/make/cpu/cortex-m0.mk index feb0f395b..c2c33a2ee 100644 --- a/tools/make/cpu/cortex-m0.mk +++ b/examples/build_system/make/cpu/cortex-m0.mk @@ -4,10 +4,18 @@ ifeq ($(TOOLCHAIN),gcc) -mcpu=cortex-m0 \ -mfloat-abi=soft \ +else ifeq ($(TOOLCHAIN),clang) + CFLAGS += \ + --target=arm-none-eabi \ + -mcpu=cortex-m0 \ + else ifeq ($(TOOLCHAIN),iar) # IAR Flags CFLAGS += --cpu cortex-m0 ASFLAGS += --cpu cortex-m0 + +else + $(error "TOOLCHAIN is not supported") endif # For freeRTOS port source diff --git a/tools/make/cpu/cortex-m0plus.mk b/examples/build_system/make/cpu/cortex-m0plus.mk similarity index 67% rename from tools/make/cpu/cortex-m0plus.mk rename to examples/build_system/make/cpu/cortex-m0plus.mk index b416b7a4a..fe8feb227 100644 --- a/tools/make/cpu/cortex-m0plus.mk +++ b/examples/build_system/make/cpu/cortex-m0plus.mk @@ -4,10 +4,18 @@ ifeq ($(TOOLCHAIN),gcc) -mcpu=cortex-m0plus \ -mfloat-abi=soft \ +else ifeq ($(TOOLCHAIN),clang) + CFLAGS += \ + --target=arm-none-eabi \ + -mcpu=cortex-m0plus \ + else ifeq ($(TOOLCHAIN),iar) # IAR Flags CFLAGS += --cpu cortex-m0+ ASFLAGS += --cpu cortex-m0+ + +else + $(error "TOOLCHAIN is not supported") endif # For freeRTOS port source diff --git a/examples/build_system/make/cpu/cortex-m23.mk b/examples/build_system/make/cpu/cortex-m23.mk new file mode 100644 index 000000000..7ab758352 --- /dev/null +++ b/examples/build_system/make/cpu/cortex-m23.mk @@ -0,0 +1,22 @@ +ifeq ($(TOOLCHAIN),gcc) + CFLAGS += \ + -mthumb \ + -mcpu=cortex-m23 \ + -mfloat-abi=soft \ + +else ifeq ($(TOOLCHAIN),clang) + CFLAGS += \ + --target=arm-none-eabi \ + -mcpu=cortex-m23 \ + +else ifeq ($(TOOLCHAIN),iar) + # IAR Flags + CFLAGS += --cpu cortex-m23 + ASFLAGS += --cpu cortex-m23 + +else + $(error "TOOLCHAIN is not supported") +endif + +# For freeRTOS port source +FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM23 diff --git a/tools/make/cpu/cortex-m3.mk b/examples/build_system/make/cpu/cortex-m3.mk similarity index 57% rename from tools/make/cpu/cortex-m3.mk rename to examples/build_system/make/cpu/cortex-m3.mk index 7a34b9e04..b6325313f 100644 --- a/tools/make/cpu/cortex-m3.mk +++ b/examples/build_system/make/cpu/cortex-m3.mk @@ -4,13 +4,18 @@ ifeq ($(TOOLCHAIN),gcc) -mcpu=cortex-m3 \ -mfloat-abi=soft \ +else ifeq ($(TOOLCHAIN),clang) + CFLAGS += \ + --target=arm-none-eabi \ + -mcpu=cortex-m3 \ + else ifeq ($(TOOLCHAIN),iar) # IAR Flags - CFLAGS += \ - --cpu cortex-m3 \ + CFLAGS += --cpu cortex-m3 + ASFLAGS += --cpu cortex-m3 - ASFLAGS += \ - --cpu cortex-m3 +else + $(error "TOOLCHAIN is not supported") endif # For freeRTOS port source diff --git a/examples/build_system/make/cpu/cortex-m33-nodsp-nofp.mk b/examples/build_system/make/cpu/cortex-m33-nodsp-nofp.mk new file mode 100644 index 000000000..405053dd0 --- /dev/null +++ b/examples/build_system/make/cpu/cortex-m33-nodsp-nofp.mk @@ -0,0 +1,24 @@ +ifeq ($(TOOLCHAIN),gcc) + CFLAGS += \ + -mthumb \ + -mcpu=cortex-m33+nodsp \ + -mfloat-abi=soft \ + +else ifeq ($(TOOLCHAIN),clang) + CFLAGS += \ + --target=arm-none-eabi \ + -mcpu=cortex-m33 \ + -mfpu=softvp \ + +else ifeq ($(TOOLCHAIN),iar) + CFLAGS += \ + --cpu cortex-m33+nodsp \ + + ASFLAGS += \ + --cpu cortex-m33+nodsp \ + +else + $(error "TOOLCHAIN is not supported") +endif + +FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM33_NTZ/non_secure diff --git a/tools/make/cpu/cortex-m33.mk b/examples/build_system/make/cpu/cortex-m33.mk similarity index 62% rename from tools/make/cpu/cortex-m33.mk rename to examples/build_system/make/cpu/cortex-m33.mk index fe5b7b380..47b0eaecd 100644 --- a/tools/make/cpu/cortex-m33.mk +++ b/examples/build_system/make/cpu/cortex-m33.mk @@ -5,15 +5,23 @@ ifeq ($(TOOLCHAIN),gcc) -mfloat-abi=hard \ -mfpu=fpv5-sp-d16 \ +else ifeq ($(TOOLCHAIN),clang) + CFLAGS += \ + --target=arm-none-eabi \ + -mcpu=cortex-m33 \ + -mfpu=fpv5-sp-d16 \ + else ifeq ($(TOOLCHAIN),iar) - CFLAGS += \ + CFLAGS += \ --cpu cortex-m33 \ --fpu VFPv5-SP \ - ASFLAGS += \ + ASFLAGS += \ --cpu cortex-m33 \ --fpu VFPv5-SP \ +else + $(error "TOOLCHAIN is not supported") endif FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM33_NTZ/non_secure diff --git a/tools/make/cpu/cortex-m4.mk b/examples/build_system/make/cpu/cortex-m4.mk similarity index 64% rename from tools/make/cpu/cortex-m4.mk rename to examples/build_system/make/cpu/cortex-m4.mk index d8776b5d8..4e16819d1 100644 --- a/tools/make/cpu/cortex-m4.mk +++ b/examples/build_system/make/cpu/cortex-m4.mk @@ -5,9 +5,18 @@ ifeq ($(TOOLCHAIN),gcc) -mfloat-abi=hard \ -mfpu=fpv4-sp-d16 \ +else ifeq ($(TOOLCHAIN),clang) + CFLAGS += \ + --target=arm-none-eabi \ + -mcpu=cortex-m4 \ + -mfpu=fpv4-sp-d16 \ + else ifeq ($(TOOLCHAIN),iar) CFLAGS += --cpu cortex-m4 --fpu VFPv4 ASFLAGS += --cpu cortex-m4 --fpu VFPv4 + +else + $(error "TOOLCHAIN is not supported") endif FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM4F diff --git a/examples/build_system/make/cpu/cortex-m7-fpsp.mk b/examples/build_system/make/cpu/cortex-m7-fpsp.mk new file mode 100644 index 000000000..cd42c6fb8 --- /dev/null +++ b/examples/build_system/make/cpu/cortex-m7-fpsp.mk @@ -0,0 +1,27 @@ +ifeq ($(TOOLCHAIN),gcc) + CFLAGS += \ + -mthumb \ + -mcpu=cortex-m7 \ + -mfloat-abi=hard \ + -mfpu=fpv5-sp-d16 \ + +else ifeq ($(TOOLCHAIN),clang) + CFLAGS += \ + --target=arm-none-eabi \ + -mcpu=cortex-m7 \ + -mfpu=fpv5-sp-d16 \ + +else ifeq ($(TOOLCHAIN),iar) + CFLAGS += \ + --cpu cortex-m7 \ + --fpu VFPv5_sp \ + + ASFLAGS += \ + --cpu cortex-m7 \ + --fpu VFPv5_sp \ + +else + $(error "TOOLCHAIN is not supported") +endif + +FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM7/r0p1 diff --git a/tools/make/cpu/cortex-m7.mk b/examples/build_system/make/cpu/cortex-m7.mk similarity index 67% rename from tools/make/cpu/cortex-m7.mk rename to examples/build_system/make/cpu/cortex-m7.mk index 0e3461787..3e6116179 100644 --- a/tools/make/cpu/cortex-m7.mk +++ b/examples/build_system/make/cpu/cortex-m7.mk @@ -5,6 +5,12 @@ ifeq ($(TOOLCHAIN),gcc) -mfloat-abi=hard \ -mfpu=fpv5-d16 \ +else ifeq ($(TOOLCHAIN),clang) + CFLAGS += \ + --target=arm-none-eabi \ + -mcpu=cortex-m7 \ + -mfpu=fpv5-d16 \ + else ifeq ($(TOOLCHAIN),iar) CFLAGS += \ --cpu cortex-m7 \ @@ -14,6 +20,8 @@ else ifeq ($(TOOLCHAIN),iar) --cpu cortex-m7 \ --fpu VFPv5_D16 \ +else + $(error "TOOLCHAIN is not supported") endif FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM7/r0p1 diff --git a/examples/build_system/make/cpu/msp430.mk b/examples/build_system/make/cpu/msp430.mk new file mode 100644 index 000000000..6daa2c38d --- /dev/null +++ b/examples/build_system/make/cpu/msp430.mk @@ -0,0 +1,12 @@ +ifeq ($(TOOLCHAIN),gcc) + # nothing to add +else ifeq ($(TOOLCHAIN),clang) + # nothing to add +else ifeq ($(TOOLCHAIN),iar) + # nothing to add +else + $(error "TOOLCHAIN is not supported") +endif + +# For freeRTOS port source +FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/GCC_MSP430F449 diff --git a/examples/build_system/make/cpu/rv32i-ilp32.mk b/examples/build_system/make/cpu/rv32i-ilp32.mk new file mode 100644 index 000000000..a465baf4c --- /dev/null +++ b/examples/build_system/make/cpu/rv32i-ilp32.mk @@ -0,0 +1,13 @@ +ifeq ($(TOOLCHAIN),gcc) + CFLAGS += \ + -march=rv32i \ + -mabi=ilp32 \ + +else ifeq ($(TOOLCHAIN),iar) + #CFLAGS += --cpu cortex-a53 + #ASFLAGS += --cpu cortex-a53 + +endif + +# For freeRTOS port source +FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V diff --git a/examples/build_system/make/cpu/rv32imac-ilp32.mk b/examples/build_system/make/cpu/rv32imac-ilp32.mk new file mode 100644 index 000000000..2b6493e48 --- /dev/null +++ b/examples/build_system/make/cpu/rv32imac-ilp32.mk @@ -0,0 +1,13 @@ +ifeq ($(TOOLCHAIN),gcc) + CFLAGS += \ + -march=rv32imac \ + -mabi=ilp32 \ + +else ifeq ($(TOOLCHAIN),iar) + #CFLAGS += --cpu cortex-a53 + #ASFLAGS += --cpu cortex-a53 + +endif + +# For freeRTOS port source +FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V diff --git a/examples/make.mk b/examples/build_system/make/make.mk similarity index 74% rename from examples/make.mk rename to examples/build_system/make/make.mk index a590e34f7..a78f4130d 100644 --- a/examples/make.mk +++ b/examples/build_system/make/make.mk @@ -2,23 +2,39 @@ # Common make definition for all examples # --------------------------------------- -# Supported toolchain: gcc, iar -TOOLCHAIN ?= gcc +#------------------------------------------------------------- +# Toolchain +# Can be changed via TOOLCHAIN=gcc|iar or CC=arm-none-eabi-gcc|iccarm|clang +#------------------------------------------------------------- + +ifneq (,$(findstring clang,$(CC))) + TOOLCHAIN = clang +else ifneq (,$(findstring iccarm,$(CC))) + TOOLCHAIN = iar +else ifneq (,$(findstring gcc,$(CC))) + TOOLCHAIN = gcc +endif + +# Default to GCC +ifndef TOOLCHAIN + TOOLCHAIN = gcc +endif #-------------- TOP and CURRENT_PATH ------------ -# Set TOP to be the path to get from the current directory (where make was -# invoked) to the top of the tree. $(lastword $(MAKEFILE_LIST)) returns -# the name of this makefile relative to where make was invoked. +# Set TOP to be the path to get from the current directory (where make was invoked) to the top of the tree. +# $(lastword $(MAKEFILE_LIST)) returns the name of this makefile relative to where make was invoked. THIS_MAKEFILE := $(lastword $(MAKEFILE_LIST)) -# strip off /tools/top.mk to get for example ../../.. +# strip off /examples/build_system/make to get for example ../../.. # and Set TOP to an absolute path -TOP = $(abspath $(subst make.mk,..,$(THIS_MAKEFILE))) +TOP = $(abspath $(subst make.mk,../../..,$(THIS_MAKEFILE))) # Set CURRENT_PATH to the relative path from TOP to the current directory, ie examples/device/cdc_msc_freertos CURRENT_PATH = $(subst $(TOP)/,,$(abspath .)) +#-------------- Linux/Windows ------------ + # Detect whether shell style is windows or not # https://stackoverflow.com/questions/714100/os-detecting-makefile/52062069#52062069 ifeq '$(findstring ;,$(PATH))' ';' @@ -26,20 +42,21 @@ ifeq '$(findstring ;,$(PATH))' ';' CMDEXE := 1 # makefile shell commands should use syntax for DOS CMD, not unix sh -# Unfortunately, SHELL may point to sh or bash, which can't accept DOS syntax. -# We can't just use sh, because while sh and/or bash shell may be available, -# many Windows environments won't have utilities like realpath used below, so... # Force DOS command shell on Windows. SHELL := cmd.exe endif -# Handy check parameter function -check_defined = \ - $(strip $(foreach 1,$1, \ - $(call __check_defined,$1,$(strip $(value 2))))) -__check_defined = \ - $(if $(value $1),, \ - $(error Undefined make flag: $1$(if $2, ($2)))) +ifeq ($(CMDEXE),1) + CP = copy + RM = del + MKDIR = mkdir + PYTHON = python +else + CP = cp + RM = rm + MKDIR = mkdir + PYTHON = python3 +endif # Build directory @@ -52,8 +69,8 @@ BIN := $(TOP)/_bin/$(BOARD)/$(notdir $(CURDIR)) # Board without family ifneq ($(wildcard $(TOP)/hw/bsp/$(BOARD)/board.mk),) -BOARD_PATH := hw/bsp/$(BOARD) -FAMILY := + BOARD_PATH := hw/bsp/$(BOARD) + FAMILY := endif # Board within family @@ -73,45 +90,18 @@ ifeq ($(FAMILY),) else # Include Family and Board specific defs include $(TOP)/$(FAMILY_PATH)/family.mk - SRC_C += $(subst $(TOP)/,,$(wildcard $(TOP)/$(FAMILY_PATH)/*.c)) endif -#-------------- Cross Compiler ------------ - -# Can be set by board, default to ARM GCC -CROSS_COMPILE ?= arm-none-eabi- - -ifeq ($(TOOLCHAIN),iar) -CC := iccarm -endif - -ifeq ($(CC),iccarm) -USE_IAR = 1 -endif - -ifeq ($(CMDEXE),1) - CP = copy - RM = del - MKDIR = mkdir - PYTHON = python -else - CP = cp - RM = rm - MKDIR = mkdir - PYTHON = python3 -endif - #-------------- Source files and compiler flags -------------- # tinyusb makefile include $(TOP)/src/tinyusb.mk +SRC_C += $(TINYUSB_SRC_C) # Include all source C in family & board folder SRC_C += hw/bsp/board.c SRC_C += $(subst $(TOP)/,,$(wildcard $(TOP)/$(BOARD_PATH)/*.c)) -SRC_C += $(TINYUSB_SRC_C) - INC += \ $(TOP)/$(FAMILY_PATH) \ $(TOP)/src \ @@ -119,6 +109,13 @@ INC += \ BOARD_UPPER = $(subst a,A,$(subst b,B,$(subst c,C,$(subst d,D,$(subst e,E,$(subst f,F,$(subst g,G,$(subst h,H,$(subst i,I,$(subst j,J,$(subst k,K,$(subst l,L,$(subst m,M,$(subst n,N,$(subst o,O,$(subst p,P,$(subst q,Q,$(subst r,R,$(subst s,S,$(subst t,T,$(subst u,U,$(subst v,V,$(subst w,W,$(subst x,X,$(subst y,Y,$(subst z,Z,$(subst -,_,$(BOARD)))))))))))))))))))))))))))) CFLAGS += -DBOARD_$(BOARD_UPPER) +# use max3421 as host controller +ifeq (${MAX3421_HOST},1) + SRC_C += src/portable/analog/max3421/hcd_max3421.c + CFLAGS += -DCFG_TUH_MAX3421=1 + CMAKE_DEFSYM += -DMAX3421_HOST=1 +endif + # Log level is mapped to TUSB DEBUG option ifneq ($(LOG),) CMAKE_DEFSYM += -DLOG=$(LOG) @@ -127,7 +124,7 @@ endif # Logger: default is uart, can be set to rtt or swo ifneq ($(LOGGER),) - CMAKE_DEFSYM += -DLOGGER=$(LOGGER) + CMAKE_DEFSYM += -DLOGGER=$(LOGGER) endif ifeq ($(LOGGER),rtt) @@ -141,8 +138,16 @@ endif # CPU specific flags ifdef CPU_CORE -include $(TOP)/tools/make/cpu/$(CPU_CORE).mk + include ${TOP}/examples/build_system/make/cpu/$(CPU_CORE).mk endif # toolchain specific -include $(TOP)/tools/make/toolchain/arm_$(TOOLCHAIN).mk +include ${TOP}/examples/build_system/make/toolchain/arm_$(TOOLCHAIN).mk + +# Handy check parameter function +check_defined = \ + $(strip $(foreach 1,$1, \ + $(call __check_defined,$1,$(strip $(value 2))))) +__check_defined = \ + $(if $(value $1),, \ + $(error Undefined make flag: $1$(if $2, ($2)))) diff --git a/examples/rules.mk b/examples/build_system/make/rules.mk similarity index 97% rename from examples/rules.mk rename to examples/build_system/make/rules.mk index 44d6b84c8..7b6b339ed 100644 --- a/examples/rules.mk +++ b/examples/build_system/make/rules.mk @@ -9,19 +9,6 @@ # ESP32-Sx and RP2040 has its own CMake build system ifeq (,$(findstring $(FAMILY),espressif rp2040)) -# --------------------------------------- -# Compiler Flags -# --------------------------------------- - -CFLAGS += $(addprefix -I,$(INC)) - -# Verbose mode -ifeq ("$(V)","1") -$(info CFLAGS $(CFLAGS) ) $(info ) -$(info LDFLAGS $(LDFLAGS)) $(info ) -$(info ASFLAGS $(ASFLAGS)) $(info ) -endif - # --------------------------------------- # Rules # --------------------------------------- @@ -37,7 +24,20 @@ vpath %.c . $(TOP) vpath %.s . $(TOP) vpath %.S . $(TOP) -include $(TOP)/tools/make/toolchain/arm_$(TOOLCHAIN)_rules.mk +include ${TOP}/examples/build_system/make/toolchain/$(TOOLCHAIN)_rules.mk + +# --------------------------------------- +# Compiler Flags +# --------------------------------------- + +CFLAGS += $(addprefix -I,$(INC)) + +# Verbose mode +ifeq ("$(V)","1") +$(info CFLAGS $(CFLAGS) ) $(info ) +$(info LDFLAGS $(LDFLAGS)) $(info ) +$(info ASFLAGS $(ASFLAGS)) $(info ) +endif OBJ_DIRS = $(sort $(dir $(OBJ))) @@ -72,7 +72,7 @@ endif # get depenecies .PHONY: get-deps get-deps: - $(PYTHON) $(TOP)/tools/get_deps.py $(DEPS_SUBMODULES) + $(PYTHON) $(TOP)/tools/get_deps.py ${FAMILY} .PHONY: size size: $(BUILD)/$(PROJECT).elf diff --git a/examples/build_system/make/toolchain/arm_clang.mk b/examples/build_system/make/toolchain/arm_clang.mk new file mode 100644 index 000000000..97face39c --- /dev/null +++ b/examples/build_system/make/toolchain/arm_clang.mk @@ -0,0 +1,10 @@ +CC = clang +CXX = clang++ +AS = $(CC) -x assembler-with-cpp +LD = $(CC) + +GDB = $(CROSS_COMPILE)gdb +OBJCOPY = llvm-objcopy +SIZE = llvm-size + +include ${TOP}/examples/build_system/make/toolchain/gcc_common.mk diff --git a/examples/build_system/make/toolchain/arm_gcc.mk b/examples/build_system/make/toolchain/arm_gcc.mk new file mode 100644 index 000000000..a8576f8ee --- /dev/null +++ b/examples/build_system/make/toolchain/arm_gcc.mk @@ -0,0 +1,20 @@ +# makefile for arm gcc toolchain + +# Can be set by family, default to ARM GCC +CROSS_COMPILE ?= arm-none-eabi- + +CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ +AS = $(CC) -x assembler-with-cpp +LD = $(CC) + +GDB = $(CROSS_COMPILE)gdb +OBJCOPY = $(CROSS_COMPILE)objcopy +SIZE = $(CROSS_COMPILE)size + +CFLAGS += \ + -fsingle-precision-constant \ + +LIBS += -lgcc -lm -lnosys + +include ${TOP}/examples/build_system/make/toolchain/gcc_common.mk diff --git a/tools/make/toolchain/arm_iar.mk b/examples/build_system/make/toolchain/arm_iar.mk similarity index 94% rename from tools/make/toolchain/arm_iar.mk rename to examples/build_system/make/toolchain/arm_iar.mk index 04c9f22b3..17967b41a 100644 --- a/tools/make/toolchain/arm_iar.mk +++ b/examples/build_system/make/toolchain/arm_iar.mk @@ -1,4 +1,6 @@ # makefile for arm iar toolchain + +CC = iccarm AS = iasmarm LD = ilinkarm OBJCOPY = ielftool --silent diff --git a/examples/build_system/make/toolchain/clang_rules.mk b/examples/build_system/make/toolchain/clang_rules.mk new file mode 100644 index 000000000..341f705b1 --- /dev/null +++ b/examples/build_system/make/toolchain/clang_rules.mk @@ -0,0 +1 @@ +include ${TOP}/examples/build_system/make/toolchain/gcc_rules.mk diff --git a/tools/make/toolchain/arm_gcc.mk b/examples/build_system/make/toolchain/gcc_common.mk similarity index 72% rename from tools/make/toolchain/arm_gcc.mk rename to examples/build_system/make/toolchain/gcc_common.mk index bba0607df..6986d8bba 100644 --- a/tools/make/toolchain/arm_gcc.mk +++ b/examples/build_system/make/toolchain/gcc_common.mk @@ -1,14 +1,3 @@ -# makefile for arm gcc toolchain - -CC = $(CROSS_COMPILE)gcc -CXX = $(CROSS_COMPILE)g++ -AS = $(CC) -x assembler-with-cpp -LD = $(CC) - -GDB = $(CROSS_COMPILE)gdb -OBJCOPY = $(CROSS_COMPILE)objcopy -SIZE = $(CROSS_COMPILE)size - # --------------------------------------- # Compiler Flags # --------------------------------------- @@ -17,7 +6,6 @@ CFLAGS += \ -ggdb \ -fdata-sections \ -ffunction-sections \ - -fsingle-precision-constant \ -fno-strict-aliasing \ -Wall \ -Wextra \ @@ -62,10 +50,22 @@ endif # --------------------------------------- LDFLAGS += \ -Wl,-Map=$@.map \ - -Wl,-cref \ + -Wl,--cref \ -Wl,-gc-sections \ -# Some toolchain such as renesas rx does not support --print-memory-usage flags +# renesas rx does not support --print-memory-usage flags ifneq ($(FAMILY),rx) LDFLAGS += -Wl,--print-memory-usage endif + +ifeq ($(TOOLCHAIN),gcc) +CC_VERSION := $(shell $(CC) -dumpversion) +CC_VERSION_MAJOR = $(firstword $(subst ., ,$(CC_VERSION))) + +# from version 12 +ifeq ($(strip $(if $(CMDEXE),\ + $(shell if $(CC_VERSION_MAJOR) geq 12 (echo 1) else (echo 0)),\ + $(shell expr $(CC_VERSION_MAJOR) \>= 12))), 1) +LDFLAGS += -Wl,--no-warn-rwx-segment +endif +endif diff --git a/tools/make/toolchain/arm_gcc_rules.mk b/examples/build_system/make/toolchain/gcc_rules.mk similarity index 91% rename from tools/make/toolchain/arm_gcc_rules.mk rename to examples/build_system/make/toolchain/gcc_rules.mk index b76d4aec3..fc5225503 100644 --- a/tools/make/toolchain/arm_gcc_rules.mk +++ b/examples/build_system/make/toolchain/gcc_rules.mk @@ -21,8 +21,14 @@ ifneq ($(CFLAGS_SKIP),) CFLAGS := $(filter-out $(CFLAGS_SKIP),$(CFLAGS)) endif +ifeq ($(TOOLCHAIN),clang) +CFLAGS += $(CFLAGS_CLANG) +LDFLAGS += $(CFLAGS) $(LDFLAGS_CLANG) +else LDFLAGS += $(CFLAGS) $(LDFLAGS_GCC) +endif +# TODO should be removed after all examples are updated ifdef LD_FILE LDFLAGS += -Wl,-T,$(TOP)/$(LD_FILE) endif @@ -31,17 +37,9 @@ ifdef LD_FILE_GCC LDFLAGS += -Wl,-T,$(TOP)/$(LD_FILE_GCC) endif -ifneq ($(SKIP_NANOLIB), 1) -LDFLAGS += --specs=nosys.specs --specs=nano.specs -endif - ASFLAGS += $(CFLAGS) -LIBS_GCC ?= -lgcc -lm -lnosys - # libc -LIBS += $(LIBS_GCC) - ifneq ($(BOARD), spresense) LIBS += -lc endif diff --git a/tools/make/toolchain/arm_iar_rules.mk b/examples/build_system/make/toolchain/iar_rules.mk similarity index 100% rename from tools/make/toolchain/arm_iar_rules.mk rename to examples/build_system/make/toolchain/iar_rules.mk diff --git a/examples/build_system/make/toolchain/riscv_gcc.mk b/examples/build_system/make/toolchain/riscv_gcc.mk new file mode 100644 index 000000000..843aff38c --- /dev/null +++ b/examples/build_system/make/toolchain/riscv_gcc.mk @@ -0,0 +1,20 @@ +# makefile for arm gcc toolchain + +# Can be set by family, default to ARM GCC +CROSS_COMPILE ?= riscv-none-embed- + +CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ +AS = $(CC) -x assembler-with-cpp +LD = $(CC) + +GDB = $(CROSS_COMPILE)gdb +OBJCOPY = $(CROSS_COMPILE)objcopy +SIZE = $(CROSS_COMPILE)size + +CFLAGS += \ + -fsingle-precision-constant \ + +LIBS += -lgcc -lm -lnosys + +include ${TOP}/examples/build_system/make/toolchain/gcc_common.mk diff --git a/examples/device/CMakeLists.txt b/examples/device/CMakeLists.txt index f590fff3f..638440795 100644 --- a/examples/device/CMakeLists.txt +++ b/examples/device/CMakeLists.txt @@ -8,6 +8,8 @@ family_initialize_project(tinyusb_device_examples ${CMAKE_CURRENT_LIST_DIR}) # family_add_subdirectory will filter what to actually add based on selected FAMILY family_add_subdirectory(audio_4_channel_mic) family_add_subdirectory(audio_test) +family_add_subdirectory(audio_4_channel_mic_freertos) +family_add_subdirectory(audio_test_freertos) family_add_subdirectory(audio_test_multi_rate) family_add_subdirectory(board_test) family_add_subdirectory(cdc_dual_ports) @@ -17,6 +19,7 @@ family_add_subdirectory(cdc_uac2) family_add_subdirectory(dfu) family_add_subdirectory(dfu_runtime) family_add_subdirectory(dynamic_configuration) +family_add_subdirectory(hid_boot_interface) family_add_subdirectory(hid_composite) family_add_subdirectory(hid_composite_freertos) family_add_subdirectory(hid_generic_inout) @@ -27,4 +30,5 @@ family_add_subdirectory(net_lwip_webserver) family_add_subdirectory(uac2_headset) family_add_subdirectory(usbtmc) family_add_subdirectory(video_capture) +family_add_subdirectory(video_capture_2ch) family_add_subdirectory(webusb_serial) diff --git a/examples/device/audio_4_channel_mic/CMakeLists.txt b/examples/device/audio_4_channel_mic/CMakeLists.txt index f61e1b640..0f5d36193 100644 --- a/examples/device/audio_4_channel_mic/CMakeLists.txt +++ b/examples/device/audio_4_channel_mic/CMakeLists.txt @@ -28,6 +28,11 @@ target_include_directories(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) +# Add libm for GCC +if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_libraries(${PROJECT} PUBLIC m) +endif() + # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. family_configure_device_example(${PROJECT} noos) diff --git a/examples/device/audio_4_channel_mic/Makefile b/examples/device/audio_4_channel_mic/Makefile index 2a3d854fb..2c825bbf7 100644 --- a/examples/device/audio_4_channel_mic/Makefile +++ b/examples/device/audio_4_channel_mic/Makefile @@ -1,11 +1,14 @@ -include ../../make.mk +include ../../build_system/make/make.mk INC += \ src \ $(TOP)/hw \ # Example source -EXAMPLE_SOURCE += $(wildcard src/*.c) +EXAMPLE_SOURCE += \ + src/main.c \ + src/usb_descriptors.c \ + SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) -include ../../rules.mk +include ../../build_system/make/rules.mk diff --git a/examples/device/audio_4_channel_mic/skip.txt b/examples/device/audio_4_channel_mic/skip.txt index 1ee86a485..157605df1 100644 --- a/examples/device/audio_4_channel_mic/skip.txt +++ b/examples/device/audio_4_channel_mic/skip.txt @@ -1,3 +1,5 @@ mcu:SAMD11 mcu:SAME5X mcu:SAMG +family:broadcom_64bit +family:espressif diff --git a/examples/device/audio_4_channel_mic/src/main.c b/examples/device/audio_4_channel_mic/src/main.c index 94754fbda..10e6fe88a 100644 --- a/examples/device/audio_4_channel_mic/src/main.c +++ b/examples/device/audio_4_channel_mic/src/main.c @@ -34,17 +34,16 @@ #include #include #include +#include #include "bsp/board_api.h" #include "tusb.h" +#include "tusb_config.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ - -#ifndef AUDIO_SAMPLE_RATE -#define AUDIO_SAMPLE_RATE 48000 -#endif +#define AUDIO_SAMPLE_RATE CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE /* Blink pattern * - 250 ms : device not mounted @@ -70,8 +69,13 @@ uint8_t clkValid; audio_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX+1]; // Volume range state audio_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state -// Audio test data -uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ/2]; // Ensure half word aligned +#if CFG_TUD_AUDIO_ENABLE_ENCODING +// Audio test data, each buffer contains 2 channels, buffer[0] for CH0-1, buffer[1] for CH1-2 +uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX*CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE/1000/CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO]; +#else +// Audio test data, 4 channels muxed together, buffer[0] for CH0, buffer[1] for CH1, buffer[2] for CH2, buffer[3] for CH3 +uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX*CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE/1000]; +#endif void led_blinking_task(void); void audio_task(void); @@ -97,6 +101,45 @@ int main(void) sampleFreqRng.subrange[0].bMax = AUDIO_SAMPLE_RATE; sampleFreqRng.subrange[0].bRes = 0; + // Generate dummy data +#if CFG_TUD_AUDIO_ENABLE_ENCODING + uint16_t * p_buff = i2s_dummy_buffer[0]; + uint16_t dataVal = 0; + for (uint16_t cnt = 0; cnt < AUDIO_SAMPLE_RATE/1000; cnt++) + { + // CH0 saw wave + *p_buff++ = dataVal; + // CH1 inverted saw wave + *p_buff++ = 3200 + AUDIO_SAMPLE_RATE/1000 - dataVal; + dataVal+= 32; + } + p_buff = i2s_dummy_buffer[1]; + for (uint16_t cnt = 0; cnt < AUDIO_SAMPLE_RATE/1000; cnt++) + { + // CH3 square wave + *p_buff++ = cnt < (AUDIO_SAMPLE_RATE/1000/2) ? 3400:5000; + // CH4 sinus wave + float t = 2*3.1415f * cnt / (AUDIO_SAMPLE_RATE/1000); + *p_buff++ = (uint16_t)((int16_t)(sinf(t) * 750) + 6000); + } +#else + uint16_t * p_buff = i2s_dummy_buffer; + uint16_t dataVal = 0; + for (uint16_t cnt = 0; cnt < AUDIO_SAMPLE_RATE/1000; cnt++) + { + // CH0 saw wave + *p_buff++ = dataVal; + // CH1 inverted saw wave + *p_buff++ = 3200 + AUDIO_SAMPLE_RATE/1000 - dataVal; + dataVal+= 32; + // CH3 square wave + *p_buff++ = cnt < (AUDIO_SAMPLE_RATE/1000/2) ? 3400:5000; + // CH4 sinus wave + float t = 2*3.1415f * cnt / (AUDIO_SAMPLE_RATE/1000); + *p_buff++ = (uint16_t)((int16_t)(sinf(t) * 750) + 6000); + } +#endif + while (1) { tud_task(); // tinyusb device task @@ -133,7 +176,7 @@ void tud_suspend_cb(bool remote_wakeup_en) // Invoked when usb bus is resumed void tud_resume_cb(void) { - blink_interval_ms = BLINK_MOUNTED; + blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ @@ -142,8 +185,21 @@ void tud_resume_cb(void) void audio_task(void) { - // Yet to be filled - e.g. put meas data into TX FIFOs etc. - // asm("nop"); + // Yet to be filled - e.g. read audio from I2S buffer. + // Here we simulate a I2S receive callback every 1ms. + static uint32_t start_ms = 0; + uint32_t curr_ms = board_millis(); + if ( start_ms == curr_ms ) return; // not enough time + start_ms = curr_ms; +#if CFG_TUD_AUDIO_ENABLE_ENCODING + // Write I2S buffer into FIFO + for (uint8_t cnt=0; cnt < 2; cnt++) + { + tud_audio_write_support_ff(cnt, i2s_dummy_buffer[cnt], AUDIO_SAMPLE_RATE/1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX); + } +#else + tud_audio_write(i2s_dummy_buffer, AUDIO_SAMPLE_RATE/1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX); +#endif } //--------------------------------------------------------------------+ @@ -364,7 +420,8 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const * { case AUDIO_CS_REQ_CUR: TU_LOG2(" Get Sample Freq.\r\n"); - return tud_control_xfer(rhport, p_request, &sampFreq, sizeof(sampFreq)); + // Buffered control transfer is needed for IN flow control to work + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &sampFreq, sizeof(sampFreq)); case AUDIO_CS_REQ_RANGE: TU_LOG2(" Get Sample Freq. range\r\n"); @@ -400,10 +457,14 @@ bool tud_audio_tx_done_pre_load_cb(uint8_t rhport, uint8_t itf, uint8_t ep_in, u (void) ep_in; (void) cur_alt_setting; - for (uint8_t cnt=0; cnt < CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO; cnt++) - { - tud_audio_write_support_ff(cnt, i2s_dummy_buffer[cnt], AUDIO_SAMPLE_RATE/1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX); - } + + // In read world application data flow is driven by I2S clock, + // both tud_audio_tx_done_pre_load_cb() & tud_audio_tx_done_post_load_cb() are hardly used. + // For example in your I2S receive callback: + // void I2S_Rx_Callback(int channel, const void* data, uint16_t samples) + // { + // tud_audio_write_support_ff(channel, data, samples * N_BYTES_PER_SAMPLE * N_CHANNEL_PER_FIFO); + // } return true; } @@ -416,22 +477,6 @@ bool tud_audio_tx_done_post_load_cb(uint8_t rhport, uint16_t n_bytes_copied, uin (void) ep_in; (void) cur_alt_setting; - uint16_t dataVal; - - // Generate dummy data - for (uint16_t cnt = 0; cnt < CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO; cnt++) - { - uint16_t * p_buff = i2s_dummy_buffer[cnt]; // 2 bytes per sample - dataVal = 1; - for (uint16_t cnt2 = 0; cnt2 < AUDIO_SAMPLE_RATE/1000; cnt2++) - { - for (uint8_t cnt3 = 0; cnt3 < CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX; cnt3++) - { - *p_buff++ = dataVal; - } - dataVal++; - } - } return true; } diff --git a/examples/device/audio_4_channel_mic/src/plot_audio_samples.py b/examples/device/audio_4_channel_mic/src/plot_audio_samples.py index 8312b4e28..d17a908b6 100644 --- a/examples/device/audio_4_channel_mic/src/plot_audio_samples.py +++ b/examples/device/audio_4_channel_mic/src/plot_audio_samples.py @@ -10,11 +10,11 @@ if __name__ == '__main__': # print(sd.query_devices()) fs = 48000 # Sample rate - duration = 100e-3 # Duration of recording + duration = 1 # Duration of recording if platform.system() == 'Windows': # WDM-KS is needed since there are more than one MicNode device APIs (at least in Windows) - device = 'Microphone (MicNode_4_Ch), Windows WDM-KS' + device = 'Microphone (MicNode_4_Ch), Windows WASAPI' elif platform.system() == 'Darwin': device = 'MicNode_4_Ch' else: @@ -25,9 +25,13 @@ if __name__ == '__main__': sd.wait() # Wait until recording is finished print('Done!') + time = np.arange(0, duration, 1 / fs) # time vector + # strip starting zero + plt.plot(time, myrecording) plt.xlabel('Time [s]') plt.ylabel('Amplitude') plt.title('MicNode 4 Channel') + plt.legend(['CH-1', 'CH-2', 'CH-3','CH-4']) plt.show() diff --git a/examples/device/audio_4_channel_mic/src/tusb_config.h b/examples/device/audio_4_channel_mic/src/tusb_config.h index 5cf6d07c3..46484f847 100644 --- a/examples/device/audio_4_channel_mic/src/tusb_config.h +++ b/examples/device/audio_4_channel_mic/src/tusb_config.h @@ -103,6 +103,7 @@ extern "C" { //-------------------------------------------------------------------- // Have a look into audio_device.h for all configurations +#define CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE 48000 #define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_MIC_FOUR_CH_DESC_LEN @@ -112,15 +113,27 @@ extern "C" { #define CFG_TUD_AUDIO_ENABLE_EP_IN 1 #define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 4 // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup -#define CFG_TUD_AUDIO_EP_SZ_IN (48 + 1) * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX // 48 Samples (48 kHz) x 2 Bytes/Sample x CFG_TUD_AUDIO_N_CHANNELS_TX Channels - the Windows driver always needs an extra sample per channel of space more, otherwise it complains... found by trial and error +#define CFG_TUD_AUDIO_EP_SZ_IN TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) + +#define CFG_TUD_AUDIO_ENABLE_ENCODING 1 +#define CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL 1 + +#if CFG_TUD_AUDIO_ENABLE_ENCODING + #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ CFG_TUD_AUDIO_EP_SZ_IN -#define CFG_TUD_AUDIO_ENABLE_ENCODING 1 #define CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING 1 #define CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX 2 // One I2S stream contains two channels, each stream is saved within one support FIFO - this value is currently fixed, the driver does not support a changing value #define CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO (CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX / CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX) -#define CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ (CFG_TUD_AUDIO_EP_SZ_IN / CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO) +#define CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * (CFG_TUD_AUDIO_EP_SZ_IN / CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO) // Example write FIFO every 1ms, so it should be 8 times larger for HS device + +#else + +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_EP_SZ_IN // Example write FIFO every 1ms, so it should be 8 times larger for HS device + +#endif #ifdef __cplusplus } diff --git a/examples/device/audio_4_channel_mic_freertos/CMakeLists.txt b/examples/device/audio_4_channel_mic_freertos/CMakeLists.txt new file mode 100644 index 000000000..e8ca3751d --- /dev/null +++ b/examples/device/audio_4_channel_mic_freertos/CMakeLists.txt @@ -0,0 +1,39 @@ +cmake_minimum_required(VERSION 3.17) + +include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) + +# gets PROJECT name for the example (e.g. -) +family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR}) + +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}) + +# Espressif has its own cmake build system +if(FAMILY STREQUAL "espressif") + return() +endif() + +add_executable(${PROJECT}) + +# Example source +target_sources(${PROJECT} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src/freertos_hook.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c + ) + +# Example include +target_include_directories(${PROJECT} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src + ) + +# Add libm for GCC +if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_libraries(${PROJECT} PUBLIC m) +endif() + +# Configure compilation flags and libraries for the example with FreeRTOS. +# See the corresponding function in hw/bsp/FAMILY/family.cmake for details. +family_configure_device_example(${PROJECT} freertos) diff --git a/examples/device/audio_4_channel_mic_freertos/Makefile b/examples/device/audio_4_channel_mic_freertos/Makefile new file mode 100644 index 000000000..df2cdef4e --- /dev/null +++ b/examples/device/audio_4_channel_mic_freertos/Makefile @@ -0,0 +1,38 @@ +include ../../build_system/make/make.mk + +FREERTOS_SRC = lib/FreeRTOS-Kernel +FREERTOS_PORTABLE_PATH = $(FREERTOS_SRC)/portable/$(if $(findstring iar,$(TOOLCHAIN)),IAR,GCC) + +INC += \ + src \ + src/FreeRTOSConfig \ + $(TOP)/hw \ + $(TOP)/$(FREERTOS_SRC)/include \ + $(TOP)/$(FREERTOS_PORTABLE_SRC) \ + +# Example source +EXAMPLE_SOURCE = \ + src/freertos_hook.c \ + src/main.c \ + src/usb_descriptors.c + +SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) + +# FreeRTOS source, all files in port folder +SRC_C += \ + $(FREERTOS_SRC)/list.c \ + $(FREERTOS_SRC)/queue.c \ + $(FREERTOS_SRC)/tasks.c \ + $(FREERTOS_SRC)/timers.c \ + $(subst $(TOP)/,,$(wildcard $(TOP)/$(FREERTOS_PORTABLE_SRC)/*.c)) + +SRC_S += \ + $(subst $(TOP)/,,$(wildcard $(TOP)/$(FREERTOS_PORTABLE_SRC)/*.s)) + +# Suppress FreeRTOS warnings +CFLAGS += -Wno-error=cast-qual -Wno-error=redundant-decls + +# FreeRTOS (lto + Os) linker issue +LDFLAGS += -Wl,--undefined=vTaskSwitchContext + +include ../../build_system/make/rules.mk diff --git a/examples/device/audio_4_channel_mic_freertos/README.md b/examples/device/audio_4_channel_mic_freertos/README.md new file mode 100644 index 000000000..a99f28bc3 --- /dev/null +++ b/examples/device/audio_4_channel_mic_freertos/README.md @@ -0,0 +1,19 @@ +# How to build example for Esp32s3 +1. Load idf environment variables (eg. using the esp-idf alias `get_idf` if configured) + +2. cd into examples directory +``` +$ cd /tinyusb/examples/device/audio_4_channel_mic_freertos +``` + +3. Run cmake in project directory specifying the board +``` +$ cmake -DBOARD=espressif_s3_devkitc -B build -G Ninja . +$ ninja.exe -C build +``` + +4. Flash the binary onto the esp32-s3 by copy-paste of the full command output by the esp-idf build system replacing **(PORT)** with eg. /dev/ttyUSB0 + +eg. + +> /home/kaspernyhus/.espressif/python_env/idf4.4_py3.8_env/bin/python ../../../../esp-idf/components/esptool_py/esptool/esptool.py -p /dev/ttyUSB0 -b 460800 --before default_reset --after hard_reset --chip esp32s3 write_flash --flash_mode dio --flash_size detect --flash_freq 80m 0x0 _build/espressif_s3_devkitc/bootloader/bootloader.bin 0x8000 _build/espressif_s3_devkitc/partition_table/partition-table.bin 0x10000 _build/espressif_s3_devkitc/audio_4_channel_mic_freertos.bin diff --git a/examples/device/audio_4_channel_mic_freertos/sdkconfig.defaults b/examples/device/audio_4_channel_mic_freertos/sdkconfig.defaults new file mode 100644 index 000000000..eaa9fb902 --- /dev/null +++ b/examples/device/audio_4_channel_mic_freertos/sdkconfig.defaults @@ -0,0 +1,4 @@ +CONFIG_IDF_CMAKE=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y +CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y diff --git a/examples/device/audio_4_channel_mic_freertos/skip.txt b/examples/device/audio_4_channel_mic_freertos/skip.txt new file mode 100644 index 000000000..0b689192d --- /dev/null +++ b/examples/device/audio_4_channel_mic_freertos/skip.txt @@ -0,0 +1,16 @@ +mcu:CH32V307 +mcu:CXD56 +mcu:F1C100S +mcu:GD32VF103 +mcu:MKL25ZXX +mcu:MSP430x5xx +mcu:RP2040 +mcu:SAMD11 +mcu:SAMX7X +mcu:VALENTYUSB_EPTRI +mcu:RAXXX +mcu:STM32L0 +board:lpcxpresso11u37 +board:lpcxpresso1347 +family:broadcom_32bit +family:broadcom_64bit diff --git a/examples/device/audio_4_channel_mic_freertos/src/CMakeLists.txt b/examples/device/audio_4_channel_mic_freertos/src/CMakeLists.txt new file mode 100644 index 000000000..cef2b46ee --- /dev/null +++ b/examples/device/audio_4_channel_mic_freertos/src/CMakeLists.txt @@ -0,0 +1,4 @@ +# This file is for ESP-IDF only +idf_component_register(SRCS "main.c" "usb_descriptors.c" + INCLUDE_DIRS "." + REQUIRES boards tinyusb_src) diff --git a/examples/device/audio_4_channel_mic_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h b/examples/device/audio_4_channel_mic_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..6cc7a6577 --- /dev/null +++ b/examples/device/audio_4_channel_mic_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,190 @@ +/* + * 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 MCU header +#include "bsp/board_mcu.h" + +#if CFG_TUSB_MCU == OPT_MCU_ESP32S2 || CFG_TUSB_MCU == OPT_MCU_ESP32S3 + #error "ESP32-Sx should use IDF's FreeRTOSConfig.h" +#endif + +// TODO fix later +#if CFG_TUSB_MCU == OPT_MCU_MM32F327X + extern u32 SystemCoreClock; +#else + // FIXME cause redundant-decls warnings + extern uint32_t SystemCoreClock; +#endif + +#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 4 +#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 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* 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 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#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 0 +#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 + +#ifdef __RX__ +/* Renesas RX series */ +#define vSoftwareInterruptISR INT_Excep_ICU_SWINT +#define vTickISR INT_Excep_CMT0_CMI0 +#define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2) +#define configKERNEL_INTERRUPT_PRIORITY 1 +#define configMAX_SYSCALL_INTERRUPT_PRIORITY 4 + +#else + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ +#if defined(__NVIC_PRIO_BITS) + // For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h + #define configPRIO_BITS __NVIC_PRIO_BITS + +#elif defined(__ECLIC_INTCTLBITS) + // RISC-V Bumblebee core from nuclei + #define configPRIO_BITS __ECLIC_INTCTLBITS + +#elif defined(__IASMARM__) + // FIXME: IAR Assembler cannot include mcu header directly to get __NVIC_PRIO_BITS. + // Therefore we will hard coded it to minimum value of 2 to get pass ci build. + // IAR user must update this to correct value of the target MCU + #message "configPRIO_BITS is hard coded to 2 to pass IAR build only. User should update it per MCU" + #define configPRIO_BITS 2 + +#else + #error "FreeRTOS configPRIO_BITS to be defined" +#endif + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< +#include +#include +#include + +#include "bsp/board_api.h" +#include "tusb.h" + +#if TUP_MCU_ESPRESSIF + // ESP-IDF need "freertos/" prefix in include path. + // CFG_TUSB_OS_INC_PATH should be defined accordingly. + #include "freertos/FreeRTOS.h" + #include "freertos/semphr.h" + #include "freertos/queue.h" + #include "freertos/task.h" + #include "freertos/timers.h" + + #define USBD_STACK_SIZE 4096 +#else + + #include "FreeRTOS.h" + #include "semphr.h" + #include "queue.h" + #include "task.h" + #include "timers.h" + + // Increase stack size when debug log is enabled + #define USBD_STACK_SIZE (4*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) +#endif + +#define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE +#define AUDIO_STACK_SIZE configMINIMAL_STACK_SIZE + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF PROTYPES +//--------------------------------------------------------------------+ +#define AUDIO_SAMPLE_RATE CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE + +/* Blink pattern + * - 250 ms : device not mounted + * - 1000 ms : device mounted + * - 2500 ms : device is suspended + */ +enum { + BLINK_NOT_MOUNTED = 250, + BLINK_MOUNTED = 1000, + BLINK_SUSPENDED = 2500, +}; + +// static task +#if configSUPPORT_STATIC_ALLOCATION +StackType_t blinky_stack[BLINKY_STACK_SIZE]; +StaticTask_t blinky_taskdef; + +StackType_t usb_device_stack[USBD_STACK_SIZE]; +StaticTask_t usb_device_taskdef; + +StackType_t audio_stack[AUDIO_STACK_SIZE]; +StaticTask_t audio_taskdef; +#endif + +static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; + +// Audio controls +// Current states +bool mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0 +uint16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0 +uint32_t sampFreq; +uint8_t clkValid; + +// Range states +audio_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX+1]; // Volume range state +audio_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state + +#if CFG_TUD_AUDIO_ENABLE_ENCODING +// Audio test data, each buffer contains 2 channels, buffer[0] for CH0-1, buffer[1] for CH1-2 +uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX*CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE/1000/CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO]; +#else +// Audio test data, 4 channels muxed together, buffer[0] for CH0, buffer[1] for CH1, buffer[2] for CH2, buffer[3] for CH3 +uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX*CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE/1000]; +#endif + +void led_blinking_task(void* param); +void usb_device_task(void* param); +void audio_task(void* param); + +/*------------- MAIN -------------*/ +int main(void) +{ + board_init(); + + // Init values + sampFreq = AUDIO_SAMPLE_RATE; + clkValid = 1; + + sampleFreqRng.wNumSubRanges = 1; + sampleFreqRng.subrange[0].bMin = AUDIO_SAMPLE_RATE; + sampleFreqRng.subrange[0].bMax = AUDIO_SAMPLE_RATE; + sampleFreqRng.subrange[0].bRes = 0; + + // Generate dummy data +#if CFG_TUD_AUDIO_ENABLE_ENCODING + uint16_t * p_buff = i2s_dummy_buffer[0]; + uint16_t dataVal = 0; + for (uint16_t cnt = 0; cnt < AUDIO_SAMPLE_RATE/1000; cnt++) + { + // CH0 saw wave + *p_buff++ = dataVal; + // CH1 inverted saw wave + *p_buff++ = 3200 + AUDIO_SAMPLE_RATE/1000 - dataVal; + dataVal+= 32; + } + p_buff = i2s_dummy_buffer[1]; + for (uint16_t cnt = 0; cnt < AUDIO_SAMPLE_RATE/1000; cnt++) + { + // CH3 square wave + *p_buff++ = cnt < (AUDIO_SAMPLE_RATE/1000/2) ? 3400:5000; + // CH4 sinus wave + float t = 2*3.1415f * cnt / (AUDIO_SAMPLE_RATE/1000); + *p_buff++ = (uint16_t)((int16_t)(sinf(t) * 750) + 6000); + } +#else + uint16_t * p_buff = i2s_dummy_buffer; + uint16_t dataVal = 0; + for (uint16_t cnt = 0; cnt < AUDIO_SAMPLE_RATE/1000; cnt++) + { + // CH0 saw wave + *p_buff++ = dataVal; + // CH1 inverted saw wave + *p_buff++ = 3200 + AUDIO_SAMPLE_RATE/1000 - dataVal; + dataVal+= 32; + // CH3 square wave + *p_buff++ = cnt < (AUDIO_SAMPLE_RATE/1000/2) ? 3400:5000; + // CH4 sinus wave + float t = 2*3.1415f * cnt / (AUDIO_SAMPLE_RATE/1000); + *p_buff++ = (uint16_t)((int16_t)(sinf(t) * 750) + 6000); + } +#endif + +#if configSUPPORT_STATIC_ALLOCATION + // blinky task + xTaskCreateStatic(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, blinky_stack, &blinky_taskdef); + + // Create a task for tinyusb device stack + xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef); + + // Create a task for audio + xTaskCreateStatic(audio_task, "audio", AUDIO_STACK_SIZE, NULL, configMAX_PRIORITIES-1, audio_stack, &audio_taskdef); +#else + xTaskCreate(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, NULL); + xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL); + xTaskCreate(audio_task, "audio", AUDIO_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL); +#endif + + // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 + #if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) + vTaskStartScheduler(); + #endif + + return 0; +} + +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +void app_main(void) +{ + main(); +} +#endif + +// USB Device Driver task +// This top level thread process all usb events and invoke callbacks +void usb_device_task(void* param) +{ + (void) param; + + // init device stack on configured roothub port + // This should be called after scheduler/kernel is started. + // Otherwise it could cause kernel issue since USB IRQ handler does use RTOS queue API. + tud_init(BOARD_TUD_RHPORT); + + if (board_init_after_tusb) { + board_init_after_tusb(); + } + + // RTOS forever loop + while (1) + { + // tinyusb device task + tud_task(); + } +} + +//--------------------------------------------------------------------+ +// Device callbacks +//--------------------------------------------------------------------+ + +// Invoked when device is mounted +void tud_mount_cb(void) +{ + blink_interval_ms = BLINK_MOUNTED; +} + +// Invoked when device is unmounted +void tud_umount_cb(void) +{ + blink_interval_ms = BLINK_NOT_MOUNTED; +} + +// Invoked when usb bus is suspended +// remote_wakeup_en : if host allow us to perform remote wakeup +// Within 7ms, device must draw an average of current less than 2.5 mA from bus +void tud_suspend_cb(bool remote_wakeup_en) +{ + (void) remote_wakeup_en; + blink_interval_ms = BLINK_SUSPENDED; +} + +// Invoked when usb bus is resumed +void tud_resume_cb(void) +{ + blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; +} + +//--------------------------------------------------------------------+ +// AUDIO Task +//--------------------------------------------------------------------+ + +void audio_task(void* param) +{ + (void) param; + // Yet to be filled - e.g. read audio from I2S buffer. + // Here we simulate a I2S receive callback every 1ms. + while (1) { + vTaskDelay(1); +#if CFG_TUD_AUDIO_ENABLE_ENCODING + // Write I2S buffer into FIFO + for (uint8_t cnt=0; cnt < 2; cnt++) + { + tud_audio_write_support_ff(cnt, i2s_dummy_buffer[cnt], AUDIO_SAMPLE_RATE/1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX); + } +#else + tud_audio_write(i2s_dummy_buffer, AUDIO_SAMPLE_RATE/1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX); +#endif + } +} + +//--------------------------------------------------------------------+ +// Application Callback API Implementations +//--------------------------------------------------------------------+ + +// Invoked when audio class specific set request received for an EP +bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff) +{ + (void) rhport; + (void) pBuff; + + // We do not support any set range requests here, only current value requests + TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR); + + // Page 91 in UAC2 specification + uint8_t channelNum = TU_U16_LOW(p_request->wValue); + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + uint8_t ep = TU_U16_LOW(p_request->wIndex); + + (void) channelNum; (void) ctrlSel; (void) ep; + + return false; // Yet not implemented +} + +// Invoked when audio class specific set request received for an interface +bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff) +{ + (void) rhport; + (void) pBuff; + + // We do not support any set range requests here, only current value requests + TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR); + + // Page 91 in UAC2 specification + uint8_t channelNum = TU_U16_LOW(p_request->wValue); + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + uint8_t itf = TU_U16_LOW(p_request->wIndex); + + (void) channelNum; (void) ctrlSel; (void) itf; + + return false; // Yet not implemented +} + +// Invoked when audio class specific set request received for an entity +bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff) +{ + (void) rhport; + + // Page 91 in UAC2 specification + uint8_t channelNum = TU_U16_LOW(p_request->wValue); + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + uint8_t itf = TU_U16_LOW(p_request->wIndex); + uint8_t entityID = TU_U16_HIGH(p_request->wIndex); + + (void) itf; + + // We do not support any set range requests here, only current value requests + TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR); + + // If request is for our feature unit + if ( entityID == 2 ) + { + switch ( ctrlSel ) + { + case AUDIO_FU_CTRL_MUTE: + // Request uses format layout 1 + TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_1_t)); + + mute[channelNum] = ((audio_control_cur_1_t*) pBuff)->bCur; + + TU_LOG2(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum); + return true; + + case AUDIO_FU_CTRL_VOLUME: + // Request uses format layout 2 + TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_2_t)); + + volume[channelNum] = ((audio_control_cur_2_t*) pBuff)->bCur; + + TU_LOG2(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum); + return true; + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + } + return false; // Yet not implemented +} + +// Invoked when audio class specific get request received for an EP +bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request) +{ + (void) rhport; + + // Page 91 in UAC2 specification + uint8_t channelNum = TU_U16_LOW(p_request->wValue); + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + uint8_t ep = TU_U16_LOW(p_request->wIndex); + + (void) channelNum; (void) ctrlSel; (void) ep; + + return false; // Yet not implemented +} + +// Invoked when audio class specific get request received for an interface +bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request) +{ + (void) rhport; + + // Page 91 in UAC2 specification + uint8_t channelNum = TU_U16_LOW(p_request->wValue); + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + uint8_t itf = TU_U16_LOW(p_request->wIndex); + + (void) channelNum; (void) ctrlSel; (void) itf; + + return false; // Yet not implemented +} + +// Invoked when audio class specific get request received for an entity +bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request) +{ + (void) rhport; + + // Page 91 in UAC2 specification + uint8_t channelNum = TU_U16_LOW(p_request->wValue); + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + // uint8_t itf = TU_U16_LOW(p_request->wIndex); // Since we have only one audio function implemented, we do not need the itf value + uint8_t entityID = TU_U16_HIGH(p_request->wIndex); + + // Input terminal (Microphone input) + if (entityID == 1) + { + switch ( ctrlSel ) + { + case AUDIO_TE_CTRL_CONNECTOR: + { + // The terminal connector control only has a get request with only the CUR attribute. + audio_desc_channel_cluster_t ret; + + // Those are dummy values for now + ret.bNrChannels = 1; + ret.bmChannelConfig = 0; + ret.iChannelNames = 0; + + TU_LOG2(" Get terminal connector\r\n"); + + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void*) &ret, sizeof(ret)); + } + break; + + // Unknown/Unsupported control selector + default: + TU_BREAKPOINT(); + return false; + } + } + + // Feature unit + if (entityID == 2) + { + switch ( ctrlSel ) + { + case AUDIO_FU_CTRL_MUTE: + // Audio control mute cur parameter block consists of only one byte - we thus can send it right away + // There does not exist a range parameter block for mute + TU_LOG2(" Get Mute of channel: %u\r\n", channelNum); + return tud_control_xfer(rhport, p_request, &mute[channelNum], 1); + + case AUDIO_FU_CTRL_VOLUME: + switch ( p_request->bRequest ) + { + case AUDIO_CS_REQ_CUR: + TU_LOG2(" Get Volume of channel: %u\r\n", channelNum); + return tud_control_xfer(rhport, p_request, &volume[channelNum], sizeof(volume[channelNum])); + + case AUDIO_CS_REQ_RANGE: + TU_LOG2(" Get Volume range of channel: %u\r\n", channelNum); + + // Copy values - only for testing - better is version below + audio_control_range_2_n_t(1) + ret; + + ret.wNumSubRanges = 1; + ret.subrange[0].bMin = -90; // -90 dB + ret.subrange[0].bMax = 90; // +90 dB + ret.subrange[0].bRes = 1; // 1 dB steps + + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void*) &ret, sizeof(ret)); + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + break; + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + } + + // Clock Source unit + if ( entityID == 4 ) + { + switch ( ctrlSel ) + { + case AUDIO_CS_CTRL_SAM_FREQ: + // channelNum is always zero in this case + switch ( p_request->bRequest ) + { + case AUDIO_CS_REQ_CUR: + TU_LOG2(" Get Sample Freq.\r\n"); + // Buffered control transfer is needed for IN flow control to work + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &sampFreq, sizeof(sampFreq)); + + case AUDIO_CS_REQ_RANGE: + TU_LOG2(" Get Sample Freq. range\r\n"); + return tud_control_xfer(rhport, p_request, &sampleFreqRng, sizeof(sampleFreqRng)); + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + break; + + case AUDIO_CS_CTRL_CLK_VALID: + // Only cur attribute exists for this request + TU_LOG2(" Get Sample Freq. valid\r\n"); + return tud_control_xfer(rhport, p_request, &clkValid, sizeof(clkValid)); + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + } + + TU_LOG2(" Unsupported entity: %d\r\n", entityID); + return false; // Yet not implemented +} + +bool tud_audio_tx_done_pre_load_cb(uint8_t rhport, uint8_t itf, uint8_t ep_in, uint8_t cur_alt_setting) +{ + (void) rhport; + (void) itf; + (void) ep_in; + (void) cur_alt_setting; + + + // In read world application data flow is driven by I2S clock, + // both tud_audio_tx_done_pre_load_cb() & tud_audio_tx_done_post_load_cb() are hardly used. + // For example in your I2S receive callback: + // void I2S_Rx_Callback(int channel, const void* data, uint16_t samples) + // { + // tud_audio_write_support_ff(channel, data, samples * N_BYTES_PER_SAMPLE * N_CHANNEL_PER_FIFO); + // } + + return true; +} + +bool tud_audio_tx_done_post_load_cb(uint8_t rhport, uint16_t n_bytes_copied, uint8_t itf, uint8_t ep_in, uint8_t cur_alt_setting) +{ + (void) rhport; + (void) n_bytes_copied; + (void) itf; + (void) ep_in; + (void) cur_alt_setting; + + return true; +} + +bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const * p_request) +{ + (void) rhport; + (void) p_request; + + return true; +} + +///--------------------------------------------------------------------+ +// BLINKING TASK +//--------------------------------------------------------------------+ +void led_blinking_task(void* param) { + (void) param; + static uint32_t start_ms = 0; + static bool led_state = false; + + while (1) { + // Blink every interval ms + vTaskDelay(blink_interval_ms / portTICK_PERIOD_MS); + start_ms += blink_interval_ms; + + board_led_write(led_state); + led_state = 1 - led_state; // toggle + } +} diff --git a/examples/device/audio_4_channel_mic_freertos/src/plot_audio_samples.py b/examples/device/audio_4_channel_mic_freertos/src/plot_audio_samples.py new file mode 100644 index 000000000..8312b4e28 --- /dev/null +++ b/examples/device/audio_4_channel_mic_freertos/src/plot_audio_samples.py @@ -0,0 +1,33 @@ +import sounddevice as sd +import matplotlib.pyplot as plt +import numpy as np +import platform + +if __name__ == '__main__': + + # If you got "ValueError: No input device matching", that is because your PC name example device + # differently from tested list below. Uncomment the next line to see full list and try to pick correct one + # print(sd.query_devices()) + + fs = 48000 # Sample rate + duration = 100e-3 # Duration of recording + + if platform.system() == 'Windows': + # WDM-KS is needed since there are more than one MicNode device APIs (at least in Windows) + device = 'Microphone (MicNode_4_Ch), Windows WDM-KS' + elif platform.system() == 'Darwin': + device = 'MicNode_4_Ch' + else: + device ='default' + + myrecording = sd.rec(int(duration * fs), samplerate=fs, channels=4, dtype='int16', device=device) + print('Waiting...') + sd.wait() # Wait until recording is finished + print('Done!') + + time = np.arange(0, duration, 1 / fs) # time vector + plt.plot(time, myrecording) + plt.xlabel('Time [s]') + plt.ylabel('Amplitude') + plt.title('MicNode 4 Channel') + plt.show() diff --git a/examples/device/audio_4_channel_mic_freertos/src/tusb_config.h b/examples/device/audio_4_channel_mic_freertos/src/tusb_config.h new file mode 100644 index 000000000..88f20278b --- /dev/null +++ b/examples/device/audio_4_channel_mic_freertos/src/tusb_config.h @@ -0,0 +1,148 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 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. + * + */ + +#ifndef _TUSB_CONFIG_H_ +#define _TUSB_CONFIG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Board Specific Configuration +//--------------------------------------------------------------------+ + +// RHPort number used for device can be defined by board.mk, default to port 0 +#ifndef BOARD_TUD_RHPORT +#define BOARD_TUD_RHPORT 0 +#endif + +// RHPort max operational speed can defined by board.mk +#ifndef BOARD_TUD_MAX_SPEED +#define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED +#endif + +//-------------------------------------------------------------------- +// COMMON CONFIGURATION +//-------------------------------------------------------------------- + +// defined by compiler flags for flexibility +#ifndef CFG_TUSB_MCU +#error CFG_TUSB_MCU must be defined +#endif + +// This examples use FreeRTOS +#ifndef CFG_TUSB_OS +#define CFG_TUSB_OS OPT_OS_FREERTOS +#endif + +// Espressif IDF requires "freertos/" prefix in include path +#if TUP_MCU_ESPRESSIF +#define CFG_TUSB_OS_INC_PATH freertos/ +#endif + +#ifndef CFG_TUSB_DEBUG +#define CFG_TUSB_DEBUG 0 +#endif + +// Enable Device stack +#define CFG_TUD_ENABLED 1 + +// Default is max speed that hardware controller could support with on-chip PHY +#define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED + +/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. + * Tinyusb use follows macros to declare transferring memory so that they can be put + * into those specific section. + * e.g + * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) + * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) + */ +#ifndef CFG_TUSB_MEM_SECTION +#define CFG_TUSB_MEM_SECTION +#endif + +#ifndef CFG_TUSB_MEM_ALIGN +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#endif + +//-------------------------------------------------------------------- +// DEVICE CONFIGURATION +//-------------------------------------------------------------------- + +#ifndef CFG_TUD_ENDPOINT0_SIZE +#define CFG_TUD_ENDPOINT0_SIZE 64 +#endif + +//------------- CLASS -------------// +#define CFG_TUD_AUDIO 1 +#define CFG_TUD_CDC 0 +#define CFG_TUD_MSC 0 +#define CFG_TUD_HID 0 +#define CFG_TUD_MIDI 0 +#define CFG_TUD_VENDOR 0 + +//-------------------------------------------------------------------- +// AUDIO CLASS DRIVER CONFIGURATION +//-------------------------------------------------------------------- + +// Have a look into audio_device.h for all configurations +#define CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE 48000 + +#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_MIC_FOUR_CH_DESC_LEN + +#define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 1 +#define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64 + +#define CFG_TUD_AUDIO_ENABLE_EP_IN 1 +#define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup +#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 4 // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup +#define CFG_TUD_AUDIO_EP_SZ_IN TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) + +#define CFG_TUD_AUDIO_ENABLE_ENCODING 1 +#define CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL 1 + +#if CFG_TUD_AUDIO_ENABLE_ENCODING + +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ CFG_TUD_AUDIO_EP_SZ_IN + +#define CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING 1 +#define CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX 2 // One I2S stream contains two channels, each stream is saved within one support FIFO - this value is currently fixed, the driver does not support a changing value +#define CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO (CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX / CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX) +#define CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * (CFG_TUD_AUDIO_EP_SZ_IN / CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO) // Example write FIFO every 1ms, so it should be 8 times larger for HS device + +#else + +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_EP_SZ_IN // Example write FIFO every 1ms, so it should be 8 times larger for HS device + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _TUSB_CONFIG_H_ */ diff --git a/examples/device/audio_4_channel_mic_freertos/src/usb_descriptors.c b/examples/device/audio_4_channel_mic_freertos/src/usb_descriptors.c new file mode 100644 index 000000000..728a5f9ce --- /dev/null +++ b/examples/device/audio_4_channel_mic_freertos/src/usb_descriptors.c @@ -0,0 +1,179 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 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. + * + */ + +#include "bsp/board_api.h" +#include "tusb.h" + +/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. + * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. + * + * Auto ProductID layout's Bitmap: + * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] + */ +#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) +#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ + _PID_MAP(MIDI, 3) | _PID_MAP(AUDIO, 4) | _PID_MAP(VENDOR, 5) ) + +//--------------------------------------------------------------------+ +// Device Descriptors +//--------------------------------------------------------------------+ +tusb_desc_device_t const desc_device = +{ + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = 0x0200, + + // Use Interface Association Descriptor (IAD) for Audio + // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) + .bDeviceClass = TUSB_CLASS_MISC, + .bDeviceSubClass = MISC_SUBCLASS_COMMON, + .bDeviceProtocol = MISC_PROTOCOL_IAD, + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + + .idVendor = 0xCafe, + .idProduct = USB_PID, + .bcdDevice = 0x0100, + + .iManufacturer = 0x01, + .iProduct = 0x02, + .iSerialNumber = 0x03, + + .bNumConfigurations = 0x01 +}; + +// Invoked when received GET DEVICE DESCRIPTOR +// Application return pointer to descriptor +uint8_t const * tud_descriptor_device_cb(void) +{ + return (uint8_t const *) &desc_device; +} + +//--------------------------------------------------------------------+ +// Configuration Descriptor +//--------------------------------------------------------------------+ +enum +{ + ITF_NUM_AUDIO_CONTROL = 0, + ITF_NUM_AUDIO_STREAMING, + ITF_NUM_TOTAL +}; + +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_AUDIO * TUD_AUDIO_MIC_FOUR_CH_DESC_LEN) + +#if TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX) + // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number + // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... + #define EPNUM_AUDIO 0x03 + +#elif TU_CHECK_MCU(OPT_MCU_NRF5X) + // nRF5x ISO can only be endpoint 8 + #define EPNUM_AUDIO 0x08 + +#else + #define EPNUM_AUDIO 0x01 +#endif + +uint8_t const desc_configuration[] = +{ + // Config number, interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), + + // Interface number, string index, EP Out & EP In address, EP size + TUD_AUDIO_MIC_FOUR_CH_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_nBytesPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, /*_nBitsUsedPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX*8, /*_epin*/ 0x80 | EPNUM_AUDIO, /*_epsize*/ CFG_TUD_AUDIO_EP_SZ_IN) +}; + +// Invoked when received GET CONFIGURATION DESCRIPTOR +// Application return pointer to descriptor +// Descriptor contents must exist long enough for transfer to complete +uint8_t const * tud_descriptor_configuration_cb(uint8_t index) +{ + (void) index; // for multiple configurations + return desc_configuration; +} + +//--------------------------------------------------------------------+ +// String Descriptors +//--------------------------------------------------------------------+ + +// String Descriptor Index +enum { + STRID_LANGID = 0, + STRID_MANUFACTURER, + STRID_PRODUCT, + STRID_SERIAL, +}; + +// array of pointer to string descriptors +char const* string_desc_arr [] = { + (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) + "PaniRCorp", // 1: Manufacturer + "MicNode_4_Ch", // 2: Product + NULL, // 3: Serials will use unique ID if possible + "UAC2", // 4: Audio Interface +}; + +static uint16_t _desc_str[32 + 1]; + +// Invoked when received GET STRING DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete +uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { + (void) langid; + size_t chr_count; + + switch ( index ) { + case STRID_LANGID: + memcpy(&_desc_str[1], string_desc_arr[0], 2); + chr_count = 1; + break; + + case STRID_SERIAL: + chr_count = board_usb_get_serial(_desc_str + 1, 32); + break; + + default: + // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. + // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors + + if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; + + const char *str = string_desc_arr[index]; + + // Cap at max char + chr_count = strlen(str); + size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type + if ( chr_count > max_count ) chr_count = max_count; + + // Convert ASCII string into UTF-16 + for ( size_t i = 0; i < chr_count; i++ ) { + _desc_str[1 + i] = str[i]; + } + break; + } + + // first byte is length (including header), second byte is string type + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); + + return _desc_str; +} diff --git a/examples/device/audio_test/Makefile b/examples/device/audio_test/Makefile index 2a3d854fb..7fa475da5 100644 --- a/examples/device/audio_test/Makefile +++ b/examples/device/audio_test/Makefile @@ -1,4 +1,4 @@ -include ../../make.mk +include ../../build_system/make/make.mk INC += \ src \ @@ -8,4 +8,4 @@ INC += \ EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) -include ../../rules.mk +include ../../build_system/make/rules.mk diff --git a/examples/device/audio_test/skip.txt b/examples/device/audio_test/skip.txt index 1ee86a485..65b137814 100644 --- a/examples/device/audio_test/skip.txt +++ b/examples/device/audio_test/skip.txt @@ -1,3 +1,4 @@ mcu:SAMD11 mcu:SAME5X mcu:SAMG +family:espressif diff --git a/examples/device/audio_test/src/main.c b/examples/device/audio_test/src/main.c index c28928b3f..f79bb4468 100644 --- a/examples/device/audio_test/src/main.c +++ b/examples/device/audio_test/src/main.c @@ -42,10 +42,6 @@ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ -#ifndef AUDIO_SAMPLE_RATE -#define AUDIO_SAMPLE_RATE 48000 -#endif - /* Blink pattern * - 250 ms : device not mounted * - 1000 ms : device mounted @@ -90,12 +86,12 @@ int main(void) } // Init values - sampFreq = AUDIO_SAMPLE_RATE; + sampFreq = CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE; clkValid = 1; sampleFreqRng.wNumSubRanges = 1; - sampleFreqRng.subrange[0].bMin = AUDIO_SAMPLE_RATE; - sampleFreqRng.subrange[0].bMax = AUDIO_SAMPLE_RATE; + sampleFreqRng.subrange[0].bMin = CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE; + sampleFreqRng.subrange[0].bMax = CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE; sampleFreqRng.subrange[0].bRes = 0; while (1) @@ -134,7 +130,7 @@ void tud_suspend_cb(bool remote_wakeup_en) // Invoked when usb bus is resumed void tud_resume_cb(void) { - blink_interval_ms = BLINK_MOUNTED; + blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ diff --git a/examples/device/audio_test/src/tusb_config.h b/examples/device/audio_test/src/tusb_config.h index 9f38612a9..8c021e23c 100644 --- a/examples/device/audio_test/src/tusb_config.h +++ b/examples/device/audio_test/src/tusb_config.h @@ -106,6 +106,7 @@ extern "C" { //-------------------------------------------------------------------- // Have a look into audio_device.h for all configurations +#define CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE 48000 #define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_MIC_ONE_CH_DESC_LEN #define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 1 // Number of Standard AS Interface Descriptors (4.9.1) defined per audio function - this is required to be able to remember the current alternate settings of these interfaces - We restrict us here to have a constant number for all audio functions (which means this has to be the maximum number of AS interfaces an audio function has and a second audio function with less AS interfaces just wastes a few bytes) @@ -114,9 +115,9 @@ extern "C" { #define CFG_TUD_AUDIO_ENABLE_EP_IN 1 #define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 1 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below - be aware: for different number of channels you need another descriptor! -#define CFG_TUD_AUDIO_EP_SZ_IN (48 + 1) * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX // 48 Samples (48 kHz) x 2 Bytes/Sample x CFG_TUD_AUDIO_N_CHANNELS_TX Channels - One extra sample is needed for asynchronous transfer adjustment, see feedback EP -#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN // Maximum EP IN size for all AS alternate settings used -#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ CFG_TUD_AUDIO_EP_SZ_IN + 1 +#define CFG_TUD_AUDIO_EP_SZ_IN TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 8 : 1) * CFG_TUD_AUDIO_EP_SZ_IN // Example write FIFO every 1ms, so it should be 8 times larger for HS device #ifdef __cplusplus } diff --git a/examples/device/audio_test_freertos/CMakeLists.txt b/examples/device/audio_test_freertos/CMakeLists.txt new file mode 100644 index 000000000..eb22014fb --- /dev/null +++ b/examples/device/audio_test_freertos/CMakeLists.txt @@ -0,0 +1,34 @@ +cmake_minimum_required(VERSION 3.17) + +include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) + +# gets PROJECT name for the example (e.g. -) +family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR}) + +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}) + +# Espressif has its own cmake build system +if(FAMILY STREQUAL "espressif") + return() +endif() + +add_executable(${PROJECT}) + +# Example source +target_sources(${PROJECT} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src/freertos_hook.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c + ) + +# Example include +target_include_directories(${PROJECT} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src + ) + +# Configure compilation flags and libraries for the example with FreeRTOS. +# See the corresponding function in hw/bsp/FAMILY/family.cmake for details. +family_configure_device_example(${PROJECT} freertos) diff --git a/examples/device/audio_test_freertos/Makefile b/examples/device/audio_test_freertos/Makefile new file mode 100644 index 000000000..df2cdef4e --- /dev/null +++ b/examples/device/audio_test_freertos/Makefile @@ -0,0 +1,38 @@ +include ../../build_system/make/make.mk + +FREERTOS_SRC = lib/FreeRTOS-Kernel +FREERTOS_PORTABLE_PATH = $(FREERTOS_SRC)/portable/$(if $(findstring iar,$(TOOLCHAIN)),IAR,GCC) + +INC += \ + src \ + src/FreeRTOSConfig \ + $(TOP)/hw \ + $(TOP)/$(FREERTOS_SRC)/include \ + $(TOP)/$(FREERTOS_PORTABLE_SRC) \ + +# Example source +EXAMPLE_SOURCE = \ + src/freertos_hook.c \ + src/main.c \ + src/usb_descriptors.c + +SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) + +# FreeRTOS source, all files in port folder +SRC_C += \ + $(FREERTOS_SRC)/list.c \ + $(FREERTOS_SRC)/queue.c \ + $(FREERTOS_SRC)/tasks.c \ + $(FREERTOS_SRC)/timers.c \ + $(subst $(TOP)/,,$(wildcard $(TOP)/$(FREERTOS_PORTABLE_SRC)/*.c)) + +SRC_S += \ + $(subst $(TOP)/,,$(wildcard $(TOP)/$(FREERTOS_PORTABLE_SRC)/*.s)) + +# Suppress FreeRTOS warnings +CFLAGS += -Wno-error=cast-qual -Wno-error=redundant-decls + +# FreeRTOS (lto + Os) linker issue +LDFLAGS += -Wl,--undefined=vTaskSwitchContext + +include ../../build_system/make/rules.mk diff --git a/examples/device/audio_test_freertos/README.md b/examples/device/audio_test_freertos/README.md new file mode 100644 index 000000000..9477fcd78 --- /dev/null +++ b/examples/device/audio_test_freertos/README.md @@ -0,0 +1,19 @@ +# How to build example for Esp32s3 +1. Load idf environment variables (eg. using the esp-idf alias `get_idf` if configured) + +2. cd into examples directory +``` +$ cd /tinyusb/examples/device/audio_test_freertos +``` + +3. Run cmake in project directory specifying the board +``` +$ cmake -DBOARD=espressif_s3_devkitc -B build -G Ninja . +$ ninja.exe -C build +``` + +4. Flash the binary onto the esp32-s3 by copy-paste of the full command output by the esp-idf build system replacing **(PORT)** with eg. /dev/ttyUSB0 + +eg. + +> /home/kaspernyhus/.espressif/python_env/idf4.4_py3.8_env/bin/python ../../../../esp-idf/components/esptool_py/esptool/esptool.py -p /dev/ttyUSB0 -b 460800 --before default_reset --after hard_reset --chip esp32s3 write_flash --flash_mode dio --flash_size detect --flash_freq 80m 0x0 _build/espressif_s3_devkitc/bootloader/bootloader.bin 0x8000 _build/espressif_s3_devkitc/partition_table/partition-table.bin 0x10000 _build/espressif_s3_devkitc/audio_test_freertos.bin diff --git a/examples/device/audio_test_freertos/sdkconfig.defaults b/examples/device/audio_test_freertos/sdkconfig.defaults new file mode 100644 index 000000000..83871619e --- /dev/null +++ b/examples/device/audio_test_freertos/sdkconfig.defaults @@ -0,0 +1,3 @@ +CONFIG_IDF_CMAKE=y +CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y +CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y diff --git a/examples/device/audio_test_freertos/skip.txt b/examples/device/audio_test_freertos/skip.txt new file mode 100644 index 000000000..a6f96b288 --- /dev/null +++ b/examples/device/audio_test_freertos/skip.txt @@ -0,0 +1,13 @@ +mcu:CH32V307 +mcu:CXD56 +mcu:F1C100S +mcu:GD32VF103 +mcu:MKL25ZXX +mcu:MSP430x5xx +mcu:RP2040 +mcu:SAMD11 +mcu:SAMX7X +mcu:VALENTYUSB_EPTRI +mcu:RAXXX +family:broadcom_32bit +family:broadcom_64bit diff --git a/examples/device/audio_test_freertos/src/CMakeLists.txt b/examples/device/audio_test_freertos/src/CMakeLists.txt new file mode 100644 index 000000000..cef2b46ee --- /dev/null +++ b/examples/device/audio_test_freertos/src/CMakeLists.txt @@ -0,0 +1,4 @@ +# This file is for ESP-IDF only +idf_component_register(SRCS "main.c" "usb_descriptors.c" + INCLUDE_DIRS "." + REQUIRES boards tinyusb_src) diff --git a/examples/device/audio_test_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h b/examples/device/audio_test_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..6cc7a6577 --- /dev/null +++ b/examples/device/audio_test_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,190 @@ +/* + * 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 MCU header +#include "bsp/board_mcu.h" + +#if CFG_TUSB_MCU == OPT_MCU_ESP32S2 || CFG_TUSB_MCU == OPT_MCU_ESP32S3 + #error "ESP32-Sx should use IDF's FreeRTOSConfig.h" +#endif + +// TODO fix later +#if CFG_TUSB_MCU == OPT_MCU_MM32F327X + extern u32 SystemCoreClock; +#else + // FIXME cause redundant-decls warnings + extern uint32_t SystemCoreClock; +#endif + +#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 4 +#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 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* 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 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#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 0 +#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 + +#ifdef __RX__ +/* Renesas RX series */ +#define vSoftwareInterruptISR INT_Excep_ICU_SWINT +#define vTickISR INT_Excep_CMT0_CMI0 +#define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2) +#define configKERNEL_INTERRUPT_PRIORITY 1 +#define configMAX_SYSCALL_INTERRUPT_PRIORITY 4 + +#else + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ +#if defined(__NVIC_PRIO_BITS) + // For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h + #define configPRIO_BITS __NVIC_PRIO_BITS + +#elif defined(__ECLIC_INTCTLBITS) + // RISC-V Bumblebee core from nuclei + #define configPRIO_BITS __ECLIC_INTCTLBITS + +#elif defined(__IASMARM__) + // FIXME: IAR Assembler cannot include mcu header directly to get __NVIC_PRIO_BITS. + // Therefore we will hard coded it to minimum value of 2 to get pass ci build. + // IAR user must update this to correct value of the target MCU + #message "configPRIO_BITS is hard coded to 2 to pass IAR build only. User should update it per MCU" + #define configPRIO_BITS 2 + +#else + #error "FreeRTOS configPRIO_BITS to be defined" +#endif + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< +#include +#include + +#include "bsp/board_api.h" +#include "tusb.h" + +#if TUP_MCU_ESPRESSIF + // ESP-IDF need "freertos/" prefix in include path. + // CFG_TUSB_OS_INC_PATH should be defined accordingly. + #include "freertos/FreeRTOS.h" + #include "freertos/semphr.h" + #include "freertos/queue.h" + #include "freertos/task.h" + #include "freertos/timers.h" + + #define USBD_STACK_SIZE 4096 +#else + + #include "FreeRTOS.h" + #include "semphr.h" + #include "queue.h" + #include "task.h" + #include "timers.h" + + // Increase stack size when debug log is enabled + #define USBD_STACK_SIZE (4*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) +#endif + +#define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF PROTYPES +//--------------------------------------------------------------------+ + +/* Blink pattern + * - 250 ms : device not mounted + * - 1000 ms : device mounted + * - 2500 ms : device is suspended + */ +enum { + BLINK_NOT_MOUNTED = 250, + BLINK_MOUNTED = 1000, + BLINK_SUSPENDED = 2500, +}; + +// static task +#if configSUPPORT_STATIC_ALLOCATION +StackType_t blinky_stack[BLINKY_STACK_SIZE]; +StaticTask_t blinky_taskdef; + +StackType_t usb_device_stack[USBD_STACK_SIZE]; +StaticTask_t usb_device_taskdef; +#endif + +static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; + +// Audio controls +// Current states +bool mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0 +uint16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0 +uint32_t sampFreq; +uint8_t clkValid; + +// Range states +audio_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX+1]; // Volume range state +audio_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state + +// Audio test data +uint16_t test_buffer_audio[(CFG_TUD_AUDIO_EP_SZ_IN - 2) / 2]; +uint16_t startVal = 0; + +void led_blinking_task(void* param); +void usb_device_task(void* param); +void audio_task(void); + +/*------------- MAIN -------------*/ +int main(void) +{ + board_init(); + + // Init values + sampFreq = CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE; + clkValid = 1; + + sampleFreqRng.wNumSubRanges = 1; + sampleFreqRng.subrange[0].bMin = CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE; + sampleFreqRng.subrange[0].bMax = CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE; + sampleFreqRng.subrange[0].bRes = 0; + +#if configSUPPORT_STATIC_ALLOCATION + // blinky task + xTaskCreateStatic(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, blinky_stack, &blinky_taskdef); + + // Create a task for tinyusb device stack + xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef); +#else + xTaskCreate(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, NULL); + xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL); +#endif + + // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 + #if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) + vTaskStartScheduler(); + #endif + + return 0; +} + +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +void app_main(void) +{ + main(); +} +#endif + +// USB Device Driver task +// This top level thread process all usb events and invoke callbacks +void usb_device_task(void* param) +{ + (void) param; + + // init device stack on configured roothub port + // This should be called after scheduler/kernel is started. + // Otherwise it could cause kernel issue since USB IRQ handler does use RTOS queue API. + tud_init(BOARD_TUD_RHPORT); + + if (board_init_after_tusb) { + board_init_after_tusb(); + } + + // RTOS forever loop + while (1) + { + // tinyusb device task + tud_task(); + } +} + +//--------------------------------------------------------------------+ +// Device callbacks +//--------------------------------------------------------------------+ + +// Invoked when device is mounted +void tud_mount_cb(void) { + blink_interval_ms = BLINK_MOUNTED; +} + +// Invoked when device is unmounted +void tud_umount_cb(void) { + blink_interval_ms = BLINK_NOT_MOUNTED; +} + +// Invoked when usb bus is suspended +// remote_wakeup_en : if host allow us to perform remote wakeup +// Within 7ms, device must draw an average of current less than 2.5 mA from bus +void tud_suspend_cb(bool remote_wakeup_en) { + (void) remote_wakeup_en; + blink_interval_ms = BLINK_SUSPENDED; +} + +// Invoked when usb bus is resumed +void tud_resume_cb(void) { + blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; +} + +//--------------------------------------------------------------------+ +// AUDIO Task +//--------------------------------------------------------------------+ + +void audio_task(void) +{ + // Yet to be filled - e.g. put meas data into TX FIFOs etc. + // asm("nop"); +} + +//--------------------------------------------------------------------+ +// Application Callback API Implementations +//--------------------------------------------------------------------+ + +// Invoked when audio class specific set request received for an EP +bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff) +{ + (void) rhport; + (void) pBuff; + + // We do not support any set range requests here, only current value requests + TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR); + + // Page 91 in UAC2 specification + uint8_t channelNum = TU_U16_LOW(p_request->wValue); + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + uint8_t ep = TU_U16_LOW(p_request->wIndex); + + (void) channelNum; (void) ctrlSel; (void) ep; + + return false; // Yet not implemented +} + +// Invoked when audio class specific set request received for an interface +bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff) +{ + (void) rhport; + (void) pBuff; + + // We do not support any set range requests here, only current value requests + TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR); + + // Page 91 in UAC2 specification + uint8_t channelNum = TU_U16_LOW(p_request->wValue); + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + uint8_t itf = TU_U16_LOW(p_request->wIndex); + + (void) channelNum; (void) ctrlSel; (void) itf; + + return false; // Yet not implemented +} + +// Invoked when audio class specific set request received for an entity +bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff) +{ + (void) rhport; + + // Page 91 in UAC2 specification + uint8_t channelNum = TU_U16_LOW(p_request->wValue); + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + uint8_t itf = TU_U16_LOW(p_request->wIndex); + uint8_t entityID = TU_U16_HIGH(p_request->wIndex); + + (void) itf; + + // We do not support any set range requests here, only current value requests + TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR); + + // If request is for our feature unit + if ( entityID == 2 ) + { + switch ( ctrlSel ) + { + case AUDIO_FU_CTRL_MUTE: + // Request uses format layout 1 + TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_1_t)); + + mute[channelNum] = ((audio_control_cur_1_t*) pBuff)->bCur; + + TU_LOG2(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum); + return true; + + case AUDIO_FU_CTRL_VOLUME: + // Request uses format layout 2 + TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_2_t)); + + volume[channelNum] = (uint16_t) ((audio_control_cur_2_t*) pBuff)->bCur; + + TU_LOG2(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum); + return true; + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + } + return false; // Yet not implemented +} + +// Invoked when audio class specific get request received for an EP +bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request) +{ + (void) rhport; + + // Page 91 in UAC2 specification + uint8_t channelNum = TU_U16_LOW(p_request->wValue); + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + uint8_t ep = TU_U16_LOW(p_request->wIndex); + + (void) channelNum; (void) ctrlSel; (void) ep; + + return false; // Yet not implemented +} + +// Invoked when audio class specific get request received for an interface +bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request) +{ + (void) rhport; + + // Page 91 in UAC2 specification + uint8_t channelNum = TU_U16_LOW(p_request->wValue); + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + uint8_t itf = TU_U16_LOW(p_request->wIndex); + + (void) channelNum; (void) ctrlSel; (void) itf; + + return false; // Yet not implemented +} + +// Invoked when audio class specific get request received for an entity +bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request) +{ + (void) rhport; + + // Page 91 in UAC2 specification + uint8_t channelNum = TU_U16_LOW(p_request->wValue); + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + // uint8_t itf = TU_U16_LOW(p_request->wIndex); // Since we have only one audio function implemented, we do not need the itf value + uint8_t entityID = TU_U16_HIGH(p_request->wIndex); + + // Input terminal (Microphone input) + if (entityID == 1) + { + switch ( ctrlSel ) + { + case AUDIO_TE_CTRL_CONNECTOR: + { + // The terminal connector control only has a get request with only the CUR attribute. + audio_desc_channel_cluster_t ret; + + // Those are dummy values for now + ret.bNrChannels = 1; + ret.bmChannelConfig = (audio_channel_config_t) 0; + ret.iChannelNames = 0; + + TU_LOG2(" Get terminal connector\r\n"); + + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void*) &ret, sizeof(ret)); + } + break; + + // Unknown/Unsupported control selector + default: + TU_BREAKPOINT(); + return false; + } + } + + // Feature unit + if (entityID == 2) + { + switch ( ctrlSel ) + { + case AUDIO_FU_CTRL_MUTE: + // Audio control mute cur parameter block consists of only one byte - we thus can send it right away + // There does not exist a range parameter block for mute + TU_LOG2(" Get Mute of channel: %u\r\n", channelNum); + return tud_control_xfer(rhport, p_request, &mute[channelNum], 1); + + case AUDIO_FU_CTRL_VOLUME: + switch ( p_request->bRequest ) + { + case AUDIO_CS_REQ_CUR: + TU_LOG2(" Get Volume of channel: %u\r\n", channelNum); + return tud_control_xfer(rhport, p_request, &volume[channelNum], sizeof(volume[channelNum])); + + case AUDIO_CS_REQ_RANGE: + TU_LOG2(" Get Volume range of channel: %u\r\n", channelNum); + + // Copy values - only for testing - better is version below + audio_control_range_2_n_t(1) + ret; + + ret.wNumSubRanges = 1; + ret.subrange[0].bMin = -90; // -90 dB + ret.subrange[0].bMax = 90; // +90 dB + ret.subrange[0].bRes = 1; // 1 dB steps + + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void*) &ret, sizeof(ret)); + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + break; + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + } + + // Clock Source unit + if ( entityID == 4 ) + { + switch ( ctrlSel ) + { + case AUDIO_CS_CTRL_SAM_FREQ: + // channelNum is always zero in this case + switch ( p_request->bRequest ) + { + case AUDIO_CS_REQ_CUR: + TU_LOG2(" Get Sample Freq.\r\n"); + return tud_control_xfer(rhport, p_request, &sampFreq, sizeof(sampFreq)); + + case AUDIO_CS_REQ_RANGE: + TU_LOG2(" Get Sample Freq. range\r\n"); + return tud_control_xfer(rhport, p_request, &sampleFreqRng, sizeof(sampleFreqRng)); + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + break; + + case AUDIO_CS_CTRL_CLK_VALID: + // Only cur attribute exists for this request + TU_LOG2(" Get Sample Freq. valid\r\n"); + return tud_control_xfer(rhport, p_request, &clkValid, sizeof(clkValid)); + + // Unknown/Unsupported control + default: + TU_BREAKPOINT(); + return false; + } + } + + TU_LOG2(" Unsupported entity: %d\r\n", entityID); + return false; // Yet not implemented +} + +bool tud_audio_tx_done_pre_load_cb(uint8_t rhport, uint8_t itf, uint8_t ep_in, uint8_t cur_alt_setting) +{ + (void) rhport; + (void) itf; + (void) ep_in; + (void) cur_alt_setting; + + tud_audio_write ((uint8_t *)test_buffer_audio, CFG_TUD_AUDIO_EP_SZ_IN - 2); + + return true; +} + +bool tud_audio_tx_done_post_load_cb(uint8_t rhport, uint16_t n_bytes_copied, uint8_t itf, uint8_t ep_in, uint8_t cur_alt_setting) +{ + (void) rhport; + (void) n_bytes_copied; + (void) itf; + (void) ep_in; + (void) cur_alt_setting; + + for (size_t cnt = 0; cnt < (CFG_TUD_AUDIO_EP_SZ_IN - 2) / 2; cnt++) + { + test_buffer_audio[cnt] = startVal++; + } + + return true; +} + +bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const * p_request) +{ + (void) rhport; + (void) p_request; + startVal = 0; + + return true; +} + +//--------------------------------------------------------------------+ +// BLINKING TASK +//--------------------------------------------------------------------+ +void led_blinking_task(void* param) { + (void) param; + static uint32_t start_ms = 0; + static bool led_state = false; + + while (1) { + // Blink every interval ms + vTaskDelay(blink_interval_ms / portTICK_PERIOD_MS); + start_ms += blink_interval_ms; + + board_led_write(led_state); + led_state = 1 - led_state; // toggle + } +} diff --git a/examples/device/audio_test_freertos/src/plot_audio_samples.py b/examples/device/audio_test_freertos/src/plot_audio_samples.py new file mode 100644 index 000000000..304b2d5de --- /dev/null +++ b/examples/device/audio_test_freertos/src/plot_audio_samples.py @@ -0,0 +1,33 @@ +import sounddevice as sd +import matplotlib.pyplot as plt +import numpy as np +import platform + +if __name__ == '__main__': + + # If you got "ValueError: No input device matching", that is because your PC name example device + # differently from tested list below. Uncomment the next line to see full list and try to pick correct one + # print(sd.query_devices()) + + fs = 48000 # Sample rate + duration = 1000e-3 # Duration of recording + + if platform.system() == 'Windows': + # MME is needed since there are more than one MicNode device APIs (at least in Windows) + device = 'Microphone (MicNode) MME' + elif platform.system() == 'Darwin': + device = 'MicNode' + else: + device ='default' + + myrecording = sd.rec(int(duration * fs), samplerate=fs, channels=1, dtype='int16', device=device) + print('Waiting...') + sd.wait() # Wait until recording is finished + print('Done!') + + time = np.arange(0, duration, 1 / fs) # time vector + plt.plot(time, myrecording) + plt.xlabel('Time [s]') + plt.ylabel('Amplitude') + plt.title('MicNode') + plt.show() diff --git a/examples/device/audio_test_freertos/src/tusb_config.h b/examples/device/audio_test_freertos/src/tusb_config.h new file mode 100644 index 000000000..8b376a4c3 --- /dev/null +++ b/examples/device/audio_test_freertos/src/tusb_config.h @@ -0,0 +1,132 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 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. + * + */ + +#ifndef _TUSB_CONFIG_H_ +#define _TUSB_CONFIG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Board Specific Configuration +//--------------------------------------------------------------------+ + +// RHPort number used for device can be defined by board.mk, default to port 0 +#ifndef BOARD_TUD_RHPORT +#define BOARD_TUD_RHPORT 0 +#endif + +// RHPort max operational speed can defined by board.mk +#ifndef BOARD_TUD_MAX_SPEED +#define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED +#endif + +//-------------------------------------------------------------------- +// COMMON CONFIGURATION +//-------------------------------------------------------------------- + +// defined by compiler flags for flexibility +#ifndef CFG_TUSB_MCU +#error CFG_TUSB_MCU must be defined +#endif + +// This examples use FreeRTOS +#ifndef CFG_TUSB_OS +#define CFG_TUSB_OS OPT_OS_FREERTOS +#endif + +// Espressif IDF requires "freertos/" prefix in include path +#if TUP_MCU_ESPRESSIF +#define CFG_TUSB_OS_INC_PATH freertos/ +#endif + +#ifndef CFG_TUSB_DEBUG +#define CFG_TUSB_DEBUG 0 +#endif + +// Enable Device stack +#define CFG_TUD_ENABLED 1 + +// Default is max speed that hardware controller could support with on-chip PHY +#define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED + +// CFG_TUSB_DEBUG is defined by compiler in DEBUG build +// #define CFG_TUSB_DEBUG 0 + +/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. + * Tinyusb use follows macros to declare transferring memory so that they can be put + * into those specific section. + * e.g + * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) + * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) + */ +#ifndef CFG_TUSB_MEM_SECTION +#define CFG_TUSB_MEM_SECTION +#endif + +#ifndef CFG_TUSB_MEM_ALIGN +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#endif + +//-------------------------------------------------------------------- +// DEVICE CONFIGURATION +//-------------------------------------------------------------------- + +#ifndef CFG_TUD_ENDPOINT0_SIZE +#define CFG_TUD_ENDPOINT0_SIZE 64 +#endif + +//------------- CLASS -------------// +#define CFG_TUD_AUDIO 1 +#define CFG_TUD_CDC 0 +#define CFG_TUD_MSC 0 +#define CFG_TUD_HID 0 +#define CFG_TUD_MIDI 0 +#define CFG_TUD_VENDOR 0 + +//-------------------------------------------------------------------- +// AUDIO CLASS DRIVER CONFIGURATION +//-------------------------------------------------------------------- + +// Have a look into audio_device.h for all configurations +#define CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE 48000 + +#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_MIC_ONE_CH_DESC_LEN +#define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 1 // Number of Standard AS Interface Descriptors (4.9.1) defined per audio function - this is required to be able to remember the current alternate settings of these interfaces - We restrict us here to have a constant number for all audio functions (which means this has to be the maximum number of AS interfaces an audio function has and a second audio function with less AS interfaces just wastes a few bytes) +#define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64 // Size of control request buffer + +#define CFG_TUD_AUDIO_ENABLE_EP_IN 1 +#define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below +#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 1 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below - be aware: for different number of channels you need another descriptor! +#define CFG_TUD_AUDIO_EP_SZ_IN TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 8 : 1) * CFG_TUD_AUDIO_EP_SZ_IN // Example write FIFO every 1ms, so it should be 8 times larger for HS device + +#ifdef __cplusplus +} +#endif + +#endif /* _TUSB_CONFIG_H_ */ diff --git a/examples/device/audio_test_freertos/src/usb_descriptors.c b/examples/device/audio_test_freertos/src/usb_descriptors.c new file mode 100644 index 000000000..9864377f6 --- /dev/null +++ b/examples/device/audio_test_freertos/src/usb_descriptors.c @@ -0,0 +1,181 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 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. + * + */ + +#include "bsp/board_api.h" +#include "tusb.h" + +/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. + * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. + * + * Auto ProductID layout's Bitmap: + * [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB] + */ +#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) +#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ + _PID_MAP(MIDI, 3) | _PID_MAP(AUDIO, 4) | _PID_MAP(VENDOR, 5) ) + +//--------------------------------------------------------------------+ +// Device Descriptors +//--------------------------------------------------------------------+ +tusb_desc_device_t const desc_device = +{ + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = 0x0200, + + // Use Interface Association Descriptor (IAD) for Audio + // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) + .bDeviceClass = TUSB_CLASS_MISC, + .bDeviceSubClass = MISC_SUBCLASS_COMMON, + .bDeviceProtocol = MISC_PROTOCOL_IAD, + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + + .idVendor = 0xCafe, + .idProduct = USB_PID, + .bcdDevice = 0x0100, + + .iManufacturer = 0x01, + .iProduct = 0x02, + .iSerialNumber = 0x03, + + .bNumConfigurations = 0x01 +}; + +// Invoked when received GET DEVICE DESCRIPTOR +// Application return pointer to descriptor +uint8_t const * tud_descriptor_device_cb(void) +{ + return (uint8_t const *) &desc_device; +} + +//--------------------------------------------------------------------+ +// Configuration Descriptor +//--------------------------------------------------------------------+ +enum +{ + ITF_NUM_AUDIO_CONTROL = 0, + ITF_NUM_AUDIO_STREAMING, + ITF_NUM_TOTAL +}; + +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_AUDIO * TUD_AUDIO_MIC_ONE_CH_DESC_LEN) + +#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX + // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number + // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... + #define EPNUM_AUDIO 0x03 + +#elif TU_CHECK_MCU(OPT_MCU_NRF5X) + // nRF5x ISO can only be endpoint 8 + #define EPNUM_AUDIO 0x08 + +#else + #define EPNUM_AUDIO 0x01 +#endif + +uint8_t const desc_configuration[] = +{ + // Config number, interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), + + // Interface number, string index, EP Out & EP In address, EP size + TUD_AUDIO_MIC_ONE_CH_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_nBytesPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, /*_nBitsUsedPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX*8, /*_epin*/ 0x80 | EPNUM_AUDIO, /*_epsize*/ CFG_TUD_AUDIO_EP_SZ_IN) +}; + +// Invoked when received GET CONFIGURATION DESCRIPTOR +// Application return pointer to descriptor +// Descriptor contents must exist long enough for transfer to complete +uint8_t const * tud_descriptor_configuration_cb(uint8_t index) +{ + (void) index; // for multiple configurations + return desc_configuration; +} + +//--------------------------------------------------------------------+ +// String Descriptors +//--------------------------------------------------------------------+ + +// String Descriptor Index +enum { + STRID_LANGID = 0, + STRID_MANUFACTURER, + STRID_PRODUCT, + STRID_SERIAL, +}; + +// array of pointer to string descriptors +char const* string_desc_arr [] = +{ + (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) + "PaniRCorp", // 1: Manufacturer + "MicNode", // 2: Product + NULL, // 3: Serials will use unique ID if possible + "UAC2", // 4: Audio Interface + +}; + +static uint16_t _desc_str[32 + 1]; + +// Invoked when received GET STRING DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete +uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { + (void) langid; + size_t chr_count; + + switch ( index ) { + case STRID_LANGID: + memcpy(&_desc_str[1], string_desc_arr[0], 2); + chr_count = 1; + break; + + case STRID_SERIAL: + chr_count = board_usb_get_serial(_desc_str + 1, 32); + break; + + default: + // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. + // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors + + if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; + + const char *str = string_desc_arr[index]; + + // Cap at max char + chr_count = strlen(str); + size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type + if ( chr_count > max_count ) chr_count = max_count; + + // Convert ASCII string into UTF-16 + for ( size_t i = 0; i < chr_count; i++ ) { + _desc_str[1 + i] = str[i]; + } + break; + } + + // first byte is length (including header), second byte is string type + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); + + return _desc_str; +} diff --git a/examples/device/audio_test_multi_rate/Makefile b/examples/device/audio_test_multi_rate/Makefile index 2a3d854fb..7fa475da5 100644 --- a/examples/device/audio_test_multi_rate/Makefile +++ b/examples/device/audio_test_multi_rate/Makefile @@ -1,4 +1,4 @@ -include ../../make.mk +include ../../build_system/make/make.mk INC += \ src \ @@ -8,4 +8,4 @@ INC += \ EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) -include ../../rules.mk +include ../../build_system/make/rules.mk diff --git a/examples/device/audio_test_multi_rate/skip.txt b/examples/device/audio_test_multi_rate/skip.txt index 1ee86a485..65b137814 100644 --- a/examples/device/audio_test_multi_rate/skip.txt +++ b/examples/device/audio_test_multi_rate/skip.txt @@ -1,3 +1,4 @@ mcu:SAMD11 mcu:SAME5X mcu:SAMG +family:espressif diff --git a/examples/device/audio_test_multi_rate/src/main.c b/examples/device/audio_test_multi_rate/src/main.c index 677bae75a..2ff7f10bd 100644 --- a/examples/device/audio_test_multi_rate/src/main.c +++ b/examples/device/audio_test_multi_rate/src/main.c @@ -146,7 +146,7 @@ void tud_suspend_cb(bool remote_wakeup_en) // Invoked when usb bus is resumed void tud_resume_cb(void) { - blink_interval_ms = BLINK_MOUNTED; + blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ @@ -272,7 +272,7 @@ bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const * sampFreq = (uint32_t)((audio_control_cur_4_t *)pBuff)->bCur; - TU_LOG2("Clock set current freq: %lu\r\n", sampFreq); + TU_LOG2("Clock set current freq: %" PRIu32 "\r\n", sampFreq); return true; break; diff --git a/examples/device/board_test/Makefile b/examples/device/board_test/Makefile index 2a3d854fb..7fa475da5 100644 --- a/examples/device/board_test/Makefile +++ b/examples/device/board_test/Makefile @@ -1,4 +1,4 @@ -include ../../make.mk +include ../../build_system/make/make.mk INC += \ src \ @@ -8,4 +8,4 @@ INC += \ EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) -include ../../rules.mk +include ../../build_system/make/rules.mk diff --git a/examples/device/board_test/src/main.c b/examples/device/board_test/src/main.c index 0a134a2e6..91799eb89 100644 --- a/examples/device/board_test/src/main.c +++ b/examples/device/board_test/src/main.c @@ -26,39 +26,31 @@ #include #include #include - #include "bsp/board_api.h" -//--------------------------------------------------------------------+ -// MACRO CONSTANT TYPEDEF PROTOTYPES -//--------------------------------------------------------------------+ - /* Blink pattern * - 250 ms : button is not pressed * - 1000 ms : button is pressed (and hold) */ -enum { +enum { BLINK_PRESSED = 250, BLINK_UNPRESSED = 1000 }; #define HELLO_STR "Hello from TinyUSB\r\n" -int main(void) -{ +int main(void) { board_init(); board_led_write(true); uint32_t start_ms = 0; bool led_state = false; - while (1) - { + while (1) { uint32_t interval_ms = board_button_read() ? BLINK_PRESSED : BLINK_UNPRESSED; // Blink and print every interval ms - if ( !(board_millis() - start_ms < interval_ms) ) - { + if (!(board_millis() - start_ms < interval_ms)) { board_uart_write(HELLO_STR, strlen(HELLO_STR)); start_ms = board_millis(); @@ -69,16 +61,14 @@ int main(void) // echo uint8_t ch; - if ( board_uart_read(&ch, 1) > 0 ) - { + if (board_uart_read(&ch, 1) > 0) { board_uart_write(&ch, 1); } } } #if CFG_TUSB_MCU == OPT_MCU_ESP32S2 || CFG_TUSB_MCU == OPT_MCU_ESP32S3 -void app_main(void) -{ +void app_main(void) { main(); } #endif diff --git a/examples/device/board_test/src/tusb_config.h b/examples/device/board_test/src/tusb_config.h index 2c2eb5280..36eafe807 100644 --- a/examples/device/board_test/src/tusb_config.h +++ b/examples/device/board_test/src/tusb_config.h @@ -48,6 +48,11 @@ #define CFG_TUSB_OS OPT_OS_NONE #endif +// Espressif IDF requires "freertos/" prefix in include path +#if TUP_MCU_ESPRESSIF +#define CFG_TUSB_OS_INC_PATH freertos/ +#endif + // This example only test LED & GPIO, disable both device and host stack #define CFG_TUD_ENABLED 0 #define CFG_TUH_ENABLED 0 diff --git a/examples/device/cdc_dual_ports/Makefile b/examples/device/cdc_dual_ports/Makefile index 2a3d854fb..7fa475da5 100644 --- a/examples/device/cdc_dual_ports/Makefile +++ b/examples/device/cdc_dual_ports/Makefile @@ -1,4 +1,4 @@ -include ../../make.mk +include ../../build_system/make/make.mk INC += \ src \ @@ -8,4 +8,4 @@ INC += \ EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) -include ../../rules.mk +include ../../build_system/make/rules.mk diff --git a/examples/device/cdc_dual_ports/src/main.c b/examples/device/cdc_dual_ports/src/main.c index 98f3ab923..1167a5d50 100644 --- a/examples/device/cdc_dual_ports/src/main.c +++ b/examples/device/cdc_dual_ports/src/main.c @@ -31,12 +31,24 @@ #include "bsp/board_api.h" #include "tusb.h" -//------------- prototypes -------------// +/* Blink pattern + * - 250 ms : device not mounted + * - 1000 ms : device mounted + * - 2500 ms : device is suspended + */ +enum { + BLINK_NOT_MOUNTED = 250, + BLINK_MOUNTED = 1000, + BLINK_SUSPENDED = 2500, +}; + +static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; + +static void led_blinking_task(void); static void cdc_task(void); /*------------- MAIN -------------*/ -int main(void) -{ +int main(void) { board_init(); // init device stack on configured roothub port @@ -46,28 +58,23 @@ int main(void) board_init_after_tusb(); } - while (1) - { + while (1) { tud_task(); // tinyusb device task cdc_task(); + led_blinking_task(); } } // echo to either Serial0 or Serial1 // with Serial0 as all lower case, Serial1 as all upper case -static void echo_serial_port(uint8_t itf, uint8_t buf[], uint32_t count) -{ +static void echo_serial_port(uint8_t itf, uint8_t buf[], uint32_t count) { uint8_t const case_diff = 'a' - 'A'; - for(uint32_t i=0; i -#include -#include - #include "bsp/board_api.h" #include "tusb.h" @@ -39,7 +35,7 @@ * - 1000 ms : device mounted * - 2500 ms : device is suspended */ -enum { +enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, @@ -51,8 +47,7 @@ void led_blinking_task(void); void cdc_task(void); /*------------- MAIN -------------*/ -int main(void) -{ +int main(void) { board_init(); // init device stack on configured roothub port @@ -62,8 +57,7 @@ int main(void) board_init_after_tusb(); } - while (1) - { + while (1) { tud_task(); // tinyusb device task led_blinking_task(); @@ -76,45 +70,39 @@ int main(void) //--------------------------------------------------------------------+ // Invoked when device is mounted -void tud_mount_cb(void) -{ +void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted -void tud_umount_cb(void) -{ +void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus -void tud_suspend_cb(bool remote_wakeup_en) -{ +void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed -void tud_resume_cb(void) -{ - blink_interval_ms = BLINK_MOUNTED; +void tud_resume_cb(void) { + blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ // USB CDC //--------------------------------------------------------------------+ -void cdc_task(void) -{ +void cdc_task(void) { // connected() check for DTR bit // Most but not all terminal client set this when making connection // if ( tud_cdc_connected() ) { // connected and there are data available - if ( tud_cdc_available() ) - { + if (tud_cdc_available()) { // read data char buf[64]; uint32_t count = tud_cdc_read(buf, sizeof(buf)); @@ -131,37 +119,32 @@ void cdc_task(void) } // Invoked when cdc when line state changed e.g connected/disconnected -void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) -{ +void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { (void) itf; (void) rts; // TODO set some indicator - if ( dtr ) - { + if (dtr) { // Terminal connected - }else - { + } else { // Terminal disconnected } } // Invoked when CDC interface received data from host -void tud_cdc_rx_cb(uint8_t itf) -{ +void tud_cdc_rx_cb(uint8_t itf) { (void) itf; } //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ -void led_blinking_task(void) -{ +void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms - if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time + if (board_millis() - start_ms < blink_interval_ms) return; // not enough time start_ms += blink_interval_ms; board_led_write(led_state); diff --git a/examples/device/cdc_msc_freertos/Makefile b/examples/device/cdc_msc_freertos/Makefile index 0bee668b7..fe3fb6482 100644 --- a/examples/device/cdc_msc_freertos/Makefile +++ b/examples/device/cdc_msc_freertos/Makefile @@ -1,16 +1,14 @@ -DEPS_SUBMODULES += lib/FreeRTOS-Kernel - -include ../../make.mk +include ../../build_system/make/make.mk FREERTOS_SRC = lib/FreeRTOS-Kernel -FREERTOS_PORTABLE_PATH= $(FREERTOS_SRC)/portable/$(if $(USE_IAR),IAR,GCC) +FREERTOS_PORTABLE_PATH = $(FREERTOS_SRC)/portable/$(if $(findstring iar,$(TOOLCHAIN)),IAR,GCC) INC += \ src \ src/FreeRTOSConfig \ $(TOP)/hw \ $(TOP)/$(FREERTOS_SRC)/include \ - $(TOP)/$(FREERTOS_PORTABLE_SRC) + $(TOP)/$(FREERTOS_PORTABLE_SRC) \ # Example source EXAMPLE_SOURCE = \ @@ -45,4 +43,4 @@ CFLAGS_GCC += -Wno-error=cast-qual # FreeRTOS (lto + Os) linker issue LDFLAGS_GCC += -Wl,--undefined=vTaskSwitchContext -include ../../rules.mk +include ../../build_system/make/rules.mk diff --git a/examples/device/cdc_msc_freertos/skip.txt b/examples/device/cdc_msc_freertos/skip.txt index a6f96b288..eb434c23b 100644 --- a/examples/device/cdc_msc_freertos/skip.txt +++ b/examples/device/cdc_msc_freertos/skip.txt @@ -9,5 +9,6 @@ mcu:SAMD11 mcu:SAMX7X mcu:VALENTYUSB_EPTRI mcu:RAXXX +mcu:STM32L0 family:broadcom_32bit family:broadcom_64bit diff --git a/examples/device/cdc_msc_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h b/examples/device/cdc_msc_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h index 69d638288..6cc7a6577 100644 --- a/examples/device/cdc_msc_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h +++ b/examples/device/cdc_msc_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h @@ -96,6 +96,7 @@ #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 +#define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 @@ -130,23 +131,6 @@ #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 - #ifdef __RX__ /* Renesas RX series */ #define vSoftwareInterruptISR INT_Excep_ICU_SWINT diff --git a/examples/device/cdc_msc_freertos/src/freertos_hook.c b/examples/device/cdc_msc_freertos/src/freertos_hook.c index ab885947c..4920e3fae 100644 --- a/examples/device/cdc_msc_freertos/src/freertos_hook.c +++ b/examples/device/cdc_msc_freertos/src/freertos_hook.c @@ -99,9 +99,10 @@ void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, Stack void vApplicationSetupTimerInterrupt(void) { /* Enable CMT0 */ + unsigned short oldPRCR = SYSTEM.PRCR.WORD; SYSTEM.PRCR.WORD = (0xA5u<<8) | TU_BIT(1); MSTP(CMT0) = 0; - SYSTEM.PRCR.WORD = (0xA5u<<8); + SYSTEM.PRCR.WORD = (0xA5u<<8) | oldPRCR; CMT0.CMCNT = 0; CMT0.CMCOR = (unsigned short)(((configPERIPHERAL_CLOCK_HZ/configTICK_RATE_HZ)-1)/128); diff --git a/examples/device/cdc_msc_freertos/src/main.c b/examples/device/cdc_msc_freertos/src/main.c index c93e89752..607d40270 100644 --- a/examples/device/cdc_msc_freertos/src/main.c +++ b/examples/device/cdc_msc_freertos/src/main.c @@ -30,7 +30,7 @@ #include "bsp/board_api.h" #include "tusb.h" -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF // ESP-IDF need "freertos/" prefix in include path. // CFG_TUSB_OS_INC_PATH should be defined accordingly. #include "freertos/FreeRTOS.h" @@ -41,6 +41,7 @@ #define USBD_STACK_SIZE 4096 #else + #include "FreeRTOS.h" #include "semphr.h" #include "queue.h" @@ -51,10 +52,11 @@ #define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) #endif -#define CDC_STACK_SZIE configMINIMAL_STACK_SIZE +#define CDC_STACK_SIZE configMINIMAL_STACK_SIZE +#define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE //--------------------------------------------------------------------+ -// MACRO CONSTANT TYPEDEF PROTYPES +// MACRO CONSTANT TYPEDEF PROTOTYPES //--------------------------------------------------------------------+ /* Blink pattern @@ -62,73 +64,69 @@ * - 1000 ms : device mounted * - 2500 ms : device is suspended */ -enum { +enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, }; -// static timer & task +// static task #if configSUPPORT_STATIC_ALLOCATION -StaticTimer_t blinky_tmdef; +StackType_t blinky_stack[BLINKY_STACK_SIZE]; +StaticTask_t blinky_taskdef; StackType_t usb_device_stack[USBD_STACK_SIZE]; StaticTask_t usb_device_taskdef; -StackType_t cdc_stack[CDC_STACK_SZIE]; +StackType_t cdc_stack[CDC_STACK_SIZE]; StaticTask_t cdc_taskdef; #endif -TimerHandle_t blinky_tm; +static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; -void led_blinky_cb(TimerHandle_t xTimer); -void usb_device_task(void* param); -void cdc_task(void* params); +static void usb_device_task(void *param); +void led_blinking_task(void* param); +void cdc_task(void *params); //--------------------------------------------------------------------+ // Main //--------------------------------------------------------------------+ -int main(void) -{ +int main(void) { board_init(); #if configSUPPORT_STATIC_ALLOCATION - // soft timer for blinky - blinky_tm = xTimerCreateStatic(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb, &blinky_tmdef); + // blinky task + xTaskCreateStatic(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, blinky_stack, &blinky_taskdef); // Create a task for tinyusb device stack xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef); // Create CDC task - xTaskCreateStatic(cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, cdc_stack, &cdc_taskdef); + xTaskCreateStatic(cdc_task, "cdc", CDC_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, cdc_stack, &cdc_taskdef); #else - blinky_tm = xTimerCreate(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb); - xTaskCreate( usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, NULL); - xTaskCreate( cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, NULL); + xTaskCreate(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, NULL); + xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL); + xTaskCreate(cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES - 2, NULL); #endif - xTimerStart(blinky_tm, 0); - // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 -#if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if !TUP_MCU_ESPRESSIF vTaskStartScheduler(); #endif return 0; } -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) -void app_main(void) -{ +#if TUP_MCU_ESPRESSIF +void app_main(void) { main(); } #endif // USB Device Driver task // This top level thread process all usb events and invoke callbacks -void usb_device_task(void* param) -{ +static void usb_device_task(void *param) { (void) param; // init device stack on configured roothub port @@ -141,8 +139,7 @@ void usb_device_task(void* param) } // RTOS forever loop - while (1) - { + while (1) { // put this thread to waiting state until there is new events tud_task(); @@ -156,49 +153,42 @@ void usb_device_task(void* param) //--------------------------------------------------------------------+ // Invoked when device is mounted -void tud_mount_cb(void) -{ - xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_MOUNTED), 0); +void tud_mount_cb(void) { + blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted -void tud_umount_cb(void) -{ - xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), 0); +void tud_umount_cb(void) { + blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus -void tud_suspend_cb(bool remote_wakeup_en) -{ +void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; - xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_SUSPENDED), 0); + blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed -void tud_resume_cb(void) -{ - xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_MOUNTED), 0); +void tud_resume_cb(void) { + blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ // USB CDC //--------------------------------------------------------------------+ -void cdc_task(void* params) -{ +void cdc_task(void *params) { (void) params; // RTOS forever loop - while ( 1 ) - { + while (1) { // connected() check for DTR bit // Most but not all terminal client set this when making connection // if ( tud_cdc_connected() ) { // There are data available - while ( tud_cdc_available() ) - { + while (tud_cdc_available()) { uint8_t buf[64]; // read and echo back @@ -221,35 +211,37 @@ void cdc_task(void* params) } // Invoked when cdc when line state changed e.g connected/disconnected -void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) -{ +void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { (void) itf; (void) rts; // TODO set some indicator - if ( dtr ) - { + if (dtr) { // Terminal connected - }else - { + } else { // Terminal disconnected } } // Invoked when CDC interface received data from host -void tud_cdc_rx_cb(uint8_t itf) -{ +void tud_cdc_rx_cb(uint8_t itf) { (void) itf; } //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ -void led_blinky_cb(TimerHandle_t xTimer) -{ - (void) xTimer; +void led_blinking_task(void* param) { + (void) param; + static uint32_t start_ms = 0; static bool led_state = false; - board_led_write(led_state); - led_state = 1 - led_state; // toggle + while (1) { + // Blink every interval ms + vTaskDelay(blink_interval_ms / portTICK_PERIOD_MS); + start_ms += blink_interval_ms; + + board_led_write(led_state); + led_state = 1 - led_state; // toggle + } } diff --git a/examples/device/cdc_msc_freertos/src/msc_disk.c b/examples/device/cdc_msc_freertos/src/msc_disk.c index 9520dfec1..c8a04bb74 100644 --- a/examples/device/cdc_msc_freertos/src/msc_disk.c +++ b/examples/device/cdc_msc_freertos/src/msc_disk.c @@ -184,7 +184,7 @@ int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buff uint8_t const* addr = msc_disk[lba] + offset; memcpy(buffer, addr, bufsize); - return bufsize; + return (int32_t) bufsize; } // Callback invoked when received WRITE10 command. @@ -203,7 +203,7 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* (void) lba; (void) offset; (void) buffer; #endif - return bufsize; + return (int32_t) bufsize; } // Callback invoked when received an SCSI command not in built-in list below @@ -237,14 +237,14 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, { if(in_xfer) { - memcpy(buffer, response, resplen); + memcpy(buffer, response, (size_t) resplen); }else { // SCSI output } } - return resplen; + return (int32_t) resplen; } #endif diff --git a/examples/device/cdc_msc_freertos/src/tusb_config.h b/examples/device/cdc_msc_freertos/src/tusb_config.h index 91efe7d40..e743c9148 100644 --- a/examples/device/cdc_msc_freertos/src/tusb_config.h +++ b/examples/device/cdc_msc_freertos/src/tusb_config.h @@ -59,7 +59,7 @@ #endif // Espressif IDF requires "freertos/" prefix in include path -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF #define CFG_TUSB_OS_INC_PATH freertos/ #endif diff --git a/examples/device/cdc_uac2/Makefile b/examples/device/cdc_uac2/Makefile index b7a8302ce..21dcdb0b2 100644 --- a/examples/device/cdc_uac2/Makefile +++ b/examples/device/cdc_uac2/Makefile @@ -1,4 +1,4 @@ -include ../../make.mk +include ../../build_system/make/make.mk INC += \ src \ @@ -13,4 +13,4 @@ EXAMPLE_SOURCE += \ SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) -include ../../rules.mk +include ../../build_system/make/rules.mk diff --git a/examples/device/cdc_uac2/src/main.c b/examples/device/cdc_uac2/src/main.c index 7afa96c1a..25b2cd9a5 100644 --- a/examples/device/cdc_uac2/src/main.c +++ b/examples/device/cdc_uac2/src/main.c @@ -60,7 +60,7 @@ int main(void) led_blinking_task(); #if (CFG_TUSB_MCU == OPT_MCU_RP2040) - // printf("Hello, world!\n"); + // printf("Hello, world!\r\n"); #endif } diff --git a/examples/device/cdc_uac2/src/tusb_config.h b/examples/device/cdc_uac2/src/tusb_config.h index 373f0b01f..93489cf62 100644 --- a/examples/device/cdc_uac2/src/tusb_config.h +++ b/examples/device/cdc_uac2/src/tusb_config.h @@ -151,11 +151,11 @@ extern "C" { // EP and buffer size - for isochronous EP´s, the buffer and EP size are equal (different sizes would not make sense) #define CFG_TUD_AUDIO_ENABLE_EP_OUT 1 -#define CFG_TUD_AUDIO_UNC_1_FORMAT_1_EP_SZ_OUT TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX) -#define CFG_TUD_AUDIO_UNC_1_FORMAT_2_EP_SZ_OUT TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX) +#define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_OUT TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX) +#define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_OUT TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX) -#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ TU_MAX(CFG_TUD_AUDIO_UNC_1_FORMAT_1_EP_SZ_OUT, CFG_TUD_AUDIO_UNC_1_FORMAT_1_EP_SZ_OUT) -#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX TU_MAX(CFG_TUD_AUDIO_UNC_1_FORMAT_1_EP_SZ_OUT, CFG_TUD_AUDIO_UNC_1_FORMAT_1_EP_SZ_OUT) // Maximum EP IN size for all AS alternate settings used +#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ TU_MAX(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_OUT, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_OUT) +#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX TU_MAX(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_OUT, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_OUT) // Maximum EP IN size for all AS alternate settings used // Number of Standard AS Interface Descriptors (4.9.1) defined per audio function - this is required to be able to remember the current alternate settings of these interfaces - We restrict us here to have a constant number for all audio functions (which means this has to be the maximum number of AS interfaces an audio function has and a second audio function with less AS interfaces just wastes a few bytes) #define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 2 diff --git a/examples/device/cdc_uac2/src/uac2_app.c b/examples/device/cdc_uac2/src/uac2_app.c index 98659ea68..c57d98a1a 100644 --- a/examples/device/cdc_uac2/src/uac2_app.c +++ b/examples/device/cdc_uac2/src/uac2_app.c @@ -69,7 +69,7 @@ static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t { if (request->bRequest == AUDIO_CS_REQ_CUR) { - TU_LOG1("Clock get current freq %lu\r\n", current_sample_rate); + TU_LOG1("Clock get current freq %" PRIu32 "\r\n", current_sample_rate); audio_control_cur_4_t curf = { (int32_t) tu_htole32(current_sample_rate) }; return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &curf, sizeof(curf)); @@ -118,7 +118,7 @@ static bool tud_audio_clock_set_request(uint8_t rhport, audio_control_request_t current_sample_rate = (uint32_t) ((audio_control_cur_4_t const *)buf)->bCur; - TU_LOG1("Clock set current freq: %ld\r\n", current_sample_rate); + TU_LOG1("Clock set current freq: %" PRIu32 "\r\n", current_sample_rate); return true; } diff --git a/examples/device/dfu/Makefile b/examples/device/dfu/Makefile index b3f2cc588..52a24cdb0 100644 --- a/examples/device/dfu/Makefile +++ b/examples/device/dfu/Makefile @@ -1,4 +1,4 @@ -include ../../make.mk +include ../../build_system/make/make.mk INC += \ src \ @@ -11,4 +11,4 @@ EXAMPLE_SOURCE = \ SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) -include ../../rules.mk +include ../../build_system/make/rules.mk diff --git a/examples/device/dfu/skip.txt b/examples/device/dfu/skip.txt index 9ac346bad..9dde06c30 100644 --- a/examples/device/dfu/skip.txt +++ b/examples/device/dfu/skip.txt @@ -1,2 +1,3 @@ mcu:TM4C123 mcu:BCM2835 +family:espressif diff --git a/examples/device/dfu/src/main.c b/examples/device/dfu/src/main.c index 748e6a5c8..81fc0a62c 100644 --- a/examples/device/dfu/src/main.c +++ b/examples/device/dfu/src/main.c @@ -116,7 +116,7 @@ void tud_suspend_cb(bool remote_wakeup_en) // Invoked when usb bus is resumed void tud_resume_cb(void) { - blink_interval_ms = BLINK_MOUNTED; + blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ diff --git a/examples/device/dfu_runtime/Makefile b/examples/device/dfu_runtime/Makefile index da088ea6b..1b4d398cf 100644 --- a/examples/device/dfu_runtime/Makefile +++ b/examples/device/dfu_runtime/Makefile @@ -1,4 +1,4 @@ -include ../../make.mk +include ../../build_system/make/make.mk INC += \ src \ @@ -8,4 +8,4 @@ INC += \ EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) -include ../../rules.mk +include ../../build_system/make/rules.mk diff --git a/examples/device/dfu_runtime/src/main.c b/examples/device/dfu_runtime/src/main.c index 2ea39fb0f..170dde932 100644 --- a/examples/device/dfu_runtime/src/main.c +++ b/examples/device/dfu_runtime/src/main.c @@ -111,7 +111,7 @@ void tud_suspend_cb(bool remote_wakeup_en) // Invoked when usb bus is resumed void tud_resume_cb(void) { - blink_interval_ms = BLINK_MOUNTED; + blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } // Invoked on DFU_DETACH request to reboot to the bootloader diff --git a/examples/device/dynamic_configuration/Makefile b/examples/device/dynamic_configuration/Makefile index da088ea6b..1b4d398cf 100644 --- a/examples/device/dynamic_configuration/Makefile +++ b/examples/device/dynamic_configuration/Makefile @@ -1,4 +1,4 @@ -include ../../make.mk +include ../../build_system/make/make.mk INC += \ src \ @@ -8,4 +8,4 @@ INC += \ EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) -include ../../rules.mk +include ../../build_system/make/rules.mk diff --git a/examples/device/dynamic_configuration/skip.txt b/examples/device/dynamic_configuration/skip.txt index eadb6e74a..833fd072c 100644 --- a/examples/device/dynamic_configuration/skip.txt +++ b/examples/device/dynamic_configuration/skip.txt @@ -1 +1,2 @@ mcu:SAMD11 +family:espressif diff --git a/examples/device/dynamic_configuration/src/main.c b/examples/device/dynamic_configuration/src/main.c index 178d44e79..b6409c8e1 100644 --- a/examples/device/dynamic_configuration/src/main.c +++ b/examples/device/dynamic_configuration/src/main.c @@ -100,7 +100,7 @@ void tud_suspend_cb(bool remote_wakeup_en) // Invoked when usb bus is resumed void tud_resume_cb(void) { - blink_interval_ms = BLINK_MOUNTED; + blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } diff --git a/examples/device/hid_boot_interface/Makefile b/examples/device/hid_boot_interface/Makefile index b3f2cc588..52a24cdb0 100644 --- a/examples/device/hid_boot_interface/Makefile +++ b/examples/device/hid_boot_interface/Makefile @@ -1,4 +1,4 @@ -include ../../make.mk +include ../../build_system/make/make.mk INC += \ src \ @@ -11,4 +11,4 @@ EXAMPLE_SOURCE = \ SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) -include ../../rules.mk +include ../../build_system/make/rules.mk diff --git a/examples/device/hid_boot_interface/src/main.c b/examples/device/hid_boot_interface/src/main.c index 24ac3ae40..7ad5c53c2 100644 --- a/examples/device/hid_boot_interface/src/main.c +++ b/examples/device/hid_boot_interface/src/main.c @@ -102,7 +102,7 @@ void tud_suspend_cb(bool remote_wakeup_en) // Invoked when usb bus is resumed void tud_resume_cb(void) { - blink_interval_ms = BLINK_MOUNTED; + blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ diff --git a/examples/device/hid_composite/Makefile b/examples/device/hid_composite/Makefile index da088ea6b..1b4d398cf 100644 --- a/examples/device/hid_composite/Makefile +++ b/examples/device/hid_composite/Makefile @@ -1,4 +1,4 @@ -include ../../make.mk +include ../../build_system/make/make.mk INC += \ src \ @@ -8,4 +8,4 @@ INC += \ EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) -include ../../rules.mk +include ../../build_system/make/rules.mk diff --git a/examples/device/hid_composite/src/main.c b/examples/device/hid_composite/src/main.c index f04abbeb4..dcf13079f 100644 --- a/examples/device/hid_composite/src/main.c +++ b/examples/device/hid_composite/src/main.c @@ -101,7 +101,7 @@ void tud_suspend_cb(bool remote_wakeup_en) // Invoked when usb bus is resumed void tud_resume_cb(void) { - blink_interval_ms = BLINK_MOUNTED; + blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ diff --git a/examples/device/hid_composite_freertos/Makefile b/examples/device/hid_composite_freertos/Makefile index a892e7d1d..88d602393 100644 --- a/examples/device/hid_composite_freertos/Makefile +++ b/examples/device/hid_composite_freertos/Makefile @@ -1,9 +1,9 @@ DEPS_SUBMODULES += lib/FreeRTOS-Kernel -include ../../make.mk +include ../../build_system/make/make.mk FREERTOS_SRC = lib/FreeRTOS-Kernel -FREERTOS_PORTABLE_PATH= $(FREERTOS_SRC)/portable/$(if $(USE_IAR),IAR,GCC) +FREERTOS_PORTABLE_PATH= $(FREERTOS_SRC)/portable/$(if $(findstring iar,$(TOOLCHAIN)),IAR,GCC) INC += \ src \ @@ -44,4 +44,4 @@ CFLAGS_GCC += -Wno-error=cast-qual # FreeRTOS (lto + Os) linker issue LDFLAGS_GCC += -Wl,--undefined=vTaskSwitchContext -include ../../rules.mk +include ../../build_system/make/rules.mk diff --git a/examples/device/hid_composite_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h b/examples/device/hid_composite_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h index 69d638288..6cc7a6577 100644 --- a/examples/device/hid_composite_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h +++ b/examples/device/hid_composite_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h @@ -96,6 +96,7 @@ #define configUSE_TICK_HOOK 0 #define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning #define configCHECK_FOR_STACK_OVERFLOW 2 +#define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 @@ -130,23 +131,6 @@ #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 - #ifdef __RX__ /* Renesas RX series */ #define vSoftwareInterruptISR INT_Excep_ICU_SWINT diff --git a/examples/device/hid_composite_freertos/src/freertos_hook.c b/examples/device/hid_composite_freertos/src/freertos_hook.c index ab885947c..4920e3fae 100644 --- a/examples/device/hid_composite_freertos/src/freertos_hook.c +++ b/examples/device/hid_composite_freertos/src/freertos_hook.c @@ -99,9 +99,10 @@ void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, Stack void vApplicationSetupTimerInterrupt(void) { /* Enable CMT0 */ + unsigned short oldPRCR = SYSTEM.PRCR.WORD; SYSTEM.PRCR.WORD = (0xA5u<<8) | TU_BIT(1); MSTP(CMT0) = 0; - SYSTEM.PRCR.WORD = (0xA5u<<8); + SYSTEM.PRCR.WORD = (0xA5u<<8) | oldPRCR; CMT0.CMCNT = 0; CMT0.CMCOR = (unsigned short)(((configPERIPHERAL_CLOCK_HZ/configTICK_RATE_HZ)-1)/128); diff --git a/examples/device/hid_composite_freertos/src/main.c b/examples/device/hid_composite_freertos/src/main.c index 6aa08636c..2bd545bc2 100644 --- a/examples/device/hid_composite_freertos/src/main.c +++ b/examples/device/hid_composite_freertos/src/main.c @@ -31,7 +31,7 @@ #include "tusb.h" #include "usb_descriptors.h" -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF // ESP-IDF need "freertos/" prefix in include path. // CFG_TUSB_OS_INC_PATH should be defined accordingly. #include "freertos/FreeRTOS.h" @@ -113,14 +113,14 @@ int main(void) xTimerStart(blinky_tm, 0); // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 -#if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if !TUP_MCU_ESPRESSIF vTaskStartScheduler(); #endif return 0; } -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF void app_main(void) { main(); @@ -180,7 +180,14 @@ void tud_suspend_cb(bool remote_wakeup_en) // Invoked when usb bus is resumed void tud_resume_cb(void) { - xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_MOUNTED), 0); + if (tud_mounted()) + { + xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_MOUNTED), 0); + } + else + { + xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), 0); + } } //--------------------------------------------------------------------+ diff --git a/examples/device/hid_composite_freertos/src/tusb_config.h b/examples/device/hid_composite_freertos/src/tusb_config.h index 3ba9bf311..0689e0f23 100644 --- a/examples/device/hid_composite_freertos/src/tusb_config.h +++ b/examples/device/hid_composite_freertos/src/tusb_config.h @@ -59,7 +59,7 @@ #endif // Espressif IDF requires "freertos/" prefix in include path -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF #define CFG_TUSB_OS_INC_PATH freertos/ #endif diff --git a/examples/device/hid_generic_inout/Makefile b/examples/device/hid_generic_inout/Makefile index da088ea6b..1b4d398cf 100644 --- a/examples/device/hid_generic_inout/Makefile +++ b/examples/device/hid_generic_inout/Makefile @@ -1,4 +1,4 @@ -include ../../make.mk +include ../../build_system/make/make.mk INC += \ src \ @@ -8,4 +8,4 @@ INC += \ EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) -include ../../rules.mk +include ../../build_system/make/rules.mk diff --git a/examples/device/hid_generic_inout/src/main.c b/examples/device/hid_generic_inout/src/main.c index 71ae2148b..cfa9f6283 100644 --- a/examples/device/hid_generic_inout/src/main.c +++ b/examples/device/hid_generic_inout/src/main.c @@ -122,7 +122,7 @@ void tud_suspend_cb(bool remote_wakeup_en) // Invoked when usb bus is resumed void tud_resume_cb(void) { - blink_interval_ms = BLINK_MOUNTED; + blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ diff --git a/examples/device/hid_multiple_interface/Makefile b/examples/device/hid_multiple_interface/Makefile index da088ea6b..1b4d398cf 100644 --- a/examples/device/hid_multiple_interface/Makefile +++ b/examples/device/hid_multiple_interface/Makefile @@ -1,4 +1,4 @@ -include ../../make.mk +include ../../build_system/make/make.mk INC += \ src \ @@ -8,4 +8,4 @@ INC += \ EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) -include ../../rules.mk +include ../../build_system/make/rules.mk diff --git a/examples/device/hid_multiple_interface/src/main.c b/examples/device/hid_multiple_interface/src/main.c index 516c342fa..30b4ae055 100644 --- a/examples/device/hid_multiple_interface/src/main.c +++ b/examples/device/hid_multiple_interface/src/main.c @@ -105,7 +105,7 @@ void tud_suspend_cb(bool remote_wakeup_en) // Invoked when usb bus is resumed void tud_resume_cb(void) { - blink_interval_ms = BLINK_MOUNTED; + blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ diff --git a/examples/device/midi_test/Makefile b/examples/device/midi_test/Makefile index 2a3d854fb..7fa475da5 100644 --- a/examples/device/midi_test/Makefile +++ b/examples/device/midi_test/Makefile @@ -1,4 +1,4 @@ -include ../../make.mk +include ../../build_system/make/make.mk INC += \ src \ @@ -8,4 +8,4 @@ INC += \ EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) -include ../../rules.mk +include ../../build_system/make/rules.mk diff --git a/examples/device/midi_test/src/main.c b/examples/device/midi_test/src/main.c index 264566d4c..b1d51598f 100644 --- a/examples/device/midi_test/src/main.c +++ b/examples/device/midi_test/src/main.c @@ -105,7 +105,7 @@ void tud_suspend_cb(bool remote_wakeup_en) // Invoked when usb bus is resumed void tud_resume_cb(void) { - blink_interval_ms = BLINK_MOUNTED; + blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ diff --git a/examples/device/msc_dual_lun/Makefile b/examples/device/msc_dual_lun/Makefile index 2a3d854fb..7fa475da5 100644 --- a/examples/device/msc_dual_lun/Makefile +++ b/examples/device/msc_dual_lun/Makefile @@ -1,4 +1,4 @@ -include ../../make.mk +include ../../build_system/make/make.mk INC += \ src \ @@ -8,4 +8,4 @@ INC += \ EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) -include ../../rules.mk +include ../../build_system/make/rules.mk diff --git a/examples/device/msc_dual_lun/skip.txt b/examples/device/msc_dual_lun/skip.txt index 47e561cf0..a9e3a99b1 100644 --- a/examples/device/msc_dual_lun/skip.txt +++ b/examples/device/msc_dual_lun/skip.txt @@ -1,2 +1,3 @@ mcu:SAMD11 mcu:MKL25ZXX +family:espressif diff --git a/examples/device/msc_dual_lun/src/main.c b/examples/device/msc_dual_lun/src/main.c index 0aecb3ecb..aabd0bf8a 100644 --- a/examples/device/msc_dual_lun/src/main.c +++ b/examples/device/msc_dual_lun/src/main.c @@ -39,7 +39,7 @@ * - 1000 ms : device mounted * - 2500 ms : device is suspended */ -enum { +enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, @@ -50,8 +50,7 @@ static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; void led_blinking_task(void); /*------------- MAIN -------------*/ -int main(void) -{ +int main(void) { board_init(); // init device stack on configured roothub port @@ -61,8 +60,7 @@ int main(void) board_init_after_tusb(); } - while (1) - { + while (1) { tud_task(); // tinyusb device task led_blinking_task(); } @@ -73,42 +71,37 @@ int main(void) //--------------------------------------------------------------------+ // Invoked when device is mounted -void tud_mount_cb(void) -{ +void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted -void tud_umount_cb(void) -{ +void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus -void tud_suspend_cb(bool remote_wakeup_en) -{ +void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed -void tud_resume_cb(void) -{ - blink_interval_ms = BLINK_MOUNTED; +void tud_resume_cb(void) { + blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ -void led_blinking_task(void) -{ +void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms - if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time + if (board_millis() - start_ms < blink_interval_ms) return; // not enough time start_ms += blink_interval_ms; board_led_write(led_state); diff --git a/examples/device/net_lwip_webserver/CMakeLists.txt b/examples/device/net_lwip_webserver/CMakeLists.txt index a16b8bd71..c39fd32c5 100644 --- a/examples/device/net_lwip_webserver/CMakeLists.txt +++ b/examples/device/net_lwip_webserver/CMakeLists.txt @@ -74,6 +74,7 @@ target_sources(${PROJECT} PUBLIC ${LWIP}/src/netif/slipif.c ${LWIP}/src/apps/http/httpd.c ${LWIP}/src/apps/http/fs.c + ${LWIP}/src/apps/lwiperf/lwiperf.c ) # due to warnings from other net source, we need to prevent error from some of the warnings options diff --git a/examples/device/net_lwip_webserver/Makefile b/examples/device/net_lwip_webserver/Makefile index 90b429d00..141532466 100644 --- a/examples/device/net_lwip_webserver/Makefile +++ b/examples/device/net_lwip_webserver/Makefile @@ -1,6 +1,6 @@ DEPS_SUBMODULES += lib/lwip -include ../../make.mk +include ../../build_system/make/make.mk # suppress warning caused by lwip CFLAGS_GCC += \ @@ -63,8 +63,9 @@ SRC_C += \ lib/lwip/src/netif/slipif.c \ lib/lwip/src/apps/http/httpd.c \ lib/lwip/src/apps/http/fs.c \ + lib/lwip/src/apps/lwiperf/lwiperf.c \ lib/networking/dhserver.c \ lib/networking/dnserver.c \ lib/networking/rndis_reports.c -include ../../rules.mk +include ../../build_system/make/rules.mk diff --git a/examples/device/net_lwip_webserver/skip.txt b/examples/device/net_lwip_webserver/skip.txt index e3a726a2b..bb3ff7885 100644 --- a/examples/device/net_lwip_webserver/skip.txt +++ b/examples/device/net_lwip_webserver/skip.txt @@ -1,11 +1,14 @@ mcu:LPC11UXX mcu:LPC13XX +mcu:LPC15XX mcu:MSP430x5xx mcu:NUC121 mcu:SAMD11 mcu:STM32L0 +mcu:STM32F0 mcu:KINETIS_KL family:broadcom_64bit family:broadcom_32bit board:curiosity_nano board:frdm_kl25z +family:espressif diff --git a/examples/device/net_lwip_webserver/src/lwipopts.h b/examples/device/net_lwip_webserver/src/lwipopts.h index 336c9243d..41e8f0d67 100644 --- a/examples/device/net_lwip_webserver/src/lwipopts.h +++ b/examples/device/net_lwip_webserver/src/lwipopts.h @@ -48,8 +48,8 @@ #define LWIP_IP_ACCEPT_UDP_PORT(p) ((p) == PP_NTOHS(67)) #define TCP_MSS (1500 /*mtu*/ - 20 /*iphdr*/ - 20 /*tcphhr*/) -#define TCP_SND_BUF (2 * TCP_MSS) -#define TCP_WND (TCP_MSS) +#define TCP_SND_BUF (4 * TCP_MSS) +#define TCP_WND (4 * TCP_MSS) #define ETHARP_SUPPORT_STATIC_ENTRIES 1 @@ -59,7 +59,7 @@ #define LWIP_SINGLE_NETIF 1 -#define PBUF_POOL_SIZE 2 +#define PBUF_POOL_SIZE 4 #define HTTPD_USE_CUSTOM_FSDATA 0 diff --git a/examples/device/net_lwip_webserver/src/main.c b/examples/device/net_lwip_webserver/src/main.c index 7d98aacbc..791e09b4f 100644 --- a/examples/device/net_lwip_webserver/src/main.c +++ b/examples/device/net_lwip_webserver/src/main.c @@ -48,12 +48,17 @@ try changing the first byte of tud_network_mac_address[] below from 0x02 to 0x00 #include "dhserver.h" #include "dnserver.h" +#include "httpd.h" +#include "lwip/ethip6.h" #include "lwip/init.h" #include "lwip/timeouts.h" -#include "lwip/ethip6.h" -#include "httpd.h" -#define INIT_IP4(a,b,c,d) { PP_HTONL(LWIP_MAKEU32(a,b,c,d)) } +#ifdef INCLUDE_IPERF + #include "lwip/apps/lwiperf.h" +#endif + +#define INIT_IP4(a, b, c, d) \ + { PP_HTONL(LWIP_MAKEU32(a, b, c, d)) } /* lwip context */ static struct netif netif_data; @@ -64,44 +69,40 @@ static struct pbuf *received_frame; /* this is used by this code, ./class/net/net_driver.c, and usb_descriptors.c */ /* ideally speaking, this should be generated from the hardware's unique ID (if available) */ /* it is suggested that the first byte is 0x02 to indicate a link-local address */ -uint8_t tud_network_mac_address[6] = {0x02,0x02,0x84,0x6A,0x96,0x00}; +uint8_t tud_network_mac_address[6] = {0x02, 0x02, 0x84, 0x6A, 0x96, 0x00}; /* network parameters of this MCU */ -static const ip4_addr_t ipaddr = INIT_IP4(192, 168, 7, 1); +static const ip4_addr_t ipaddr = INIT_IP4(192, 168, 7, 1); static const ip4_addr_t netmask = INIT_IP4(255, 255, 255, 0); static const ip4_addr_t gateway = INIT_IP4(0, 0, 0, 0); /* database IP addresses that can be offered to the host; this must be in RAM to store assigned MAC addresses */ -static dhcp_entry_t entries[] = -{ - /* mac ip address lease time */ - { {0}, INIT_IP4(192, 168, 7, 2), 24 * 60 * 60 }, - { {0}, INIT_IP4(192, 168, 7, 3), 24 * 60 * 60 }, - { {0}, INIT_IP4(192, 168, 7, 4), 24 * 60 * 60 }, +static dhcp_entry_t entries[] = { + /* mac ip address lease time */ + {{0}, INIT_IP4(192, 168, 7, 2), 24 * 60 * 60}, + {{0}, INIT_IP4(192, 168, 7, 3), 24 * 60 * 60}, + {{0}, INIT_IP4(192, 168, 7, 4), 24 * 60 * 60}, }; -static const dhcp_config_t dhcp_config = -{ - .router = INIT_IP4(0, 0, 0, 0), /* router address (if any) */ - .port = 67, /* listen port */ - .dns = INIT_IP4(192, 168, 7, 1), /* dns server (if any) */ - "usb", /* dns suffix */ - TU_ARRAY_SIZE(entries), /* num entry */ - entries /* entries */ +static const dhcp_config_t dhcp_config = { + .router = INIT_IP4(0, 0, 0, 0), /* router address (if any) */ + .port = 67, /* listen port */ + .dns = INIT_IP4(192, 168, 7, 1), /* dns server (if any) */ + "usb", /* dns suffix */ + TU_ARRAY_SIZE(entries), /* num entry */ + entries /* entries */ }; -static err_t linkoutput_fn(struct netif *netif, struct pbuf *p) -{ - (void)netif; - for (;;) - { +static err_t linkoutput_fn(struct netif *netif, struct pbuf *p) { + (void) netif; + + for (;;) { /* if TinyUSB isn't ready, we must signal back to lwip that there is nothing we can do */ if (!tud_ready()) return ERR_USE; /* if the network driver can accept another packet, we make it happen */ - if (tud_network_can_xmit(p->tot_len)) - { + if (tud_network_can_xmit(p->tot_len)) { tud_network_xmit(p, 0 /* unused for this example */); return ERR_OK; } @@ -111,20 +112,17 @@ static err_t linkoutput_fn(struct netif *netif, struct pbuf *p) } } -static err_t ip4_output_fn(struct netif *netif, struct pbuf *p, const ip4_addr_t *addr) -{ +static err_t ip4_output_fn(struct netif *netif, struct pbuf *p, const ip4_addr_t *addr) { return etharp_output(netif, p, addr); } #if LWIP_IPV6 -static err_t ip6_output_fn(struct netif *netif, struct pbuf *p, const ip6_addr_t *addr) -{ +static err_t ip6_output_fn(struct netif *netif, struct pbuf *p, const ip6_addr_t *addr) { return ethip6_output(netif, p, addr); } #endif -static err_t netif_init_cb(struct netif *netif) -{ +static err_t netif_init_cb(struct netif *netif) { LWIP_ASSERT("netif != NULL", (netif != NULL)); netif->mtu = CFG_TUD_NET_MTU; netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP; @@ -139,8 +137,7 @@ static err_t netif_init_cb(struct netif *netif) return ERR_OK; } -static void init_lwip(void) -{ +static void init_lwip(void) { struct netif *netif = &netif_data; lwip_init(); @@ -158,28 +155,23 @@ static void init_lwip(void) } /* handle any DNS requests from dns-server */ -bool dns_query_proc(const char *name, ip4_addr_t *addr) -{ - if (0 == strcmp(name, "tiny.usb")) - { +bool dns_query_proc(const char *name, ip4_addr_t *addr) { + if (0 == strcmp(name, "tiny.usb")) { *addr = ipaddr; return true; } return false; } -bool tud_network_recv_cb(const uint8_t *src, uint16_t size) -{ +bool tud_network_recv_cb(const uint8_t *src, uint16_t size) { /* this shouldn't happen, but if we get another packet before parsing the previous, we must signal our inability to accept it */ if (received_frame) return false; - if (size) - { + if (size) { struct pbuf *p = pbuf_alloc(PBUF_RAW, size, PBUF_POOL); - if (p) - { + if (p) { /* pbuf_alloc() has already initialized struct; all we need to do is copy the data */ memcpy(p->payload, src, size); @@ -191,20 +183,17 @@ bool tud_network_recv_cb(const uint8_t *src, uint16_t size) return true; } -uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg) -{ - struct pbuf *p = (struct pbuf *)ref; +uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg) { + struct pbuf *p = (struct pbuf *) ref; - (void)arg; /* unused for this example */ + (void) arg; /* unused for this example */ return pbuf_copy_partial(p, dst, p->tot_len, 0); } -static void service_traffic(void) -{ +static void service_traffic(void) { /* handle any packet received by tud_network_recv_cb() */ - if (received_frame) - { + if (received_frame) { ethernet_input(received_frame, &netif_data); pbuf_free(received_frame); received_frame = NULL; @@ -214,18 +203,15 @@ static void service_traffic(void) sys_check_timeouts(); } -void tud_network_init_cb(void) -{ +void tud_network_init_cb(void) { /* if the network is re-initializing and we have a leftover packet, we must do a cleanup */ - if (received_frame) - { + if (received_frame) { pbuf_free(received_frame); received_frame = NULL; } } -int main(void) -{ +int main(void) { /* initialize TinyUSB */ board_init(); @@ -243,8 +229,12 @@ int main(void) while (dnserv_init(IP_ADDR_ANY, 53, dns_query_proc) != ERR_OK); httpd_init(); - while (1) - { +#ifdef INCLUDE_IPERF + // test with: iperf -c 192.168.7.1 -e -i 1 -M 5000 -l 8192 -r + lwiperf_start_tcp_server_default(NULL, NULL); +#endif + + while (1) { tud_task(); service_traffic(); } @@ -253,17 +243,14 @@ int main(void) } /* lwip has provision for using a mutex, when applicable */ -sys_prot_t sys_arch_protect(void) -{ +sys_prot_t sys_arch_protect(void) { return 0; } -void sys_arch_unprotect(sys_prot_t pval) -{ - (void)pval; +void sys_arch_unprotect(sys_prot_t pval) { + (void) pval; } /* lwip needs a millisecond time source, and the TinyUSB board support code has one available */ -uint32_t sys_now(void) -{ +uint32_t sys_now(void) { return board_millis(); } diff --git a/examples/device/net_lwip_webserver/src/tusb_config.h b/examples/device/net_lwip_webserver/src/tusb_config.h index fe72ecdfe..d3e094517 100644 --- a/examples/device/net_lwip_webserver/src/tusb_config.h +++ b/examples/device/net_lwip_webserver/src/tusb_config.h @@ -27,21 +27,23 @@ #define _TUSB_CONFIG_H_ #ifdef __cplusplus - extern "C" { +extern "C" { #endif +#include "lwipopts.h" + //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT -#define BOARD_TUD_RHPORT 0 + #define BOARD_TUD_RHPORT 0 #endif // RHPort max operational speed can defined by board.mk #ifndef BOARD_TUD_MAX_SPEED -#define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED + #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED #endif //-------------------------------------------------------------------- @@ -50,22 +52,22 @@ // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU -#error CFG_TUSB_MCU must be defined + #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS -#define CFG_TUSB_OS OPT_OS_NONE + #define CFG_TUSB_OS OPT_OS_NONE #endif #ifndef CFG_TUSB_DEBUG -#define CFG_TUSB_DEBUG 0 + #define CFG_TUSB_DEBUG 0 #endif // Enable Device stack -#define CFG_TUD_ENABLED 1 +#define CFG_TUD_ENABLED 1 // Default is max speed that hardware controller could support with on-chip PHY -#define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED +#define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put @@ -75,11 +77,45 @@ * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) */ #ifndef CFG_TUSB_MEM_SECTION -#define CFG_TUSB_MEM_SECTION + #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN -#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) + #define CFG_TUSB_MEM_ALIGN __attribute__((aligned(4))) +#endif + +// Use different configurations to test all net devices (also due to resource limitations) +#if TU_CHECK_MCU(OPT_MCU_LPC15XX, OPT_MCU_LPC40XX, OPT_MCU_LPC51UXX, OPT_MCU_LPC54) + #define USE_ECM 1 +#elif TU_CHECK_MCU(OPT_MCU_SAMD21, OPT_MCU_SAML21, OPT_MCU_SAML22) + #define USE_ECM 1 +#elif TU_CHECK_MCU(OPT_MCU_STM32F0, OPT_MCU_STM32F1) + #define USE_ECM 1 +#else + #define USE_ECM 0 + #define INCLUDE_IPERF +#endif + +//-------------------------------------------------------------------- +// NCM CLASS CONFIGURATION, SEE "ncm.h" FOR PERFORMANCE TUNING +//-------------------------------------------------------------------- + +// Must be >> MTU +// Can be set to 2048 without impact +#define CFG_TUD_NCM_IN_NTB_MAX_SIZE (2 * TCP_MSS + 100) + +// Must be >> MTU +// Can be set to smaller values if wNtbOutMaxDatagrams==1 +#define CFG_TUD_NCM_OUT_NTB_MAX_SIZE (2 * TCP_MSS + 100) + +// Number of NCM transfer blocks for reception side +#ifndef CFG_TUD_NCM_OUT_NTB_N + #define CFG_TUD_NCM_OUT_NTB_N 1 +#endif + +// Number of NCM transfer blocks for transmission side +#ifndef CFG_TUD_NCM_IN_NTB_N + #define CFG_TUD_NCM_IN_NTB_N 1 #endif //-------------------------------------------------------------------- @@ -87,18 +123,18 @@ //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE -#define CFG_TUD_ENDPOINT0_SIZE 64 + #define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// // Network class has 2 drivers: ECM/RNDIS and NCM. // Only one of the drivers can be enabled -#define CFG_TUD_ECM_RNDIS 1 -#define CFG_TUD_NCM (1-CFG_TUD_ECM_RNDIS) +#define CFG_TUD_ECM_RNDIS USE_ECM +#define CFG_TUD_NCM (1 - CFG_TUD_ECM_RNDIS) #ifdef __cplusplus - } +} #endif #endif /* _TUSB_CONFIG_H_ */ diff --git a/examples/device/uac2_headset/Makefile b/examples/device/uac2_headset/Makefile index 2a3d854fb..7fa475da5 100644 --- a/examples/device/uac2_headset/Makefile +++ b/examples/device/uac2_headset/Makefile @@ -1,4 +1,4 @@ -include ../../make.mk +include ../../build_system/make/make.mk INC += \ src \ @@ -8,4 +8,4 @@ INC += \ EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) -include ../../rules.mk +include ../../build_system/make/rules.mk diff --git a/examples/device/uac2_headset/skip.txt b/examples/device/uac2_headset/skip.txt index 70d8e8838..a2a76af0e 100644 --- a/examples/device/uac2_headset/skip.txt +++ b/examples/device/uac2_headset/skip.txt @@ -5,3 +5,4 @@ mcu:SAMD11 mcu:SAME5X mcu:SAMG board:stm32l052dap52 +family:espressif diff --git a/examples/device/uac2_headset/src/main.c b/examples/device/uac2_headset/src/main.c index f6c23bff5..0ea6e7025 100644 --- a/examples/device/uac2_headset/src/main.c +++ b/examples/device/uac2_headset/src/main.c @@ -35,11 +35,7 @@ //--------------------------------------------------------------------+ // List of supported sample rates -#if defined(__RX__) - const uint32_t sample_rates[] = {44100, 48000}; -#else - const uint32_t sample_rates[] = {44100, 48000, 88200, 96000}; -#endif +const uint32_t sample_rates[] = {44100, 48000}; uint32_t current_sample_rate = 44100; @@ -96,6 +92,7 @@ uint8_t current_resolution; void led_blinking_task(void); void audio_task(void); +void audio_control_task(void); /*------------- MAIN -------------*/ int main(void) @@ -115,6 +112,7 @@ int main(void) { tud_task(); // TinyUSB device task audio_task(); + audio_control_task(); led_blinking_task(); } } @@ -147,7 +145,7 @@ void tud_suspend_cb(bool remote_wakeup_en) // Invoked when usb bus is resumed void tud_resume_cb(void) { - blink_interval_ms = BLINK_MOUNTED; + blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } // Helper for clock get requests @@ -159,7 +157,7 @@ static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t { if (request->bRequest == AUDIO_CS_REQ_CUR) { - TU_LOG1("Clock get current freq %lu\r\n", current_sample_rate); + TU_LOG1("Clock get current freq %" PRIu32 "\r\n", current_sample_rate); audio_control_cur_4_t curf = { (int32_t) tu_htole32(current_sample_rate) }; return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &curf, sizeof(curf)); @@ -208,7 +206,7 @@ static bool tud_audio_clock_set_request(uint8_t rhport, audio_control_request_t current_sample_rate = (uint32_t) ((audio_control_cur_4_t const *)buf)->bCur; - TU_LOG1("Clock set current freq: %ld\r\n", current_sample_rate); + TU_LOG1("Clock set current freq: %" PRIu32 "\r\n", current_sample_rate); return true; } @@ -428,6 +426,45 @@ void audio_task(void) } } +void audio_control_task(void) +{ + // Press on-board button to control volume + // Open host volume control, volume should switch between 10% and 100% + + // Poll every 50ms + const uint32_t interval_ms = 50; + static uint32_t start_ms = 0; + static uint32_t btn_prev = 0; + + if ( board_millis() - start_ms < interval_ms) return; // not enough time + start_ms += interval_ms; + + uint32_t btn = board_button_read(); + + if (!btn_prev && btn) + { + // Adjust volume between 0dB (100%) and -30dB (10%) + for (int i = 0; i < CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1; i++) + { + volume[i] = volume[i] == 0 ? -VOLUME_CTRL_30_DB : 0; + } + + // 6.1 Interrupt Data Message + const audio_interrupt_data_t data = { + .bInfo = 0, // Class-specific interrupt, originated from an interface + .bAttribute = AUDIO_CS_REQ_CUR, // Caused by current settings + .wValue_cn_or_mcn = 0, // CH0: master volume + .wValue_cs = AUDIO_FU_CTRL_VOLUME, // Volume change + .wIndex_ep_or_int = 0, // From the interface itself + .wIndex_entity_id = UAC2_ENTITY_SPK_FEATURE_UNIT, // From feature unit + }; + + tud_audio_int_write(&data); + } + + btn_prev = btn; +} + //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ diff --git a/examples/device/uac2_headset/src/tusb_config.h b/examples/device/uac2_headset/src/tusb_config.h index 1a3e23e95..328e35f52 100644 --- a/examples/device/uac2_headset/src/tusb_config.h +++ b/examples/device/uac2_headset/src/tusb_config.h @@ -105,17 +105,18 @@ extern "C" { // AUDIO CLASS DRIVER CONFIGURATION //-------------------------------------------------------------------- +// Allow volume controlled by on-baord button +#define CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP 1 + #define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_HEADSET_STEREO_DESC_LEN // How many formats are used, need to adjust USB descriptor if changed #define CFG_TUD_AUDIO_FUNC_1_N_FORMATS 2 // Audio format type I specifications -#if defined(__RX__) -#define CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE 48000 // 16bit/48kHz is the best quality for Renesas RX -#else -#define CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE 96000 // 24bit/96kHz is the best quality for full-speed, high-speed is needed beyond this -#endif +/* 24bit/48kHz is the best quality for headset or 24bit/96kHz for 2ch speaker, + high-speed is needed beyond this */ +#define CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE 48000 #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 1 #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX 2 @@ -151,11 +152,11 @@ extern "C" { // EP and buffer size - for isochronous EP´s, the buffer and EP size are equal (different sizes would not make sense) #define CFG_TUD_AUDIO_ENABLE_EP_OUT 1 -#define CFG_TUD_AUDIO_UNC_1_FORMAT_1_EP_SZ_OUT TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX) -#define CFG_TUD_AUDIO_UNC_1_FORMAT_2_EP_SZ_OUT TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX) +#define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_OUT TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX) +#define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_OUT TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX) -#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ TU_MAX(CFG_TUD_AUDIO_UNC_1_FORMAT_1_EP_SZ_OUT, CFG_TUD_AUDIO_UNC_1_FORMAT_2_EP_SZ_OUT)*2 -#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX TU_MAX(CFG_TUD_AUDIO_UNC_1_FORMAT_1_EP_SZ_OUT, CFG_TUD_AUDIO_UNC_1_FORMAT_2_EP_SZ_OUT) // Maximum EP IN size for all AS alternate settings used +#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ TU_MAX(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_OUT, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_OUT)*2 +#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX TU_MAX(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_OUT, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_OUT) // Maximum EP IN size for all AS alternate settings used // Number of Standard AS Interface Descriptors (4.9.1) defined per audio function - this is required to be able to remember the current alternate settings of these interfaces - We restrict us here to have a constant number for all audio functions (which means this has to be the maximum number of AS interfaces an audio function has and a second audio function with less AS interfaces just wastes a few bytes) #define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 2 diff --git a/examples/device/uac2_headset/src/usb_descriptors.c b/examples/device/uac2_headset/src/usb_descriptors.c index 6d1e6a23f..ff4dc2acc 100644 --- a/examples/device/uac2_headset/src/usb_descriptors.c +++ b/examples/device/uac2_headset/src/usb_descriptors.c @@ -82,27 +82,32 @@ uint8_t const * tud_descriptor_device_cb(void) // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... #define EPNUM_AUDIO_IN 0x03 #define EPNUM_AUDIO_OUT 0x03 + #define EPNUM_AUDIO_INT 0x01 #elif CFG_TUSB_MCU == OPT_MCU_NRF5X // ISO endpoints for NRF5x are fixed to 0x08 (0x88) #define EPNUM_AUDIO_IN 0x08 #define EPNUM_AUDIO_OUT 0x08 + #define EPNUM_AUDIO_INT 0x01 #elif CFG_TUSB_MCU == OPT_MCU_SAMG || CFG_TUSB_MCU == OPT_MCU_SAMX7X // SAMG & SAME70 don't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_AUDIO_IN 0x01 #define EPNUM_AUDIO_OUT 0x02 + #define EPNUM_AUDIO_INT 0x03 #elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X // FT9XX doesn't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_AUDIO_IN 0x01 #define EPNUM_AUDIO_OUT 0x02 + #define EPNUM_AUDIO_INT 0x03 #else #define EPNUM_AUDIO_IN 0x01 #define EPNUM_AUDIO_OUT 0x01 + #define EPNUM_AUDIO_INT 0x02 #endif uint8_t const desc_configuration[] = @@ -111,7 +116,7 @@ uint8_t const desc_configuration[] = TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // Interface number, string index, EP Out & EP In address, EP size - TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR(2, EPNUM_AUDIO_OUT, EPNUM_AUDIO_IN | 0x80) + TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR(2, EPNUM_AUDIO_OUT, EPNUM_AUDIO_IN | 0x80, EPNUM_AUDIO_INT | 0x80) }; // Invoked when received GET CONFIGURATION DESCRIPTOR diff --git a/examples/device/uac2_headset/src/usb_descriptors.h b/examples/device/uac2_headset/src/usb_descriptors.h index d7e170162..da0da83e8 100644 --- a/examples/device/uac2_headset/src/usb_descriptors.h +++ b/examples/device/uac2_headset/src/usb_descriptors.h @@ -55,6 +55,7 @@ enum + TUD_AUDIO_DESC_OUTPUT_TERM_LEN\ + TUD_AUDIO_DESC_INPUT_TERM_LEN\ + TUD_AUDIO_DESC_OUTPUT_TERM_LEN\ + + TUD_AUDIO_DESC_STD_AC_INT_EP_LEN\ /* Interface 1, Alternate 0 */\ + TUD_AUDIO_DESC_STD_AS_INT_LEN\ /* Interface 1, Alternate 1 */\ @@ -84,11 +85,11 @@ enum + TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN\ + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN) -#define TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR(_stridx, _epout, _epin) \ +#define TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR(_stridx, _epout, _epin, _epint) \ /* Standard Interface Association Descriptor (IAD) */\ TUD_AUDIO_DESC_IAD(/*_firstitf*/ ITF_NUM_AUDIO_CONTROL, /*_nitfs*/ ITF_NUM_TOTAL, /*_stridx*/ 0x00),\ /* Standard AC Interface Descriptor(4.7.1) */\ - TUD_AUDIO_DESC_STD_AC(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ + TUD_AUDIO_DESC_STD_AC(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_nEPs*/ 0x01, /*_stridx*/ _stridx),\ /* Class-Specific AC Interface Header Descriptor(4.7.2) */\ TUD_AUDIO_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO_FUNC_HEADSET, /*_totallen*/ TUD_AUDIO_DESC_CLK_SRC_LEN+TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+TUD_AUDIO_DESC_OUTPUT_TERM_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+TUD_AUDIO_DESC_OUTPUT_TERM_LEN, /*_ctrl*/ AUDIO_CS_AS_INTERFACE_CTRL_LATENCY_POS),\ /* Clock Source Descriptor(4.7.2.1) */\ @@ -103,6 +104,8 @@ enum TUD_AUDIO_DESC_INPUT_TERM(/*_termid*/ UAC2_ENTITY_MIC_INPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ 0x00, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_nchannelslogical*/ 0x01, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO_CTRL_R << AUDIO_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00),\ /* Output Terminal Descriptor(4.7.2.5) */\ TUD_AUDIO_DESC_OUTPUT_TERM(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_srcid*/ UAC2_ENTITY_MIC_INPUT_TERMINAL, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\ + /* Standard AC Interrupt Endpoint Descriptor(4.8.2.1) */\ + TUD_AUDIO_DESC_STD_AC_INT_EP(/*_ep*/ _epint, /*_interval*/ 0x01), \ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */\ TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_SPK), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x05),\ @@ -114,7 +117,7 @@ enum /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_RX),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ADAPTIVE | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX), /*_interval*/ 0x01),\ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ADAPTIVE | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX), /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001),\ /* Interface 1, Alternate 2 - alternate interface for data streaming */\ @@ -124,7 +127,7 @@ enum /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_RX),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ADAPTIVE | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX), /*_interval*/ 0x01),\ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ADAPTIVE | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX), /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001),\ /* Standard AS Interface Descriptor(4.9.1) */\ @@ -138,7 +141,7 @@ enum /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_TX),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX), /*_interval*/ 0x01),\ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX), /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000),\ /* Interface 2, Alternate 2 - alternate interface for data streaming */\ @@ -148,7 +151,7 @@ enum /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_TX),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX), /*_interval*/ 0x01),\ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX), /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000) diff --git a/examples/device/usbtmc/Makefile b/examples/device/usbtmc/Makefile index da088ea6b..1b4d398cf 100644 --- a/examples/device/usbtmc/Makefile +++ b/examples/device/usbtmc/Makefile @@ -1,4 +1,4 @@ -include ../../make.mk +include ../../build_system/make/make.mk INC += \ src \ @@ -8,4 +8,4 @@ INC += \ EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) -include ../../rules.mk +include ../../build_system/make/rules.mk diff --git a/examples/device/usbtmc/skip.txt b/examples/device/usbtmc/skip.txt index a43106cf0..ccff857ac 100644 --- a/examples/device/usbtmc/skip.txt +++ b/examples/device/usbtmc/skip.txt @@ -1 +1,2 @@ mcu:BCM2835 +family:espressif diff --git a/examples/device/usbtmc/src/main.c b/examples/device/usbtmc/src/main.c index 306175d4a..9d8f0783d 100644 --- a/examples/device/usbtmc/src/main.c +++ b/examples/device/usbtmc/src/main.c @@ -97,7 +97,7 @@ void tud_suspend_cb(bool remote_wakeup_en) // Invoked when usb bus is resumed void tud_resume_cb(void) { - blink_interval_ms = BLINK_MOUNTED; + blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ diff --git a/examples/device/video_capture/Makefile b/examples/device/video_capture/Makefile index 90d174c32..d698a848d 100644 --- a/examples/device/video_capture/Makefile +++ b/examples/device/video_capture/Makefile @@ -1,4 +1,4 @@ -include ../../make.mk +include ../../build_system/make/make.mk ifeq ($(DISABLE_MJPEG),1) CFLAGS += -DCFG_EXAMPLE_VIDEO_DISABLE_MJPEG @@ -15,4 +15,4 @@ INC += \ EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) -include ../../rules.mk +include ../../build_system/make/rules.mk diff --git a/examples/device/video_capture/src/CMakeLists.txt b/examples/device/video_capture/src/CMakeLists.txt new file mode 100644 index 000000000..cef2b46ee --- /dev/null +++ b/examples/device/video_capture/src/CMakeLists.txt @@ -0,0 +1,4 @@ +# This file is for ESP-IDF only +idf_component_register(SRCS "main.c" "usb_descriptors.c" + INCLUDE_DIRS "." + REQUIRES boards tinyusb_src) diff --git a/examples/device/video_capture/src/images.h b/examples/device/video_capture/src/images.h index 0398428b3..ac372cb16 100644 --- a/examples/device/video_capture/src/images.h +++ b/examples/device/video_capture/src/images.h @@ -1,4 +1,5 @@ -#if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPG) +#if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) +// uncopmressed frame static const unsigned char frame_buffer[128 * (96 + 1) * 2] = { /* 0 */ 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, @@ -1650,8 +1651,10 @@ static const unsigned char frame_buffer[128 * (96 + 1) * 2] = { 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, }; + #else +// mpeg compressed data (not CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) #define color_bar_0_jpg_len 511 #define color_bar_1_jpg_len 512 #define color_bar_2_jpg_len 511 diff --git a/examples/device/video_capture/src/main.c b/examples/device/video_capture/src/main.c index 0c0b065d1..ddb51e03a 100644 --- a/examples/device/video_capture/src/main.c +++ b/examples/device/video_capture/src/main.c @@ -40,7 +40,7 @@ * - 1000 ms : device mounted * - 2500 ms : device is suspended */ -enum { +enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, @@ -48,14 +48,25 @@ enum { static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; -void led_blinking_task(void); -void video_task(void); +void led_blinking_task(void* param); +void usb_device_task(void *param); +void video_task(void* param); -/*------------- MAIN -------------*/ -int main(void) -{ +#if CFG_TUSB_OS == OPT_OS_FREERTOS +void freertos_init_task(void); +#endif + + +//--------------------------------------------------------------------+ +// Main +//--------------------------------------------------------------------+ +int main(void) { board_init(); + // If using FreeRTOS: create blinky, tinyusb device, video task +#if CFG_TUSB_OS == OPT_OS_FREERTOS + freertos_init_task(); +#else // init device stack on configured roothub port tud_init(BOARD_TUD_RHPORT); @@ -63,13 +74,12 @@ int main(void) board_init_after_tusb(); } - while (1) - { + while (1) { tud_task(); // tinyusb device task - led_blinking_task(); - - video_task(); + led_blinking_task(NULL); + video_task(NULL); } +#endif } //--------------------------------------------------------------------+ @@ -77,33 +87,28 @@ int main(void) //--------------------------------------------------------------------+ // Invoked when device is mounted -void tud_mount_cb(void) -{ +void tud_mount_cb(void) { blink_interval_ms = BLINK_MOUNTED; } // Invoked when device is unmounted -void tud_umount_cb(void) -{ +void tud_umount_cb(void) { blink_interval_ms = BLINK_NOT_MOUNTED; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus -void tud_suspend_cb(bool remote_wakeup_en) -{ +void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; blink_interval_ms = BLINK_SUSPENDED; } // Invoked when usb bus is resumed -void tud_resume_cb(void) -{ - blink_interval_ms = BLINK_MOUNTED; +void tud_resume_cb(void) { + blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } - //--------------------------------------------------------------------+ // USB Video //--------------------------------------------------------------------+ @@ -111,11 +116,12 @@ static unsigned frame_num = 0; static unsigned tx_busy = 0; static unsigned interval_ms = 1000 / FRAME_RATE; -/* YUY2 frame buffer */ #ifdef CFG_EXAMPLE_VIDEO_READONLY +// For mcus that does not have enough SRAM for frame buffer, we use fixed frame data. +// To further reduce the size, we use MJPEG format instead of YUY2. #include "images.h" -# if !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPG) +#if !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) static struct { uint32_t size; uint8_t const *buffer; @@ -129,29 +135,30 @@ static struct { {color_bar_6_jpg_len, color_bar_6_jpg}, {color_bar_7_jpg_len, color_bar_7_jpg}, }; -# endif +#endif #else + +// YUY2 frame buffer static uint8_t frame_buffer[FRAME_WIDTH * FRAME_HEIGHT * 16 / 8]; -static void fill_color_bar(uint8_t *buffer, unsigned start_position) -{ - /* EBU color bars - * See also https://stackoverflow.com/questions/6939422 */ + +static void fill_color_bar(uint8_t* buffer, unsigned start_position) { + /* EBU color bars: https://stackoverflow.com/questions/6939422 */ static uint8_t const bar_color[8][4] = { - /* Y, U, Y, V */ - { 235, 128, 235, 128}, /* 100% White */ - { 219, 16, 219, 138}, /* Yellow */ - { 188, 154, 188, 16}, /* Cyan */ - { 173, 42, 173, 26}, /* Green */ - { 78, 214, 78, 230}, /* Magenta */ - { 63, 102, 63, 240}, /* Red */ - { 32, 240, 32, 118}, /* Blue */ - { 16, 128, 16, 128}, /* Black */ + /* Y, U, Y, V */ + { 235, 128, 235, 128}, /* 100% White */ + { 219, 16, 219, 138}, /* Yellow */ + { 188, 154, 188, 16}, /* Cyan */ + { 173, 42, 173, 26}, /* Green */ + { 78, 214, 78, 230}, /* Magenta */ + { 63, 102, 63, 240}, /* Red */ + { 32, 240, 32, 118}, /* Blue */ + { 16, 128, 16, 128}, /* Black */ }; - uint8_t *p; + uint8_t* p; /* Generate the 1st line */ - uint8_t *end = &buffer[FRAME_WIDTH * 2]; + uint8_t* end = &buffer[FRAME_WIDTH * 2]; unsigned idx = (FRAME_WIDTH / 2 - 1) - (start_position % (FRAME_WIDTH / 2)); p = &buffer[idx * 4]; for (unsigned i = 0; i < 8; ++i) { @@ -163,6 +170,7 @@ static void fill_color_bar(uint8_t *buffer, unsigned start_position) } } } + /* Duplicate the 1st line to the others */ p = &buffer[FRAME_WIDTH * 2]; for (unsigned i = 1; i < FRAME_HEIGHT; ++i) { @@ -170,32 +178,33 @@ static void fill_color_bar(uint8_t *buffer, unsigned start_position) p += FRAME_WIDTH * 2; } } + #endif -void video_task(void) -{ +void video_send_frame(void) { static unsigned start_ms = 0; static unsigned already_sent = 0; if (!tud_video_n_streaming(0, 0)) { - already_sent = 0; - frame_num = 0; + already_sent = 0; + frame_num = 0; return; } if (!already_sent) { already_sent = 1; + tx_busy = 1; start_ms = board_millis(); #ifdef CFG_EXAMPLE_VIDEO_READONLY -# if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPG) + #if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)&frame_buffer[(frame_num % (FRAME_WIDTH / 2)) * 4], FRAME_WIDTH * FRAME_HEIGHT * 16/8); -# else + #else tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)frames[frame_num % 8].buffer, frames[frame_num % 8].size); -# endif + #endif #else fill_color_bar(frame_buffer, frame_num); - tud_video_n_frame_xfer(0, 0, (void*)frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16/8); + tud_video_n_frame_xfer(0, 0, (void*) frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16 / 8); #endif } @@ -203,49 +212,140 @@ void video_task(void) if (cur - start_ms < interval_ms) return; // not enough time if (tx_busy) return; start_ms += interval_ms; + tx_busy = 1; #ifdef CFG_EXAMPLE_VIDEO_READONLY -# if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPG) + #if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)&frame_buffer[(frame_num % (FRAME_WIDTH / 2)) * 4], FRAME_WIDTH * FRAME_HEIGHT * 16/8); -# else + #else tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)frames[frame_num % 8].buffer, frames[frame_num % 8].size); -# endif + #endif #else fill_color_bar(frame_buffer, frame_num); - tud_video_n_frame_xfer(0, 0, (void*)frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16/8); + tud_video_n_frame_xfer(0, 0, (void*) frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16 / 8); #endif } -void tud_video_frame_xfer_complete_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) -{ - (void)ctl_idx; (void)stm_idx; + +void video_task(void* param) { + (void) param; + + while(1) { + video_send_frame(); + + #if CFG_TUSB_OS == OPT_OS_FREERTOS + vTaskDelay(interval_ms / portTICK_PERIOD_MS); + #else + return; + #endif + } +} + +void tud_video_frame_xfer_complete_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) { + (void) ctl_idx; + (void) stm_idx; tx_busy = 0; /* flip buffer */ ++frame_num; } int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, - video_probe_and_commit_control_t const *parameters) -{ - (void)ctl_idx; (void)stm_idx; + video_probe_and_commit_control_t const* parameters) { + (void) ctl_idx; + (void) stm_idx; /* convert unit to ms from 100 ns */ interval_ms = parameters->dwFrameInterval / 10000; return VIDEO_ERROR_NONE; } //--------------------------------------------------------------------+ -// BLINKING TASK +// Blinking Task //--------------------------------------------------------------------+ -void led_blinking_task(void) -{ +void led_blinking_task(void* param) { + (void) param; static uint32_t start_ms = 0; static bool led_state = false; - // Blink every interval ms - if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time - start_ms += blink_interval_ms; + while (1) { + #if CFG_TUSB_OS == OPT_OS_FREERTOS + vTaskDelay(blink_interval_ms / portTICK_PERIOD_MS); + #else + if (board_millis() - start_ms < blink_interval_ms) return; // not enough time + #endif - board_led_write(led_state); - led_state = 1 - led_state; // toggle + start_ms += blink_interval_ms; + board_led_write(led_state); + led_state = 1 - led_state; // toggle + } } + +//--------------------------------------------------------------------+ +// FreeRTOS +//--------------------------------------------------------------------+ +#if CFG_TUSB_OS == OPT_OS_FREERTOS + +#define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE +#define VIDEO_STACK_SIZE (configMINIMAL_STACK_SIZE*4) + +#if TUP_MCU_ESPRESSIF + #define USBD_STACK_SIZE 4096 + int main(void); + void app_main(void) { + main(); + } +#else + // Increase stack size when debug log is enabled + #define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) +#endif + +// static task +#if configSUPPORT_STATIC_ALLOCATION +StackType_t blinky_stack[BLINKY_STACK_SIZE]; +StaticTask_t blinky_taskdef; + +StackType_t usb_device_stack[USBD_STACK_SIZE]; +StaticTask_t usb_device_taskdef; + +StackType_t video_stack[VIDEO_STACK_SIZE]; +StaticTask_t video_taskdef; +#endif + +// USB Device Driver task +// This top level thread process all usb events and invoke callbacks +void usb_device_task(void *param) { + (void) param; + + // init device stack on configured roothub port + // This should be called after scheduler/kernel is started. + // Otherwise, it could cause kernel issue since USB IRQ handler does use RTOS queue API. + tud_init(BOARD_TUD_RHPORT); + + if (board_init_after_tusb) { + board_init_after_tusb(); + } + + // RTOS forever loop + while (1) { + // put this thread to waiting state until there is new events + tud_task(); + } +} + +void freertos_init_task(void) { + #if configSUPPORT_STATIC_ALLOCATION + xTaskCreateStatic(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, blinky_stack, &blinky_taskdef); + xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef); + xTaskCreateStatic(video_task, "cdc", VIDEO_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, video_stack, &video_taskdef); + #else + xTaskCreate(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, NULL); + xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL); + xTaskCreate(video_task, "video", VIDEO_STACK_SZIE, NULL, configMAX_PRIORITIES - 2, NULL); + #endif + + // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 + #if !TUP_MCU_ESPRESSIF + vTaskStartScheduler(); + #endif +} +#endif diff --git a/examples/device/video_capture/src/tusb_config.h b/examples/device/video_capture/src/tusb_config.h index 274bf2b9c..21483a2da 100644 --- a/examples/device/video_capture/src/tusb_config.h +++ b/examples/device/video_capture/src/tusb_config.h @@ -57,6 +57,11 @@ #define CFG_TUSB_OS OPT_OS_NONE #endif +// Espressif IDF requires "freertos/" prefix in include path +#if TUP_MCU_ESPRESSIF +#define CFG_TUSB_OS_INC_PATH freertos/ +#endif + #ifndef CFG_TUSB_DEBUG #define CFG_TUSB_DEBUG 0 #endif @@ -97,11 +102,14 @@ // The number of video streaming interfaces #define CFG_TUD_VIDEO_STREAMING 1 -// video streaming endpoint size +// video streaming endpoint buffer size #define CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE 256 // use bulk endpoint for streaming interface -#define CFG_TUD_VIDEO_STREAMING_BULK 0 +#define CFG_TUD_VIDEO_STREAMING_BULK 1 + +//#define CFG_EXAMPLE_VIDEO_READONLY +//#define CFG_EXAMPLE_VIDEO_DISABLE_MJPEG #ifdef __cplusplus } diff --git a/examples/device/video_capture/src/usb_descriptors.c b/examples/device/video_capture/src/usb_descriptors.c index 292d86cd9..5011bee18 100644 --- a/examples/device/video_capture/src/usb_descriptors.c +++ b/examples/device/video_capture/src/usb_descriptors.c @@ -37,14 +37,36 @@ #define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ _PID_MAP(MIDI, 3) | _PID_MAP(AUDIO, 4) | _PID_MAP(VIDEO, 5) | _PID_MAP(VENDOR, 6) ) +#define USB_VID 0xCafe +#define USB_BCD 0x0200 + +// String Descriptor Index +enum { + STRID_LANGID = 0, + STRID_MANUFACTURER, + STRID_PRODUCT, + STRID_SERIAL, + STRID_UVC_CONTROL, + STRID_UVC_STREAMING, +}; + +// array of pointer to string descriptors +char const* string_desc_arr[] = { + (const char[]) {0x09, 0x04}, // 0: is supported language is English (0x0409) + "TinyUSB", // 1: Manufacturer + "TinyUSB Device", // 2: Product + NULL, // 3: Serials will use unique ID if possible + "UVC Control", // 4: UVC Interface + "UVC Streaming", // 5: UVC Interface +}; + //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = -{ +tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, - .bcdUSB = 0x0200, + .bcdUSB = USB_BCD, // Use Interface Association Descriptor (IAD) for Video // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) @@ -54,130 +76,378 @@ tusb_desc_device_t const desc_device = .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, - .idVendor = 0xCafe, + .idVendor = USB_VID, .idProduct = USB_PID, .bcdDevice = 0x0100, - .iManufacturer = 0x01, - .iProduct = 0x02, - .iSerialNumber = 0x03, + .iManufacturer = STRID_MANUFACTURER, + .iProduct = STRID_PRODUCT, + .iSerialNumber = STRID_SERIAL, .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor -uint8_t const * tud_descriptor_device_cb(void) -{ - return (uint8_t const *) &desc_device; +uint8_t const* tud_descriptor_device_cb(void) { + return (uint8_t const*) &desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ -#if defined(CFG_EXAMPLE_VIDEO_READONLY) && !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) -# if 1 == CFG_TUD_VIDEO_STREAMING_BULK -# define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_VIDEO_CAPTURE_DESC_MJPEG_BULK_LEN) -# else -# define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_VIDEO_CAPTURE_DESC_MJPEG_LEN) -# endif -#else -# if 1 == CFG_TUD_VIDEO_STREAMING_BULK -# define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_VIDEO_CAPTURE_DESC_UNCOMPR_BULK_LEN) -# else -# define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_VIDEO_CAPTURE_DESC_UNCOMPR_LEN) -# endif -#endif +/* Time stamp base clock. It is a deprecated parameter. */ +#define UVC_CLOCK_FREQUENCY 27000000 +/* video capture path */ +#define UVC_ENTITY_CAP_INPUT_TERMINAL 0x01 +#define UVC_ENTITY_CAP_OUTPUT_TERMINAL 0x02 + +enum { + ITF_NUM_VIDEO_CONTROL, + ITF_NUM_VIDEO_STREAMING, + ITF_NUM_TOTAL +}; + +// Select appropriate endpoint number #if TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX) // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In, 5 Bulk etc ... -#if 1 == CFG_TUD_VIDEO_STREAMING_BULK - #define EPNUM_VIDEO_IN 0x82 -#else - #define EPNUM_VIDEO_IN 0x83 -#endif - + #define EPNUM_VIDEO_IN (CFG_TUD_VIDEO_STREAMING_BULK ? 0x82 : 0x83) #elif TU_CHECK_MCU(OPT_MCU_NRF5X) // nRF5x ISO can only be endpoint 8 - #define EPNUM_VIDEO_IN 0x88 - + #define EPNUM_VIDEO_IN (CFG_TUD_VIDEO_STREAMING_BULK ? 0x81 : 0x88) #else #define EPNUM_VIDEO_IN 0x81 - #endif -uint8_t const desc_fs_configuration[] = -{ - // Config number, interface count, string index, total length, attribute, power in mA - TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0, 500), - - // IAD for Video Control #if defined(CFG_EXAMPLE_VIDEO_READONLY) && !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) -# if 1 == CFG_TUD_VIDEO_STREAMING_BULK - TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG_BULK(4, EPNUM_VIDEO_IN, - FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, - 64) -# else - TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(4, EPNUM_VIDEO_IN, - FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, - CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE) -# endif + #define USE_MJPEG 1 #else -# if 1 == CFG_TUD_VIDEO_STREAMING_BULK - TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR_BULK(4, EPNUM_VIDEO_IN, - FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, - 64) -# else - TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(4, EPNUM_VIDEO_IN, - FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, - CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE) -# endif + #define USE_MJPEG 0 #endif + +#define USE_ISO_STREAMING (!CFG_TUD_VIDEO_STREAMING_BULK) + +typedef struct TU_ATTR_PACKED { + tusb_desc_interface_t itf; + tusb_desc_video_control_header_1itf_t header; + tusb_desc_video_control_camera_terminal_t camera_terminal; + tusb_desc_video_control_output_terminal_t output_terminal; +} uvc_control_desc_t; + +/* Windows support YUY2 and NV12 + * https://docs.microsoft.com/en-us/windows-hardware/drivers/stream/usb-video-class-driver-overview */ + +typedef struct TU_ATTR_PACKED { + tusb_desc_interface_t itf; + tusb_desc_video_streaming_input_header_1byte_t header; + +#if USE_MJPEG + tusb_desc_video_format_mjpeg_t format; + tusb_desc_video_frame_mjpeg_continuous_t frame; +#else + tusb_desc_video_format_uncompressed_t format; + tusb_desc_video_frame_uncompressed_continuous_t frame; +#endif + + tusb_desc_video_streaming_color_matching_t color; + +#if USE_ISO_STREAMING + // For ISO streaming, USB spec requires to alternate interface + tusb_desc_interface_t itf_alt; +#endif + + tusb_desc_endpoint_t ep; +} uvc_streaming_desc_t; + +typedef struct TU_ATTR_PACKED { + tusb_desc_configuration_t config; + tusb_desc_interface_assoc_t iad; + uvc_control_desc_t video_control; + uvc_streaming_desc_t video_streaming; +} uvc_cfg_desc_t; + +const uvc_cfg_desc_t desc_fs_configuration = { + .config = { + .bLength = sizeof(tusb_desc_configuration_t), + .bDescriptorType = TUSB_DESC_CONFIGURATION, + + .wTotalLength = sizeof(uvc_cfg_desc_t), + .bNumInterfaces = ITF_NUM_TOTAL, + .bConfigurationValue = 1, + .iConfiguration = 0, + .bmAttributes = TU_BIT(7), + .bMaxPower = 100 / 2 + }, + .iad = { + .bLength = sizeof(tusb_desc_interface_assoc_t), + .bDescriptorType = TUSB_DESC_INTERFACE_ASSOCIATION, + + .bFirstInterface = ITF_NUM_VIDEO_CONTROL, + .bInterfaceCount = 2, + .bFunctionClass = TUSB_CLASS_VIDEO, + .bFunctionSubClass = VIDEO_SUBCLASS_INTERFACE_COLLECTION, + .bFunctionProtocol = VIDEO_ITF_PROTOCOL_UNDEFINED, + .iFunction = 0 + }, + + .video_control = { + .itf = { + .bLength = sizeof(tusb_desc_interface_t), + .bDescriptorType = TUSB_DESC_INTERFACE, + + .bInterfaceNumber = ITF_NUM_VIDEO_CONTROL, + .bAlternateSetting = 0, + .bNumEndpoints = 0, + .bInterfaceClass = TUSB_CLASS_VIDEO, + .bInterfaceSubClass = VIDEO_SUBCLASS_CONTROL, + .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, + .iInterface = STRID_UVC_CONTROL + }, + .header = { + .bLength = sizeof(tusb_desc_video_control_header_1itf_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VC_HEADER, + + .bcdUVC = VIDEO_BCD_1_50, + .wTotalLength = sizeof(uvc_control_desc_t) - sizeof(tusb_desc_interface_t), // CS VC descriptors only + .dwClockFrequency = UVC_CLOCK_FREQUENCY, + .bInCollection = 1, + .baInterfaceNr = { ITF_NUM_VIDEO_STREAMING } + }, + .camera_terminal = { + .bLength = sizeof(tusb_desc_video_control_camera_terminal_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VC_INPUT_TERMINAL, + + .bTerminalID = UVC_ENTITY_CAP_INPUT_TERMINAL, + .wTerminalType = VIDEO_ITT_CAMERA, + .bAssocTerminal = 0, + .iTerminal = 0, + .wObjectiveFocalLengthMin = 0, + .wObjectiveFocalLengthMax = 0, + .wOcularFocalLength = 0, + .bControlSize = 3, + .bmControls = { 0, 0, 0 } + }, + .output_terminal = { + .bLength = sizeof(tusb_desc_video_control_output_terminal_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VC_OUTPUT_TERMINAL, + + .bTerminalID = UVC_ENTITY_CAP_OUTPUT_TERMINAL, + .wTerminalType = VIDEO_TT_STREAMING, + .bAssocTerminal = 0, + .bSourceID = UVC_ENTITY_CAP_INPUT_TERMINAL, + .iTerminal = 0 + } + }, + + .video_streaming = { + .itf = { + .bLength = sizeof(tusb_desc_interface_t), + .bDescriptorType = TUSB_DESC_INTERFACE, + + .bInterfaceNumber = ITF_NUM_VIDEO_STREAMING, + .bAlternateSetting = 0, + .bNumEndpoints = CFG_TUD_VIDEO_STREAMING_BULK, // bulk 1, iso 0 + .bInterfaceClass = TUSB_CLASS_VIDEO, + .bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING, + .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, + .iInterface = STRID_UVC_STREAMING + }, + .header = { + .bLength = sizeof(tusb_desc_video_streaming_input_header_1byte_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_INPUT_HEADER, + + .bNumFormats = 1, + .wTotalLength = sizeof(uvc_streaming_desc_t) - sizeof(tusb_desc_interface_t) + - sizeof(tusb_desc_endpoint_t) - (USE_ISO_STREAMING ? sizeof(tusb_desc_interface_t) : 0) , // CS VS descriptors only + .bEndpointAddress = EPNUM_VIDEO_IN, + .bmInfo = 0, + .bTerminalLink = UVC_ENTITY_CAP_OUTPUT_TERMINAL, + .bStillCaptureMethod = 0, + .bTriggerSupport = 0, + .bTriggerUsage = 0, + .bControlSize = 1, + .bmaControls = { 0 } + }, + .format = { +#if USE_MJPEG + .bLength = sizeof(tusb_desc_video_format_mjpeg_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_MJPEG, + .bFormatIndex = 1, // 1-based index + .bNumFrameDescriptors = 1, + .bmFlags = 0, +#else + .bLength = sizeof(tusb_desc_video_format_uncompressed_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED, + .bFormatIndex = 1, // 1-based index + .bNumFrameDescriptors = 1, + .guidFormat = { TUD_VIDEO_GUID_YUY2 }, + .bBitsPerPixel = 16, +#endif + .bDefaultFrameIndex = 1, + .bAspectRatioX = 0, + .bAspectRatioY = 0, + .bmInterlaceFlags = 0, + .bCopyProtect = 0 + }, + .frame = { +#if USE_MJPEG + .bLength = sizeof(tusb_desc_video_frame_mjpeg_continuous_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_MJPEG, +#else + .bLength = sizeof(tusb_desc_video_frame_uncompressed_continuous_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED, +#endif + .bFrameIndex = 1, // 1-based index + .bmCapabilities = 0, + .wWidth = FRAME_WIDTH, + .wHeight = FRAME_HEIGHT, + .dwMinBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * 1, + .dwMaxBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * FRAME_RATE, + .dwMaxVideoFrameBufferSize = FRAME_WIDTH * FRAME_HEIGHT * 16 / 8, + .dwDefaultFrameInterval = 10000000 / FRAME_RATE, + .bFrameIntervalType = 0, // continuous + .dwFrameInterval = { + 10000000 / FRAME_RATE, // min + 10000000, // max + 10000000 / FRAME_RATE // step + } + }, + .color = { + .bLength = sizeof(tusb_desc_video_streaming_color_matching_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_COLORFORMAT, + + .bColorPrimaries = VIDEO_COLOR_PRIMARIES_BT709, + .bTransferCharacteristics = VIDEO_COLOR_XFER_CH_BT709, + .bMatrixCoefficients = VIDEO_COLOR_COEF_SMPTE170M + }, + +#if USE_ISO_STREAMING + .itf_alt = { + .bLength = sizeof(tusb_desc_interface_t), + .bDescriptorType = TUSB_DESC_INTERFACE, + + .bInterfaceNumber = ITF_NUM_VIDEO_STREAMING, + .bAlternateSetting = 1, + .bNumEndpoints = 1, + .bInterfaceClass = TUSB_CLASS_VIDEO, + .bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING, + .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, + .iInterface = STRID_UVC_STREAMING + }, +#endif + + .ep = { + .bLength = sizeof(tusb_desc_endpoint_t), + .bDescriptorType = TUSB_DESC_ENDPOINT, + + .bEndpointAddress = EPNUM_VIDEO_IN, + .bmAttributes = { + .xfer = CFG_TUD_VIDEO_STREAMING_BULK ? TUSB_XFER_BULK : TUSB_XFER_ISOCHRONOUS, + .sync = CFG_TUD_VIDEO_STREAMING_BULK ? 0 : 1 // asynchronous + }, + .wMaxPacketSize = CFG_TUD_VIDEO_STREAMING_BULK ? 64 : CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE, + .bInterval = 1 + } + } }; +#if TUD_OPT_HIGH_SPEED +uvc_cfg_desc_t desc_hs_configuration; + +static uint8_t * get_hs_configuration_desc(void) { + static bool init = false; + + if (!init) { + desc_hs_configuration = desc_fs_configuration; + // change endpoint bulk size to 512 if bulk streaming + if (CFG_TUD_VIDEO_STREAMING_BULK) { + desc_hs_configuration.video_streaming.ep.wMaxPacketSize = 512; + } + } + init = true; + + return (uint8_t *) &desc_hs_configuration; +} + +// device qualifier is mostly similar to device descriptor since we don't change configuration based on speed +tusb_desc_device_qualifier_t const desc_device_qualifier = { + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = USB_BCD, + + .bDeviceClass = TUSB_CLASS_MISC, + .bDeviceSubClass = MISC_SUBCLASS_COMMON, + .bDeviceProtocol = MISC_PROTOCOL_IAD, + + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + .bNumConfigurations = 0x01, + .bReserved = 0x00 +}; + +// Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. +// device_qualifier descriptor describes information about a high-speed capable device that would +// change if the device were operating at the other speed. If not highspeed capable stall this request. +uint8_t const* tud_descriptor_device_qualifier_cb(void) { + return (uint8_t const*) &desc_device_qualifier; +} + +// Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete +// Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa +uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index) { + (void) index; // for multiple configurations + // if link speed is high return fullspeed config, and vice versa + if (tud_speed_get() == TUSB_SPEED_HIGH) { + return (uint8_t const*) &desc_fs_configuration; + } else { + return get_hs_configuration_desc(); + } +} +#endif // highspeed + // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete -uint8_t const * tud_descriptor_configuration_cb(uint8_t index) -{ +uint8_t const* tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations - return desc_fs_configuration; +#if TUD_OPT_HIGH_SPEED + // Although we are highspeed, host may be fullspeed. + if (tud_speed_get() == TUSB_SPEED_HIGH) { + return get_hs_configuration_desc(); + } else +#endif + { + return (uint8_t const*) &desc_fs_configuration; + } } //--------------------------------------------------------------------+ // String Descriptors //--------------------------------------------------------------------+ -// String Descriptor Index -enum { - STRID_LANGID = 0, - STRID_MANUFACTURER, - STRID_PRODUCT, - STRID_SERIAL, -}; - -// array of pointer to string descriptors -char const *string_desc_arr[] = -{ - (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) - "TinyUSB", // 1: Manufacturer - "TinyUSB Device", // 2: Product - NULL, // 3: Serials will use unique ID if possible - "TinyUSB UVC", // 4: UVC Interface -}; - static uint16_t _desc_str[32 + 1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete -uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { +uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; size_t chr_count; - switch ( index ) { + switch (index) { case STRID_LANGID: memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; @@ -191,17 +461,17 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors - if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL; + if (index >= sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) return NULL; - const char *str = string_desc_arr[index]; + const char* str = string_desc_arr[index]; // Cap at max char chr_count = strlen(str); size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type - if ( chr_count > max_count ) chr_count = max_count; + if (chr_count > max_count) chr_count = max_count; // Convert ASCII string into UTF-16 - for ( size_t i = 0; i < chr_count; i++ ) { + for (size_t i = 0; i < chr_count; i++) { _desc_str[1 + i] = str[i]; } break; diff --git a/examples/device/video_capture/src/usb_descriptors.h b/examples/device/video_capture/src/usb_descriptors.h index b924c8dbe..12d41b2f3 100644 --- a/examples/device/video_capture/src/usb_descriptors.h +++ b/examples/device/video_capture/src/usb_descriptors.h @@ -27,21 +27,11 @@ #ifndef _USB_DESCRIPTORS_H_ #define _USB_DESCRIPTORS_H_ -/* Time stamp base clock. It is a deprecated parameter. */ -#define UVC_CLOCK_FREQUENCY 27000000 -/* video capture path */ -#define UVC_ENTITY_CAP_INPUT_TERMINAL 0x01 -#define UVC_ENTITY_CAP_OUTPUT_TERMINAL 0x02 - #define FRAME_WIDTH 128 #define FRAME_HEIGHT 96 #define FRAME_RATE 10 -enum { - ITF_NUM_VIDEO_CONTROL, - ITF_NUM_VIDEO_STREAMING, - ITF_NUM_TOTAL -}; +// NOTE: descriptor template is not used but leave here as reference #define TUD_VIDEO_CAPTURE_DESC_UNCOMPR_LEN (\ TUD_VIDEO_DESC_IAD_LEN\ @@ -126,23 +116,17 @@ enum { #define TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(_stridx, _epin, _width, _height, _fps, _epsize) \ TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ /* Video control 0 */ \ - TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ - TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \ - /* wTotalLength - bLength */ \ - TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \ - UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ - TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\ - /*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\ - /*wObjectiveFocalLength*/0, /*bmControls*/0), \ + TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ + /* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \ + TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ + /* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \ TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ /* Video stream alt. 0 */ \ TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 0, _stridx), \ /* Video stream header for without still image capture */ \ TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ - /*wTotalLength - bLength */\ - TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\ - + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\ - + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + /*wTotalLength - bLength */ TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ /*bmaControls(1)*/0), \ @@ -152,7 +136,7 @@ enum { /* Video stream frame format */ \ TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT(/*bFrameIndex */1, 0, _width, _height, \ _width * _height * 16, _width * _height * 16 * _fps, \ - _width * _height * 16, \ + _width * _height * 16 / 8, \ (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ /* VS alt 1 */\ @@ -163,23 +147,17 @@ enum { #define TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(_stridx, _epin, _width, _height, _fps, _epsize) \ TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ /* Video control 0 */ \ - TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ - TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \ - /* wTotalLength - bLength */ \ - TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \ - UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ - TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\ - /*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\ - /*wObjectiveFocalLength*/0, /*bmControls*/0), \ + TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ + /* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \ + TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ + /* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \ TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ /* Video stream alt. 0 */ \ TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 0, _stridx), \ /* Video stream header for without still image capture */ \ TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ - /*wTotalLength - bLength */\ - TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\ - + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\ - + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + /*wTotalLength - bLength */ TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ /*bmaControls(1)*/0), \ @@ -202,22 +180,17 @@ enum { TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ /* Video control 0 */ \ TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ - TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \ - /* wTotalLength - bLength */ \ - TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \ - UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ - TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\ - /*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\ - /*wObjectiveFocalLength*/0, /*bmControls*/0), \ + /* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \ + TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ + /* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \ TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ /* Video stream alt. 0 */ \ TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 1, _stridx), \ /* Video stream header for without still image capture */ \ TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ /*wTotalLength - bLength */\ - TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\ - + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\ - + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ /*bmaControls(1)*/0), \ @@ -227,7 +200,7 @@ enum { /* Video stream frame format */ \ TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT(/*bFrameIndex */1, 0, _width, _height, \ _width * _height * 16, _width * _height * 16 * _fps, \ - _width * _height * 16, \ + _width * _height * 16 / 8, \ (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ TUD_VIDEO_DESC_EP_BULK(_epin, _epsize, 1) @@ -235,23 +208,17 @@ enum { #define TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG_BULK(_stridx, _epin, _width, _height, _fps, _epsize) \ TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ /* Video control 0 */ \ - TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ - TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \ - /* wTotalLength - bLength */ \ - TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \ - UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ - TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\ - /*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\ - /*wObjectiveFocalLength*/0, /*bmControls*/0), \ - TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ + TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ + /* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \ + TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ + /* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \ + TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, UVC_ENTITY_CAP_INPUT_TERMINAL, 0), \ /* Video stream alt. 0 */ \ TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 1, _stridx), \ /* Video stream header for without still image capture */ \ TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ - /*wTotalLength - bLength */\ - TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\ - + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\ - + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + /*wTotalLength - bLength */ TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ /*bmaControls(1)*/0), \ diff --git a/examples/device/video_capture_2ch/CMakeLists.txt b/examples/device/video_capture_2ch/CMakeLists.txt new file mode 100644 index 000000000..80dc39ca5 --- /dev/null +++ b/examples/device/video_capture_2ch/CMakeLists.txt @@ -0,0 +1,39 @@ +cmake_minimum_required(VERSION 3.17) + +include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) + +# gets PROJECT name for the example (e.g. -) +family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR}) + +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}) + +# Espressif has its own cmake build system +if(FAMILY STREQUAL "espressif") + return() +endif() + +add_executable(${PROJECT}) + +if (FORCE_READONLY) +target_compile_definitions(${PROJECT} PRIVATE + CFG_EXAMPLE_VIDEO_READONLY +) +endif() + +# Example source +target_sources(${PROJECT} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c +) + +# Example include +target_include_directories(${PROJECT} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src +) + +# Configure compilation flags and libraries for the example without RTOS. +# See the corresponding function in hw/bsp/FAMILY/family.cmake for details. +family_configure_device_example(${PROJECT} noos) diff --git a/examples/device/video_capture_2ch/Makefile b/examples/device/video_capture_2ch/Makefile new file mode 100644 index 000000000..d698a848d --- /dev/null +++ b/examples/device/video_capture_2ch/Makefile @@ -0,0 +1,18 @@ +include ../../build_system/make/make.mk + +ifeq ($(DISABLE_MJPEG),1) +CFLAGS += -DCFG_EXAMPLE_VIDEO_DISABLE_MJPEG +endif +ifeq ($(FORCE_READONLY),1) +CFLAGS += -DCFG_EXAMPLE_VIDEO_READONLY +endif + +INC += \ + src \ + $(TOP)/hw \ + +# Example source +EXAMPLE_SOURCE += $(wildcard src/*.c) +SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) + +include ../../build_system/make/rules.mk diff --git a/examples/device/video_capture_2ch/skip.txt b/examples/device/video_capture_2ch/skip.txt new file mode 100644 index 000000000..15c176a2a --- /dev/null +++ b/examples/device/video_capture_2ch/skip.txt @@ -0,0 +1,14 @@ +mcu:MSP430x5xx +mcu:NUC121 +mcu:SAMD11 +mcu:GD32VF103 +mcu:CH32V307 +mcu:STM32L0 +family:espressif +board:curiosity_nano +board:kuiic +board:frdm_k32l2b +board:lpcxpresso11u68 +board:stm32f303disco +board:stm32l412nucleo +board:ek_tm4c123gxl diff --git a/examples/device/video_capture_2ch/src/CMakeLists.txt b/examples/device/video_capture_2ch/src/CMakeLists.txt new file mode 100644 index 000000000..cef2b46ee --- /dev/null +++ b/examples/device/video_capture_2ch/src/CMakeLists.txt @@ -0,0 +1,4 @@ +# This file is for ESP-IDF only +idf_component_register(SRCS "main.c" "usb_descriptors.c" + INCLUDE_DIRS "." + REQUIRES boards tinyusb_src) diff --git a/examples/device/video_capture_2ch/src/images.h b/examples/device/video_capture_2ch/src/images.h new file mode 100644 index 000000000..f0badd074 --- /dev/null +++ b/examples/device/video_capture_2ch/src/images.h @@ -0,0 +1,1934 @@ +#if defined(CFG_EXAMPLE_VIDEO_READONLY) +//--------------------------------------------------------------------+ +// YUY2 Uncompressed Frame (fixed) +//--------------------------------------------------------------------+ +static const unsigned char framebuf_yuy2_readonly[128 * (96 + 1) * 2] = { + /* 0 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 1 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 2 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 3 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 4 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 5 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 6 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 7 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 8 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 9 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 10 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 11 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 12 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 13 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 14 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 15 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 16 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 17 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 18 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 19 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 20 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 21 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 22 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 23 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 24 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 25 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 26 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 27 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 28 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 29 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 30 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 31 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 32 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 33 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 34 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 35 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 36 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 37 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 38 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 39 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 40 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 41 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 42 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 43 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 44 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 45 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 46 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 47 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 48 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 49 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 50 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 51 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 52 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 53 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 54 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 55 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 56 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 57 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 58 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 59 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 60 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 61 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 62 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 63 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 64 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 65 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 66 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 67 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 68 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 69 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 70 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 71 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 72 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 73 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 74 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 75 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 76 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 77 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 78 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 79 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 80 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 81 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 82 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 83 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 84 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 85 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 86 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 87 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 88 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 89 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 90 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 91 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 92 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 93 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 94 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 95 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + /* 96 */ + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, 0xdb, 0x10, 0xdb, 0x8a, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, 0xbc, 0x9a, 0xbc, 0x10, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, 0xad, 0x2a, 0xad, 0x1a, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, 0x4e, 0xd6, 0x4e, 0xe6, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, 0x3f, 0x66, 0x3f, 0xf0, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, 0x20, 0xf0, 0x20, 0x76, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, + 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, +}; + +#endif + +//--------------------------------------------------------------------+ +// MPEG Compressed Frame (fixed) +//--------------------------------------------------------------------+ + +unsigned char color_bar_0_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x92, 0x8a, 0x00, + 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, + 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, + 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, + 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, + 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, + 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, + 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, + 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, + 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, + 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, + 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, + 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, + 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, + 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, + 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, + 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, + 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, + 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, + 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, + 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, + 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0xff, 0xd9 +}; +unsigned char color_bar_1_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x7d, 0x15, 0x98, + 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, + 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, + 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, + 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, + 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, + 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, + 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, + 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, + 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, + 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, + 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, + 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, + 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, + 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, + 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, + 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, + 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, + 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, + 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, + 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, + 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x7f, 0xff, 0xd9 +}; +unsigned char color_bar_2_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x75, 0x14, 0xcc, + 0xc4, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, + 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, + 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, + 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, + 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, + 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, + 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, + 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, + 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, + 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, + 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, + 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, + 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, + 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, + 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, + 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, + 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, + 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, + 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, + 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, + 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x33, 0xff, 0xd9 +}; +unsigned char color_bar_3_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x5a, 0x2a, 0x08, + 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, + 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, + 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, + 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, + 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, + 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, + 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, + 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, + 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, + 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, + 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, + 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, + 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, + 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, + 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, + 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, + 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, + 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, + 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, + 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, + 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x91, 0xff, 0xd9 +}; +unsigned char color_bar_4_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x4a, 0x2a, 0xcb, + 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, + 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, + 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, + 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, + 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, + 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, + 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, + 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, + 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, + 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, + 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, + 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, + 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, + 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, + 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, + 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, + 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, + 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, + 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, + 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, + 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x9f, 0xff, 0xd9 +}; +unsigned char color_bar_5_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x6d, 0x14, 0x8d, + 0x04, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, + 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, + 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, + 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, + 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, + 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, + 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, + 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, + 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, + 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, + 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, + 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, + 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, + 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, + 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, + 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, + 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, + 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, + 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, + 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, + 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x7f, 0xff, 0xd9 +}; +unsigned char color_bar_6_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x65, 0x15, 0xa0, + 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, + 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, + 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, + 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, + 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, + 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, + 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, + 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, + 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, + 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, + 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, + 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, + 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, + 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, + 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, + 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, + 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, + 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, + 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, + 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, + 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x33, 0xff, 0xd9 +}; +unsigned char color_bar_7_jpg[] = { + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, + 0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, + 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x8e, 0x8a, 0x00, + 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, + 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, + 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, + 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, + 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, + 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, + 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, + 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, + 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, + 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, + 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, + 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, + 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, + 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, + 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, + 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, + 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, + 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, + 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, + 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, + 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x47, 0xff, 0xd9 +}; diff --git a/examples/device/video_capture_2ch/src/main.c b/examples/device/video_capture_2ch/src/main.c new file mode 100644 index 000000000..e8c2ec6b0 --- /dev/null +++ b/examples/device/video_capture_2ch/src/main.c @@ -0,0 +1,359 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 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. + * + */ + +#include +#include +#include + +#include "bsp/board_api.h" +#include "tusb.h" +#include "usb_descriptors.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF PROTYPES +//--------------------------------------------------------------------+ + +/* Blink pattern + * - 250 ms : device not mounted + * - 1000 ms : device mounted + * - 2500 ms : device is suspended + */ +enum { + BLINK_NOT_MOUNTED = 250, + BLINK_MOUNTED = 1000, + BLINK_SUSPENDED = 2500, +}; + +static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; + +void led_blinking_task(void* param); +void usb_device_task(void *param); +void video_task(void* param); + +#if CFG_TUSB_OS == OPT_OS_FREERTOS +void freertos_init_task(void); +#endif + + +//--------------------------------------------------------------------+ +// Main +//--------------------------------------------------------------------+ +int main(void) { + board_init(); + + // If using FreeRTOS: create blinky, tinyusb device, video task +#if CFG_TUSB_OS == OPT_OS_FREERTOS + freertos_init_task(); +#else + // init device stack on configured roothub port + tud_init(BOARD_TUD_RHPORT); + + if (board_init_after_tusb) { + board_init_after_tusb(); + } + + while (1) { + tud_task(); // tinyusb device task + led_blinking_task(NULL); + video_task(NULL); + } +#endif +} + +//--------------------------------------------------------------------+ +// Device callbacks +//--------------------------------------------------------------------+ + +// Invoked when device is mounted +void tud_mount_cb(void) { + blink_interval_ms = BLINK_MOUNTED; +} + +// Invoked when device is unmounted +void tud_umount_cb(void) { + blink_interval_ms = BLINK_NOT_MOUNTED; +} + +// Invoked when usb bus is suspended +// remote_wakeup_en : if host allow us to perform remote wakeup +// Within 7ms, device must draw an average of current less than 2.5 mA from bus +void tud_suspend_cb(bool remote_wakeup_en) { + (void) remote_wakeup_en; + blink_interval_ms = BLINK_SUSPENDED; +} + +// Invoked when usb bus is resumed +void tud_resume_cb(void) { + blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; +} + +//--------------------------------------------------------------------+ +// USB Video +//--------------------------------------------------------------------+ +#define FRAMEBUF_SIZE (FRAME_WIDTH * FRAME_HEIGHT * 16 / 8) + +static unsigned frame_num[CFG_TUD_VIDEO_STREAMING] = {1}; +static unsigned tx_busy = 0; +static unsigned interval_ms[CFG_TUD_VIDEO_STREAMING] = {1000 / FRAME_RATE}; + +// For mcus that does not have enough SRAM for frame buffer, we use fixed frame data. +// To further reduce the size, we use MJPEG format instead of YUY2. +#include "images.h" + +static struct { + uint32_t size; + uint8_t const *buffer; +} const framebuf_mjpeg[] = { + {sizeof(color_bar_0_jpg), color_bar_0_jpg}, + {sizeof(color_bar_1_jpg), color_bar_1_jpg}, + {sizeof(color_bar_2_jpg), color_bar_2_jpg}, + {sizeof(color_bar_3_jpg), color_bar_3_jpg}, + {sizeof(color_bar_4_jpg), color_bar_4_jpg}, + {sizeof(color_bar_5_jpg), color_bar_5_jpg}, + {sizeof(color_bar_6_jpg), color_bar_6_jpg}, + {sizeof(color_bar_7_jpg), color_bar_7_jpg}, +}; + +#if !defined(CFG_EXAMPLE_VIDEO_READONLY) +// YUY2 frame buffer +static uint8_t framebuf_yuy2[FRAMEBUF_SIZE]; + +static void fill_color_bar(uint8_t* buffer, unsigned start_position) { + /* EBU color bars: https://stackoverflow.com/questions/6939422 */ + static uint8_t const bar_color[8][4] = { + /* Y, U, Y, V */ + { 235, 128, 235, 128}, /* 100% White */ + { 219, 16, 219, 138}, /* Yellow */ + { 188, 154, 188, 16}, /* Cyan */ + { 173, 42, 173, 26}, /* Green */ + { 78, 214, 78, 230}, /* Magenta */ + { 63, 102, 63, 240}, /* Red */ + { 32, 240, 32, 118}, /* Blue */ + { 16, 128, 16, 128}, /* Black */ + }; + uint8_t* p; + + /* Generate the 1st line */ + uint8_t* end = &buffer[FRAME_WIDTH * 2]; + unsigned idx = (FRAME_WIDTH / 2 - 1) - (start_position % (FRAME_WIDTH / 2)); + p = &buffer[idx * 4]; + for (unsigned i = 0; i < 8; ++i) { + for (int j = 0; j < FRAME_WIDTH / (2 * 8); ++j) { + memcpy(p, &bar_color[i], 4); + p += 4; + if (end <= p) { + p = buffer; + } + } + } + + /* Duplicate the 1st line to the others */ + p = &buffer[FRAME_WIDTH * 2]; + for (unsigned i = 1; i < FRAME_HEIGHT; ++i) { + memcpy(p, buffer, FRAME_WIDTH * 2); + p += FRAME_WIDTH * 2; + } +} +#endif + +size_t get_framebuf(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, size_t fnum, void **fb) { + uint32_t idx = ctl_idx + stm_idx; + + if (idx == 0) { + // stream 0 use uncompressed YUY2 frame + #if defined(CFG_EXAMPLE_VIDEO_READONLY) + *fb = (void*)(uintptr_t ) &framebuf_yuy2_readonly[(fnum % (FRAME_WIDTH / 2)) * 4]; + #else + fill_color_bar(framebuf_yuy2, frame_num[idx]); + *fb = framebuf_yuy2; + #endif + + return FRAMEBUF_SIZE; + }else { + // stream 1 use MJPEG frame + size_t const bar_id = fnum & 0x7; + + *fb = (void*)(uintptr_t) framebuf_mjpeg[bar_id].buffer; + return framebuf_mjpeg[bar_id].size; + } +} + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ + +void video_send_frame(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) { + static unsigned start_ms[CFG_TUD_VIDEO_STREAMING] = {0, }; + static unsigned already_sent = 0; + + uint32_t idx = ctl_idx + stm_idx; + if (!tud_video_n_streaming(ctl_idx, stm_idx)) { + already_sent &= ~(1u << idx); + frame_num[idx] = 0; + return; + } + void* fp; + size_t fb_size; + + if (!(already_sent & (1u << idx))) { + already_sent |= 1u << idx; + tx_busy |= 1u << idx; + start_ms[idx] = board_millis(); + + fb_size = get_framebuf(ctl_idx, stm_idx, frame_num[idx], &fp); + tud_video_n_frame_xfer(ctl_idx, stm_idx, fp, fb_size); + } + + unsigned cur = board_millis(); + if (cur - start_ms[idx] < interval_ms[idx]) return; // not enough time + if (tx_busy & (1u << idx)) return; + start_ms[idx] += interval_ms[idx]; + tx_busy |= 1u << idx; + + fb_size = get_framebuf(ctl_idx, stm_idx, frame_num[idx], &fp); + tud_video_n_frame_xfer(ctl_idx, stm_idx, fp, fb_size); +} + + +void video_task(void* param) { + (void) param; + + while(1) { + video_send_frame(0, 0); + video_send_frame(1, 0); + + #if CFG_TUSB_OS == OPT_OS_FREERTOS + vTaskDelay(interval_ms[0] / portTICK_PERIOD_MS); + #else + return; + #endif + } +} + +void tud_video_frame_xfer_complete_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) { + uint32_t idx = ctl_idx + stm_idx; + tx_busy &= ~(1u << idx); + /* flip buffer */ + ++frame_num[idx]; +} + +int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, + video_probe_and_commit_control_t const* parameters) { + uint32_t idx = ctl_idx + stm_idx; + /* convert unit to ms from 100 ns */ + interval_ms[idx] = parameters->dwFrameInterval / 10000; + return VIDEO_ERROR_NONE; +} + +//--------------------------------------------------------------------+ +// Blinking Task +//--------------------------------------------------------------------+ +void led_blinking_task(void* param) { + (void) param; + static uint32_t start_ms = 0; + static bool led_state = false; + + while (1) { + #if CFG_TUSB_OS == OPT_OS_FREERTOS + vTaskDelay(blink_interval_ms / portTICK_PERIOD_MS); + #else + if (board_millis() - start_ms < blink_interval_ms) return; // not enough time + #endif + + start_ms += blink_interval_ms; + board_led_write(led_state); + led_state = 1 - led_state; // toggle + } +} + +//--------------------------------------------------------------------+ +// FreeRTOS +//--------------------------------------------------------------------+ +#if CFG_TUSB_OS == OPT_OS_FREERTOS + +#define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE +#define VIDEO_STACK_SIZE (configMINIMAL_STACK_SIZE*4) + +#if TUP_MCU_ESPRESSIF + #define USBD_STACK_SIZE 4096 + int main(void); + void app_main(void) { + main(); + } +#else + // Increase stack size when debug log is enabled + #define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) +#endif + +// static task +#if configSUPPORT_STATIC_ALLOCATION +StackType_t blinky_stack[BLINKY_STACK_SIZE]; +StaticTask_t blinky_taskdef; + +StackType_t usb_device_stack[USBD_STACK_SIZE]; +StaticTask_t usb_device_taskdef; + +StackType_t video_stack[VIDEO_STACK_SIZE]; +StaticTask_t video_taskdef; +#endif + +// USB Device Driver task +// This top level thread process all usb events and invoke callbacks +void usb_device_task(void *param) { + (void) param; + + // init device stack on configured roothub port + // This should be called after scheduler/kernel is started. + // Otherwise, it could cause kernel issue since USB IRQ handler does use RTOS queue API. + tud_init(BOARD_TUD_RHPORT); + + if (board_init_after_tusb) { + board_init_after_tusb(); + } + + // RTOS forever loop + while (1) { + // put this thread to waiting state until there is new events + tud_task(); + } +} + +void freertos_init_task(void) { + #if configSUPPORT_STATIC_ALLOCATION + xTaskCreateStatic(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, blinky_stack, &blinky_taskdef); + xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef); + xTaskCreateStatic(video_task, "cdc", VIDEO_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, video_stack, &video_taskdef); + #else + xTaskCreate(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, NULL); + xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL); + xTaskCreate(video_task, "video", VIDEO_STACK_SZIE, NULL, configMAX_PRIORITIES - 2, NULL); + #endif + + // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 + #if !TUP_MCU_ESPRESSIF + vTaskStartScheduler(); + #endif +} +#endif diff --git a/examples/device/video_capture_2ch/src/tusb_config.h b/examples/device/video_capture_2ch/src/tusb_config.h new file mode 100644 index 000000000..43c7dfc90 --- /dev/null +++ b/examples/device/video_capture_2ch/src/tusb_config.h @@ -0,0 +1,120 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 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. + * + */ + +#ifndef _TUSB_CONFIG_H_ +#define _TUSB_CONFIG_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Board Specific Configuration +//--------------------------------------------------------------------+ + +// RHPort number used for device can be defined by board.mk, default to port 0 +#ifndef BOARD_TUD_RHPORT +#define BOARD_TUD_RHPORT 0 +#endif + +// RHPort max operational speed can defined by board.mk +#ifndef BOARD_TUD_MAX_SPEED +#define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED +#endif + +//-------------------------------------------------------------------- +// Common Configuration +//-------------------------------------------------------------------- + +// defined by compiler flags for flexibility +#ifndef CFG_TUSB_MCU +#error CFG_TUSB_MCU must be defined +#endif + +#ifndef CFG_TUSB_OS +#define CFG_TUSB_OS OPT_OS_NONE +#endif + +// Espressif IDF requires "freertos/" prefix in include path +#if TUP_MCU_ESPRESSIF +#define CFG_TUSB_OS_INC_PATH freertos/ +#endif + +#ifndef CFG_TUSB_DEBUG +#define CFG_TUSB_DEBUG 0 +#endif + +// Enable Device stack +#define CFG_TUD_ENABLED 1 + +// Default is max speed that hardware controller could support with on-chip PHY +#define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED + +/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. + * Tinyusb use follows macros to declare transferring memory so that they can be put + * into those specific section. + * e.g + * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) + * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) + */ +#ifndef CFG_TUSB_MEM_SECTION +#define CFG_TUSB_MEM_SECTION +#endif + +#ifndef CFG_TUSB_MEM_ALIGN +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#endif + +//-------------------------------------------------------------------- +// DEVICE CONFIGURATION +//-------------------------------------------------------------------- + +#ifndef CFG_TUD_ENDPOINT0_SIZE +#define CFG_TUD_ENDPOINT0_SIZE 64 +#endif + +//------------- CLASS -------------// +// The number of video control interfaces +#define CFG_TUD_VIDEO 2 + +// The number of video streaming interfaces +#define CFG_TUD_VIDEO_STREAMING 2 + +// video streaming endpoint buffer size +#define CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE 256 + +// use bulk endpoint for streaming interface +#define CFG_TUD_VIDEO_STREAMING_BULK 1 + +//#define CFG_EXAMPLE_VIDEO_READONLY +//#define CFG_EXAMPLE_VIDEO_DISABLE_MJPEG + +#define CFG_TUD_VIDEO_LOG_LEVEL 1 + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_CONFIG_H_ */ diff --git a/examples/device/video_capture_2ch/src/usb_descriptors.c b/examples/device/video_capture_2ch/src/usb_descriptors.c new file mode 100644 index 000000000..e78e452fc --- /dev/null +++ b/examples/device/video_capture_2ch/src/usb_descriptors.c @@ -0,0 +1,653 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 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. + * + */ + +#include "bsp/board_api.h" +#include "tusb.h" +#include "usb_descriptors.h" + +/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. + * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. + * + * Auto ProductID layout's Bitmap: + * [MSB] VIDEO | AUDIO | MIDI | HID | MSC | CDC [LSB] + */ +#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) +#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ + _PID_MAP(MIDI, 3) | _PID_MAP(AUDIO, 4) | _PID_MAP(VIDEO, 5) | _PID_MAP(VENDOR, 6) ) + +#define USB_VID 0xCafe +#define USB_BCD 0x0200 + +// String Descriptor Index +enum { + STRID_LANGID = 0, + STRID_MANUFACTURER, + STRID_PRODUCT, + STRID_SERIAL, + STRID_UVC_CONTROL_1, + STRID_UVC_STREAMING_1, + STRID_UVC_CONTROL_2, + STRID_UVC_STREAMING_2, +}; + +// array of pointer to string descriptors +char const* string_desc_arr[] = { + (const char[]) {0x09, 0x04}, // 0: is supported language is English (0x0409) + "TinyUSB", // 1: Manufacturer + "TinyUSB Device", // 2: Product + NULL, // 3: Serials will use unique ID if possible + "UVC Control 1", // 4: UVC Interface 1 + "UVC Streaming 1", // 5: UVC Interface 1 + "UVC Control 2", // 6: UVC Interface 2 + "UVC Streaming 2", // 7: UVC Interface 2 + +}; + +//--------------------------------------------------------------------+ +// Device Descriptors +//--------------------------------------------------------------------+ +tusb_desc_device_t const desc_device = { + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = USB_BCD, + + // Use Interface Association Descriptor (IAD) for Video + // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) + .bDeviceClass = TUSB_CLASS_MISC, + .bDeviceSubClass = MISC_SUBCLASS_COMMON, + .bDeviceProtocol = MISC_PROTOCOL_IAD, + + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + + .idVendor = USB_VID, + .idProduct = USB_PID, + .bcdDevice = 0x0100, + + .iManufacturer = STRID_MANUFACTURER, + .iProduct = STRID_PRODUCT, + .iSerialNumber = STRID_SERIAL, + + .bNumConfigurations = 0x01 +}; + +// Invoked when received GET DEVICE DESCRIPTOR +// Application return pointer to descriptor +uint8_t const* tud_descriptor_device_cb(void) { + return (uint8_t const*) &desc_device; +} + +//--------------------------------------------------------------------+ +// Configuration Descriptor +//--------------------------------------------------------------------+ + +/* Time stamp base clock. It is a deprecated parameter. */ +#define UVC_CLOCK_FREQUENCY 27000000 + +/* video capture path */ +#define UVC_ENTITY_CAP_INPUT_TERMINAL 0x01 +#define UVC_ENTITY_CAP_OUTPUT_TERMINAL 0x02 + +enum { + ITF_NUM_VIDEO_CONTROL_1, + ITF_NUM_VIDEO_STREAMING_1, + ITF_NUM_VIDEO_CONTROL_2, + ITF_NUM_VIDEO_STREAMING_2, + ITF_NUM_TOTAL +}; + +#define EPNUM_VIDEO_IN_1 0x81 +#define EPNUM_VIDEO_IN_2 0x82 + +#if defined(CFG_EXAMPLE_VIDEO_READONLY) && !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG) + #define USE_MJPEG 1 +#else + #define USE_MJPEG 0 +#endif + +#define USE_ISO_STREAMING (!CFG_TUD_VIDEO_STREAMING_BULK) + +typedef struct TU_ATTR_PACKED { + tusb_desc_interface_t itf; + tusb_desc_video_control_header_1itf_t header; + tusb_desc_video_control_camera_terminal_t camera_terminal; + tusb_desc_video_control_output_terminal_t output_terminal; +} uvc_control_desc_t; + +/* Windows support YUY2 and NV12 + * https://docs.microsoft.com/en-us/windows-hardware/drivers/stream/usb-video-class-driver-overview */ + +typedef struct TU_ATTR_PACKED { + tusb_desc_interface_t itf; + tusb_desc_video_streaming_input_header_1byte_t header; + tusb_desc_video_format_uncompressed_t format; + tusb_desc_video_frame_uncompressed_continuous_t frame; + tusb_desc_video_streaming_color_matching_t color; + +#if USE_ISO_STREAMING + // For ISO streaming, USB spec requires to alternate interface + tusb_desc_interface_t itf_alt; +#endif + + tusb_desc_endpoint_t ep; +} uvc_streaming_yuy2_desc_t; + +typedef struct TU_ATTR_PACKED { + tusb_desc_interface_t itf; + tusb_desc_video_streaming_input_header_1byte_t header; + tusb_desc_video_format_mjpeg_t format; + tusb_desc_video_frame_mjpeg_continuous_t frame; + tusb_desc_video_streaming_color_matching_t color; + +#if USE_ISO_STREAMING + // For ISO streaming, USB spec requires to alternate interface + tusb_desc_interface_t itf_alt; +#endif + + tusb_desc_endpoint_t ep; +} uvc_streaming_mpeg_desc_t; + +typedef struct TU_ATTR_PACKED { + tusb_desc_configuration_t config; + + struct TU_ATTR_PACKED { + tusb_desc_interface_assoc_t iad; + uvc_control_desc_t video_control; + uvc_streaming_yuy2_desc_t video_streaming; + } uvc_yuy2; + + struct TU_ATTR_PACKED { + tusb_desc_interface_assoc_t iad; + uvc_control_desc_t video_control; + uvc_streaming_mpeg_desc_t video_streaming; + } uvc_mpeg; +} uvc_cfg_desc_t; + +const uvc_cfg_desc_t desc_fs_configuration = { + .config = { + .bLength = sizeof(tusb_desc_configuration_t), + .bDescriptorType = TUSB_DESC_CONFIGURATION, + + .wTotalLength = sizeof(uvc_cfg_desc_t), + .bNumInterfaces = ITF_NUM_TOTAL, + .bConfigurationValue = 1, + .iConfiguration = 0, + .bmAttributes = TU_BIT(7), + .bMaxPower = 100 / 2 + }, + //------------- Stream 0: YUY2 -------------// + .uvc_yuy2 = { + .iad = { + .bLength = sizeof(tusb_desc_interface_assoc_t), + .bDescriptorType = TUSB_DESC_INTERFACE_ASSOCIATION, + + .bFirstInterface = ITF_NUM_VIDEO_CONTROL_1, + .bInterfaceCount = 2, + .bFunctionClass = TUSB_CLASS_VIDEO, + .bFunctionSubClass = VIDEO_SUBCLASS_INTERFACE_COLLECTION, + .bFunctionProtocol = VIDEO_ITF_PROTOCOL_UNDEFINED, + .iFunction = 0 + }, + .video_control = { + .itf = { + .bLength = sizeof(tusb_desc_interface_t), + .bDescriptorType = TUSB_DESC_INTERFACE, + + .bInterfaceNumber = ITF_NUM_VIDEO_CONTROL_1, + .bAlternateSetting = 0, + .bNumEndpoints = 0, + .bInterfaceClass = TUSB_CLASS_VIDEO, + .bInterfaceSubClass = VIDEO_SUBCLASS_CONTROL, + .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, + .iInterface = STRID_UVC_CONTROL_1 + }, + .header = { + .bLength = sizeof(tusb_desc_video_control_header_1itf_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VC_HEADER, + + .bcdUVC = VIDEO_BCD_1_50, + .wTotalLength = sizeof(uvc_control_desc_t) - sizeof(tusb_desc_interface_t), // CS VC descriptors only + .dwClockFrequency = UVC_CLOCK_FREQUENCY, + .bInCollection = 1, + .baInterfaceNr = {ITF_NUM_VIDEO_STREAMING_1} + }, + .camera_terminal = { + .bLength = sizeof(tusb_desc_video_control_camera_terminal_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VC_INPUT_TERMINAL, + + .bTerminalID = UVC_ENTITY_CAP_INPUT_TERMINAL, + .wTerminalType = VIDEO_ITT_CAMERA, + .bAssocTerminal = 0, + .iTerminal = 0, + .wObjectiveFocalLengthMin = 0, + .wObjectiveFocalLengthMax = 0, + .wOcularFocalLength = 0, + .bControlSize = 3, + .bmControls = {0, 0, 0} + }, + .output_terminal = { + .bLength = sizeof(tusb_desc_video_control_output_terminal_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VC_OUTPUT_TERMINAL, + + .bTerminalID = UVC_ENTITY_CAP_OUTPUT_TERMINAL, + .wTerminalType = VIDEO_TT_STREAMING, + .bAssocTerminal = 0, + .bSourceID = UVC_ENTITY_CAP_INPUT_TERMINAL, + .iTerminal = 0 + } + }, + + .video_streaming = { + .itf = { + .bLength = sizeof(tusb_desc_interface_t), + .bDescriptorType = TUSB_DESC_INTERFACE, + + .bInterfaceNumber = ITF_NUM_VIDEO_STREAMING_1, + .bAlternateSetting = 0, + .bNumEndpoints = CFG_TUD_VIDEO_STREAMING_BULK, // bulk 1, iso 0 + .bInterfaceClass = TUSB_CLASS_VIDEO, + .bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING, + .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, + .iInterface = STRID_UVC_STREAMING_1 + }, + .header = { + .bLength = sizeof(tusb_desc_video_streaming_input_header_1byte_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_INPUT_HEADER, + + .bNumFormats = 1, + .wTotalLength = sizeof(uvc_streaming_yuy2_desc_t) - sizeof(tusb_desc_interface_t) + - sizeof(tusb_desc_endpoint_t) - + (USE_ISO_STREAMING ? sizeof(tusb_desc_interface_t) : 0), // CS VS descriptors only + .bEndpointAddress = EPNUM_VIDEO_IN_1, + .bmInfo = 0, + .bTerminalLink = UVC_ENTITY_CAP_OUTPUT_TERMINAL, + .bStillCaptureMethod = 0, + .bTriggerSupport = 0, + .bTriggerUsage = 0, + .bControlSize = 1, + .bmaControls = {0} + }, + .format = { + .bLength = sizeof(tusb_desc_video_format_uncompressed_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED, + .bFormatIndex = 1, // 1-based index + .bNumFrameDescriptors = 1, + .guidFormat = {TUD_VIDEO_GUID_YUY2}, + .bBitsPerPixel = 16, + .bDefaultFrameIndex = 1, + .bAspectRatioX = 0, + .bAspectRatioY = 0, + .bmInterlaceFlags = 0, + .bCopyProtect = 0 + }, + .frame = { + .bLength = sizeof(tusb_desc_video_frame_uncompressed_continuous_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED, + .bFrameIndex = 1, // 1-based index + .bmCapabilities = 0, + .wWidth = FRAME_WIDTH, + .wHeight = FRAME_HEIGHT, + .dwMinBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * 1, + .dwMaxBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * FRAME_RATE, + .dwMaxVideoFrameBufferSize = FRAME_WIDTH * FRAME_HEIGHT * 16 / 8, + .dwDefaultFrameInterval = 10000000 / FRAME_RATE, + .bFrameIntervalType = 0, // continuous + .dwFrameInterval = { + 10000000 / FRAME_RATE, // min + 10000000, // max + 10000000 / FRAME_RATE // step + } + }, + .color = { + .bLength = sizeof(tusb_desc_video_streaming_color_matching_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_COLORFORMAT, + + .bColorPrimaries = VIDEO_COLOR_PRIMARIES_BT709, + .bTransferCharacteristics = VIDEO_COLOR_XFER_CH_BT709, + .bMatrixCoefficients = VIDEO_COLOR_COEF_SMPTE170M + }, + +#if USE_ISO_STREAMING + .itf_alt = { + .bLength = sizeof(tusb_desc_interface_t), + .bDescriptorType = TUSB_DESC_INTERFACE, + + .bInterfaceNumber = ITF_NUM_VIDEO_STREAMING_1, + .bAlternateSetting = 1, + .bNumEndpoints = 1, + .bInterfaceClass = TUSB_CLASS_VIDEO, + .bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING, + .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, + .iInterface = STRID_UVC_STREAMING_1 + }, +#endif + .ep = { + .bLength = sizeof(tusb_desc_endpoint_t), + .bDescriptorType = TUSB_DESC_ENDPOINT, + + .bEndpointAddress = EPNUM_VIDEO_IN_1, + .bmAttributes = { + .xfer = CFG_TUD_VIDEO_STREAMING_BULK ? TUSB_XFER_BULK : TUSB_XFER_ISOCHRONOUS, + .sync = CFG_TUD_VIDEO_STREAMING_BULK ? 0 : 1 // asynchronous + }, + .wMaxPacketSize = CFG_TUD_VIDEO_STREAMING_BULK ? 64 : CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE, + .bInterval = 1 + } + } + }, + //------------- Stream 1: MPEG -------------// + .uvc_mpeg = { + .iad = { + .bLength = sizeof(tusb_desc_interface_assoc_t), + .bDescriptorType = TUSB_DESC_INTERFACE_ASSOCIATION, + + .bFirstInterface = ITF_NUM_VIDEO_CONTROL_2, + .bInterfaceCount = 2, + .bFunctionClass = TUSB_CLASS_VIDEO, + .bFunctionSubClass = VIDEO_SUBCLASS_INTERFACE_COLLECTION, + .bFunctionProtocol = VIDEO_ITF_PROTOCOL_UNDEFINED, + .iFunction = 0 + }, + + .video_control = { + .itf = { + .bLength = sizeof(tusb_desc_interface_t), + .bDescriptorType = TUSB_DESC_INTERFACE, + + .bInterfaceNumber = ITF_NUM_VIDEO_CONTROL_2, + .bAlternateSetting = 0, + .bNumEndpoints = 0, + .bInterfaceClass = TUSB_CLASS_VIDEO, + .bInterfaceSubClass = VIDEO_SUBCLASS_CONTROL, + .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, + .iInterface = STRID_UVC_CONTROL_2 + }, + .header = { + .bLength = sizeof(tusb_desc_video_control_header_1itf_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VC_HEADER, + + .bcdUVC = VIDEO_BCD_1_50, + .wTotalLength = sizeof(uvc_control_desc_t) - sizeof(tusb_desc_interface_t), // CS VC descriptors only + .dwClockFrequency = UVC_CLOCK_FREQUENCY, + .bInCollection = 1, + .baInterfaceNr = { ITF_NUM_VIDEO_STREAMING_2 } + }, + .camera_terminal = { + .bLength = sizeof(tusb_desc_video_control_camera_terminal_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VC_INPUT_TERMINAL, + + .bTerminalID = UVC_ENTITY_CAP_INPUT_TERMINAL, + .wTerminalType = VIDEO_ITT_CAMERA, + .bAssocTerminal = 0, + .iTerminal = 0, + .wObjectiveFocalLengthMin = 0, + .wObjectiveFocalLengthMax = 0, + .wOcularFocalLength = 0, + .bControlSize = 3, + .bmControls = { 0, 0, 0 } + }, + .output_terminal = { + .bLength = sizeof(tusb_desc_video_control_output_terminal_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VC_OUTPUT_TERMINAL, + + .bTerminalID = UVC_ENTITY_CAP_OUTPUT_TERMINAL, + .wTerminalType = VIDEO_TT_STREAMING, + .bAssocTerminal = 0, + .bSourceID = UVC_ENTITY_CAP_INPUT_TERMINAL, + .iTerminal = 0 + } + }, + + .video_streaming = { + .itf = { + .bLength = sizeof(tusb_desc_interface_t), + .bDescriptorType = TUSB_DESC_INTERFACE, + + .bInterfaceNumber = ITF_NUM_VIDEO_STREAMING_2, + .bAlternateSetting = 0, + .bNumEndpoints = CFG_TUD_VIDEO_STREAMING_BULK, // bulk 1, iso 0 + .bInterfaceClass = TUSB_CLASS_VIDEO, + .bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING, + .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, + .iInterface = STRID_UVC_STREAMING_2 + }, + .header = { + .bLength = sizeof(tusb_desc_video_streaming_input_header_1byte_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_INPUT_HEADER, + + .bNumFormats = 1, + .wTotalLength = sizeof(uvc_streaming_mpeg_desc_t) - sizeof(tusb_desc_interface_t) + - sizeof(tusb_desc_endpoint_t) - (USE_ISO_STREAMING ? sizeof(tusb_desc_interface_t) : 0) , // CS VS descriptors only + .bEndpointAddress = EPNUM_VIDEO_IN_2, + .bmInfo = 0, + .bTerminalLink = UVC_ENTITY_CAP_OUTPUT_TERMINAL, + .bStillCaptureMethod = 0, + .bTriggerSupport = 0, + .bTriggerUsage = 0, + .bControlSize = 1, + .bmaControls = { 0 } + }, + .format = { + .bLength = sizeof(tusb_desc_video_format_mjpeg_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_MJPEG, + .bFormatIndex = 1, // 1-based index + .bNumFrameDescriptors = 1, + .bmFlags = 0, + .bDefaultFrameIndex = 1, + .bAspectRatioX = 0, + .bAspectRatioY = 0, + .bmInterlaceFlags = 0, + .bCopyProtect = 0 + }, + .frame = { + .bLength = sizeof(tusb_desc_video_frame_mjpeg_continuous_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_MJPEG, + .bFrameIndex = 1, // 1-based index + .bmCapabilities = 0, + .wWidth = FRAME_WIDTH, + .wHeight = FRAME_HEIGHT, + .dwMinBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * 1, + .dwMaxBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * FRAME_RATE, + .dwMaxVideoFrameBufferSize = FRAME_WIDTH * FRAME_HEIGHT * 16 / 8, + .dwDefaultFrameInterval = 10000000 / FRAME_RATE, + .bFrameIntervalType = 0, // continuous + .dwFrameInterval = { + 10000000 / FRAME_RATE, // min + 10000000, // max + 10000000 / FRAME_RATE // step + } + }, + .color = { + .bLength = sizeof(tusb_desc_video_streaming_color_matching_t), + .bDescriptorType = TUSB_DESC_CS_INTERFACE, + .bDescriptorSubType = VIDEO_CS_ITF_VS_COLORFORMAT, + + .bColorPrimaries = VIDEO_COLOR_PRIMARIES_BT709, + .bTransferCharacteristics = VIDEO_COLOR_XFER_CH_BT709, + .bMatrixCoefficients = VIDEO_COLOR_COEF_SMPTE170M + }, + +#if USE_ISO_STREAMING + .itf_alt = { + .bLength = sizeof(tusb_desc_interface_t), + .bDescriptorType = TUSB_DESC_INTERFACE, + + .bInterfaceNumber = ITF_NUM_VIDEO_STREAMING_2, + .bAlternateSetting = 1, + .bNumEndpoints = 1, + .bInterfaceClass = TUSB_CLASS_VIDEO, + .bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING, + .bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15, + .iInterface = STRID_UVC_STREAMING_2 + }, +#endif + .ep = { + .bLength = sizeof(tusb_desc_endpoint_t), + .bDescriptorType = TUSB_DESC_ENDPOINT, + + .bEndpointAddress = EPNUM_VIDEO_IN_2, + .bmAttributes = { + .xfer = CFG_TUD_VIDEO_STREAMING_BULK ? TUSB_XFER_BULK : TUSB_XFER_ISOCHRONOUS, + .sync = CFG_TUD_VIDEO_STREAMING_BULK ? 0 : 1 // asynchronous + }, + .wMaxPacketSize = CFG_TUD_VIDEO_STREAMING_BULK ? 64 : CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE, + .bInterval = 1 + } + } + } +}; + +#if TUD_OPT_HIGH_SPEED +uvc_cfg_desc_t desc_hs_configuration; + +static uint8_t * get_hs_configuration_desc(void) { + static bool init = false; + + if (!init) { + desc_hs_configuration = desc_fs_configuration; + // change endpoint bulk size to 512 if bulk streaming + if (CFG_TUD_VIDEO_STREAMING_BULK) { + desc_hs_configuration.uvc_yuy2.video_streaming.ep.wMaxPacketSize = 512; + desc_hs_configuration.uvc_mpeg.video_streaming.ep.wMaxPacketSize = 512; + } + } + init = true; + + return (uint8_t *) &desc_hs_configuration; +} + +// device qualifier is mostly similar to device descriptor since we don't change configuration based on speed +tusb_desc_device_qualifier_t const desc_device_qualifier = { + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = USB_BCD, + + .bDeviceClass = TUSB_CLASS_MISC, + .bDeviceSubClass = MISC_SUBCLASS_COMMON, + .bDeviceProtocol = MISC_PROTOCOL_IAD, + + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + .bNumConfigurations = 0x01, + .bReserved = 0x00 +}; + +// Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. +// device_qualifier descriptor describes information about a high-speed capable device that would +// change if the device were operating at the other speed. If not highspeed capable stall this request. +uint8_t const* tud_descriptor_device_qualifier_cb(void) { + return (uint8_t const*) &desc_device_qualifier; +} + +// Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete +// Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa +uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index) { + (void) index; // for multiple configurations + // if link speed is high return fullspeed config, and vice versa + if (tud_speed_get() == TUSB_SPEED_HIGH) { + return (uint8_t const*) &desc_fs_configuration; + } else { + return get_hs_configuration_desc(); + } +} +#endif // highspeed + +// Invoked when received GET CONFIGURATION DESCRIPTOR +// Application return pointer to descriptor +// Descriptor contents must exist long enough for transfer to complete +uint8_t const* tud_descriptor_configuration_cb(uint8_t index) { + (void) index; // for multiple configurations + +#if TUD_OPT_HIGH_SPEED + // Although we are highspeed, host may be fullspeed. + if (tud_speed_get() == TUSB_SPEED_HIGH) { + return get_hs_configuration_desc(); + } else +#endif + { + return (uint8_t const*) &desc_fs_configuration; + } +} + +//--------------------------------------------------------------------+ +// String Descriptors +//--------------------------------------------------------------------+ + +static uint16_t _desc_str[32 + 1]; + +// Invoked when received GET STRING DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete +uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) { + (void) langid; + size_t chr_count; + + switch (index) { + case STRID_LANGID: + memcpy(&_desc_str[1], string_desc_arr[0], 2); + chr_count = 1; + break; + + case STRID_SERIAL: + chr_count = board_usb_get_serial(_desc_str + 1, 32); + break; + + default: + // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. + // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors + + if (index >= sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) return NULL; + + const char* str = string_desc_arr[index]; + + // Cap at max char + chr_count = strlen(str); + size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type + if (chr_count > max_count) chr_count = max_count; + + // Convert ASCII string into UTF-16 + for (size_t i = 0; i < chr_count; i++) { + _desc_str[1 + i] = str[i]; + } + break; + } + + // first byte is length (including header), second byte is string type + _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); + + return _desc_str; +} diff --git a/examples/device/video_capture_2ch/src/usb_descriptors.h b/examples/device/video_capture_2ch/src/usb_descriptors.h new file mode 100644 index 000000000..12d41b2f3 --- /dev/null +++ b/examples/device/video_capture_2ch/src/usb_descriptors.h @@ -0,0 +1,238 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Jerzy Kasenbreg + * Copyright (c) 2021 Koji KITAYAMA + * + * 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. + * + */ + +#ifndef _USB_DESCRIPTORS_H_ +#define _USB_DESCRIPTORS_H_ + +#define FRAME_WIDTH 128 +#define FRAME_HEIGHT 96 +#define FRAME_RATE 10 + +// NOTE: descriptor template is not used but leave here as reference + +#define TUD_VIDEO_CAPTURE_DESC_UNCOMPR_LEN (\ + TUD_VIDEO_DESC_IAD_LEN\ + /* control */\ + + TUD_VIDEO_DESC_STD_VC_LEN\ + + (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\ + + TUD_VIDEO_DESC_CAMERA_TERM_LEN\ + + TUD_VIDEO_DESC_OUTPUT_TERM_LEN\ + /* Interface 1, Alternate 0 */\ + + TUD_VIDEO_DESC_STD_VS_LEN\ + + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\ + + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\ + + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\ + /* Interface 1, Alternate 1 */\ + + TUD_VIDEO_DESC_STD_VS_LEN\ + + 7/* Endpoint */\ + ) + +#define TUD_VIDEO_CAPTURE_DESC_MJPEG_LEN (\ + TUD_VIDEO_DESC_IAD_LEN\ + /* control */\ + + TUD_VIDEO_DESC_STD_VC_LEN\ + + (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\ + + TUD_VIDEO_DESC_CAMERA_TERM_LEN\ + + TUD_VIDEO_DESC_OUTPUT_TERM_LEN\ + /* Interface 1, Alternate 0 */\ + + TUD_VIDEO_DESC_STD_VS_LEN\ + + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\ + + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\ + + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\ + /* Interface 1, Alternate 1 */\ + + TUD_VIDEO_DESC_STD_VS_LEN\ + + 7/* Endpoint */\ + ) + +#define TUD_VIDEO_CAPTURE_DESC_UNCOMPR_BULK_LEN (\ + TUD_VIDEO_DESC_IAD_LEN\ + /* control */\ + + TUD_VIDEO_DESC_STD_VC_LEN\ + + (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\ + + TUD_VIDEO_DESC_CAMERA_TERM_LEN\ + + TUD_VIDEO_DESC_OUTPUT_TERM_LEN\ + /* Interface 1, Alternate 0 */\ + + TUD_VIDEO_DESC_STD_VS_LEN\ + + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\ + + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\ + + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\ + + 7/* Endpoint */\ + ) + +#define TUD_VIDEO_CAPTURE_DESC_MJPEG_BULK_LEN (\ + TUD_VIDEO_DESC_IAD_LEN\ + /* control */\ + + TUD_VIDEO_DESC_STD_VC_LEN\ + + (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\ + + TUD_VIDEO_DESC_CAMERA_TERM_LEN\ + + TUD_VIDEO_DESC_OUTPUT_TERM_LEN\ + /* Interface 1, Alternate 0 */\ + + TUD_VIDEO_DESC_STD_VS_LEN\ + + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\ + + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\ + + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\ + + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\ + + 7/* Endpoint */\ + ) + +/* Windows support YUY2 and NV12 + * https://docs.microsoft.com/en-us/windows-hardware/drivers/stream/usb-video-class-driver-overview */ + +#define TUD_VIDEO_DESC_CS_VS_FMT_YUY2(_fmtidx, _numfmtdesc, _frmidx, _asrx, _asry, _interlace, _cp) \ + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfmtdesc, TUD_VIDEO_GUID_YUY2, 16, _frmidx, _asrx, _asry, _interlace, _cp) +#define TUD_VIDEO_DESC_CS_VS_FMT_NV12(_fmtidx, _numfmtdesc, _frmidx, _asrx, _asry, _interlace, _cp) \ + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfmtdesc, TUD_VIDEO_GUID_NV12, 12, _frmidx, _asrx, _asry, _interlace, _cp) +#define TUD_VIDEO_DESC_CS_VS_FMT_M420(_fmtidx, _numfmtdesc, _frmidx, _asrx, _asry, _interlace, _cp) \ + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfmtdesc, TUD_VIDEO_GUID_M420, 12, _frmidx, _asrx, _asry, _interlace, _cp) +#define TUD_VIDEO_DESC_CS_VS_FMT_I420(_fmtidx, _numfmtdesc, _frmidx, _asrx, _asry, _interlace, _cp) \ + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfmtdesc, TUD_VIDEO_GUID_I420, 12, _frmidx, _asrx, _asry, _interlace, _cp) + +#define TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(_stridx, _epin, _width, _height, _fps, _epsize) \ + TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ + /* Video control 0 */ \ + TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ + /* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \ + TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ + /* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \ + TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ + /* Video stream alt. 0 */ \ + TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 0, _stridx), \ + /* Video stream header for without still image capture */ \ + TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ + /*wTotalLength - bLength */ TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ + /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ + /*bmaControls(1)*/0), \ + /* Video stream format */ \ + TUD_VIDEO_DESC_CS_VS_FMT_YUY2(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \ + /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ + /* Video stream frame format */ \ + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT(/*bFrameIndex */1, 0, _width, _height, \ + _width * _height * 16, _width * _height * 16 * _fps, \ + _width * _height * 16 / 8, \ + (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ + /* VS alt 1 */\ + TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 1, 1, _stridx), \ + /* EP */ \ + TUD_VIDEO_DESC_EP_ISO(_epin, _epsize, 1) + +#define TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(_stridx, _epin, _width, _height, _fps, _epsize) \ + TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ + /* Video control 0 */ \ + TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ + /* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \ + TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ + /* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \ + TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ + /* Video stream alt. 0 */ \ + TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 0, _stridx), \ + /* Video stream header for without still image capture */ \ + TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ + /*wTotalLength - bLength */ TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ + /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ + /*bmaControls(1)*/0), \ + /* Video stream format */ \ + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \ + /*bmFlags*/0, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ + /* Video stream frame format */ \ + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT(/*bFrameIndex */1, 0, _width, _height, \ + _width * _height * 16, _width * _height * 16 * _fps, \ + _width * _height * 16 / 8, \ + (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ + /* VS alt 1 */\ + TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 1, 1, _stridx), \ + /* EP */ \ + TUD_VIDEO_DESC_EP_ISO(_epin, _epsize, 1) + + +#define TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR_BULK(_stridx, _epin, _width, _height, _fps, _epsize) \ + TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ + /* Video control 0 */ \ + TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ + /* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \ + TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ + /* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \ + TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \ + /* Video stream alt. 0 */ \ + TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 1, _stridx), \ + /* Video stream header for without still image capture */ \ + TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ + /*wTotalLength - bLength */\ + TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ + /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ + /*bmaControls(1)*/0), \ + /* Video stream format */ \ + TUD_VIDEO_DESC_CS_VS_FMT_YUY2(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \ + /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ + /* Video stream frame format */ \ + TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT(/*bFrameIndex */1, 0, _width, _height, \ + _width * _height * 16, _width * _height * 16 * _fps, \ + _width * _height * 16 / 8, \ + (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ + TUD_VIDEO_DESC_EP_BULK(_epin, _epsize, 1) + +#define TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG_BULK(_stridx, _epin, _width, _height, _fps, _epsize) \ + TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \ + /* Video control 0 */ \ + TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \ + /* Header: UVC 1.5, length of followed descs, clock (deprecated), streaming interfaces */ \ + TUD_VIDEO_DESC_CS_VC(0x0150, TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \ + /* Camera Terminal: ID, bAssocTerminal, iTerminal, focal min, max, length, bmControl */ \ + TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0, 0, 0, 0, 0), \ + TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, UVC_ENTITY_CAP_INPUT_TERMINAL, 0), \ + /* Video stream alt. 0 */ \ + TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 1, _stridx), \ + /* Video stream header for without still image capture */ \ + TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \ + /*wTotalLength - bLength */ TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\ + _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \ + /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \ + /*bmaControls(1)*/0), \ + /* Video stream format */ \ + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \ + /*bmFlags*/0, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \ + /* Video stream frame format */ \ + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT(/*bFrameIndex */1, 0, _width, _height, \ + _width * _height * 16, _width * _height * 16 * _fps, \ + _width * _height * 16 / 8, \ + (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \ + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \ + /* EP */ \ + TUD_VIDEO_DESC_EP_BULK(_epin, _epsize, 1) + + +#endif diff --git a/examples/device/webusb_serial/Makefile b/examples/device/webusb_serial/Makefile index 2a3d854fb..7fa475da5 100644 --- a/examples/device/webusb_serial/Makefile +++ b/examples/device/webusb_serial/Makefile @@ -1,4 +1,4 @@ -include ../../make.mk +include ../../build_system/make/make.mk INC += \ src \ @@ -8,4 +8,4 @@ INC += \ EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) -include ../../rules.mk +include ../../build_system/make/rules.mk diff --git a/examples/device/webusb_serial/src/main.c b/examples/device/webusb_serial/src/main.c index 6e63f869b..800d435b8 100644 --- a/examples/device/webusb_serial/src/main.c +++ b/examples/device/webusb_serial/src/main.c @@ -160,7 +160,7 @@ void tud_suspend_cb(bool remote_wakeup_en) // Invoked when usb bus is resumed void tud_resume_cb(void) { - blink_interval_ms = BLINK_MOUNTED; + blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } //--------------------------------------------------------------------+ diff --git a/examples/dual/host_hid_to_device_cdc/Makefile b/examples/dual/host_hid_to_device_cdc/Makefile index 95c88e7e8..2c2168f5d 100644 --- a/examples/dual/host_hid_to_device_cdc/Makefile +++ b/examples/dual/host_hid_to_device_cdc/Makefile @@ -1,4 +1,4 @@ -include ../../make.mk +include ../../build_system/make/make.mk INC += \ src \ @@ -15,4 +15,4 @@ SRC_C += \ src/host/hub.c \ src/host/usbh.c -include ../../rules.mk +include ../../build_system/make/rules.mk diff --git a/examples/dual/host_hid_to_device_cdc/only.txt b/examples/dual/host_hid_to_device_cdc/only.txt index a3b567f9a..cfc87eb4e 100644 --- a/examples/dual/host_hid_to_device_cdc/only.txt +++ b/examples/dual/host_hid_to_device_cdc/only.txt @@ -3,3 +3,4 @@ board:mimxrt1064_evk board:mcb1800 mcu:RP2040 mcu:ra6m5 +mcu:MAX3421 diff --git a/examples/dual/host_hid_to_device_cdc/src/main.c b/examples/dual/host_hid_to_device_cdc/src/main.c index f96f63a0d..96a2beff5 100644 --- a/examples/dual/host_hid_to_device_cdc/src/main.c +++ b/examples/dual/host_hid_to_device_cdc/src/main.c @@ -125,7 +125,7 @@ void tud_suspend_cb(bool remote_wakeup_en) // Invoked when usb bus is resumed void tud_resume_cb(void) { - blink_interval_ms = BLINK_MOUNTED; + blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED; } // Invoked when CDC interface received data from host diff --git a/examples/host/CMakeLists.txt b/examples/host/CMakeLists.txt index bedd2220b..e6a2ece14 100644 --- a/examples/host/CMakeLists.txt +++ b/examples/host/CMakeLists.txt @@ -8,5 +8,6 @@ family_initialize_project(tinyusb_host_examples ${CMAKE_CURRENT_LIST_DIR}) # family_add_subdirectory will filter what to actually add based on selected FAMILY family_add_subdirectory(bare_api) family_add_subdirectory(cdc_msc_hid) +family_add_subdirectory(cdc_msc_hid_freertos) family_add_subdirectory(hid_controller) family_add_subdirectory(msc_file_explorer) diff --git a/examples/host/bare_api/CMakeLists.txt b/examples/host/bare_api/CMakeLists.txt index 05398b079..76182d6fa 100644 --- a/examples/host/bare_api/CMakeLists.txt +++ b/examples/host/bare_api/CMakeLists.txt @@ -10,6 +10,11 @@ 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}) +# Espressif has its own cmake build system +if(FAMILY STREQUAL "espressif") + return() +endif() + add_executable(${PROJECT}) # Example source diff --git a/examples/host/bare_api/Makefile b/examples/host/bare_api/Makefile index 058307c40..0235e08c3 100644 --- a/examples/host/bare_api/Makefile +++ b/examples/host/bare_api/Makefile @@ -1,4 +1,4 @@ -include ../../make.mk +include ../../build_system/make/make.mk INC += \ src \ @@ -10,14 +10,4 @@ EXAMPLE_SOURCE += \ SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) -# TinyUSB Host Stack source -SRC_C += \ - src/class/cdc/cdc_host.c \ - src/class/hid/hid_host.c \ - src/class/msc/msc_host.c \ - src/host/hub.c \ - src/host/usbh.c \ - src/portable/ohci/ohci.c \ - src/portable/nxp/lpc17_40/hcd_lpc17_40.c - -include ../../rules.mk +include ../../build_system/make/rules.mk diff --git a/examples/host/bare_api/only.txt b/examples/host/bare_api/only.txt index f8aa2186f..fee10f9e2 100644 --- a/examples/host/bare_api/only.txt +++ b/examples/host/bare_api/only.txt @@ -1,3 +1,4 @@ +mcu:KINETIS_KL mcu:LPC175X_6X mcu:LPC177X_8X mcu:LPC18XX @@ -10,3 +11,4 @@ mcu:RP2040 mcu:MSP432E4 mcu:RX65X mcu:RAXXX +mcu:MAX3421 diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index 14725996d..670e58498 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -34,6 +34,7 @@ #include "bsp/board_api.h" #include "tusb.h" +#include "class/hid/hid.h" // English #define LANGUAGE_ID 0x0409 @@ -420,5 +421,5 @@ static void print_utf16(uint16_t *temp_buf, size_t buf_len) { _convert_utf16le_to_utf8(temp_buf + 1, utf16_len, (uint8_t *) temp_buf, sizeof(uint16_t) * buf_len); ((uint8_t*) temp_buf)[utf8_len] = '\0'; - printf((char*)temp_buf); + printf("%s", (char*)temp_buf); } diff --git a/examples/host/bare_api/src/tusb_config.h b/examples/host/bare_api/src/tusb_config.h index ede9618d3..432446e94 100644 --- a/examples/host/bare_api/src/tusb_config.h +++ b/examples/host/bare_api/src/tusb_config.h @@ -30,28 +30,8 @@ extern "C" { #endif -//--------------------------------------------------------------------+ -// Board Specific Configuration -//--------------------------------------------------------------------+ - -#if CFG_TUSB_MCU == OPT_MCU_RP2040 -// change to 1 if using pico-pio-usb as host controller for raspberry rp2040 -#define CFG_TUH_RPI_PIO_USB 0 -#define BOARD_TUH_RHPORT CFG_TUH_RPI_PIO_USB -#endif - -// RHPort number used for host can be defined by board.mk, default to port 0 -#ifndef BOARD_TUH_RHPORT -#define BOARD_TUH_RHPORT 0 -#endif - -// RHPort max operational speed can defined by board.mk -#ifndef BOARD_TUH_MAX_SPEED -#define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED -#endif - //-------------------------------------------------------------------- -// COMMON CONFIGURATION +// Common Configuration //-------------------------------------------------------------------- // defined by compiler flags for flexibility @@ -67,12 +47,6 @@ #define CFG_TUSB_DEBUG 0 #endif -// Enable Host stack -#define CFG_TUH_ENABLED 1 - -// Default is max speed that hardware controller could support with on-chip PHY -#define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED - /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. @@ -85,11 +59,43 @@ #endif #ifndef CFG_TUH_MEM_ALIGN -#define CFG_TUH_MEM_ALIGN __attribute__ ((aligned(4))) +#define CFG_TUH_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- -// CONFIGURATION +// Host Configuration +//-------------------------------------------------------------------- + +// Enable Host stack +#define CFG_TUH_ENABLED 1 + +#if CFG_TUSB_MCU == OPT_MCU_RP2040 + // #define CFG_TUH_RPI_PIO_USB 1 // use pio-usb as host controller + // #define CFG_TUH_MAX3421 1 // use max3421 as host controller + + // host roothub port is 1 if using either pio-usb or max3421 + #if (defined(CFG_TUH_RPI_PIO_USB) && CFG_TUH_RPI_PIO_USB) || (defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421) + #define BOARD_TUH_RHPORT 1 + #endif +#endif + +// Default is max speed that hardware controller could support with on-chip PHY +#define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED + +//------------------------- Board Specific -------------------------- + +// RHPort number used for host can be defined by board.mk, default to port 0 +#ifndef BOARD_TUH_RHPORT +#define BOARD_TUH_RHPORT 0 +#endif + +// RHPort max operational speed can defined by board.mk +#ifndef BOARD_TUH_MAX_SPEED +#define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED +#endif + +//-------------------------------------------------------------------- +// Driver Configuration //-------------------------------------------------------------------- // Size of buffer to hold descriptors and other data used for enumeration diff --git a/examples/host/cdc_msc_hid/CMakeLists.txt b/examples/host/cdc_msc_hid/CMakeLists.txt index ad5751705..a7c372a34 100644 --- a/examples/host/cdc_msc_hid/CMakeLists.txt +++ b/examples/host/cdc_msc_hid/CMakeLists.txt @@ -10,6 +10,11 @@ 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}) +# Espressif has its own cmake build system +if(FAMILY STREQUAL "espressif") + return() +endif() + add_executable(${PROJECT}) # Example source diff --git a/examples/host/cdc_msc_hid/Makefile b/examples/host/cdc_msc_hid/Makefile index 7c16b39d3..213c02f9c 100644 --- a/examples/host/cdc_msc_hid/Makefile +++ b/examples/host/cdc_msc_hid/Makefile @@ -1,4 +1,4 @@ -include ../../make.mk +include ../../build_system/make/make.mk INC += \ src \ @@ -13,14 +13,4 @@ EXAMPLE_SOURCE = \ SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) -# TinyUSB Host Stack source -SRC_C += \ - src/class/cdc/cdc_host.c \ - src/class/hid/hid_host.c \ - src/class/msc/msc_host.c \ - src/host/hub.c \ - src/host/usbh.c \ - src/portable/ohci/ohci.c \ - src/portable/nxp/lpc17_40/hcd_lpc17_40.c - -include ../../rules.mk +include ../../build_system/make/rules.mk diff --git a/examples/host/cdc_msc_hid/only.txt b/examples/host/cdc_msc_hid/only.txt index f8aa2186f..fee10f9e2 100644 --- a/examples/host/cdc_msc_hid/only.txt +++ b/examples/host/cdc_msc_hid/only.txt @@ -1,3 +1,4 @@ +mcu:KINETIS_KL mcu:LPC175X_6X mcu:LPC177X_8X mcu:LPC18XX @@ -10,3 +11,4 @@ mcu:RP2040 mcu:MSP432E4 mcu:RX65X mcu:RAXXX +mcu:MAX3421 diff --git a/examples/host/cdc_msc_hid/src/cdc_app.c b/examples/host/cdc_msc_hid/src/cdc_app.c index a1b26e49c..4a13f8b27 100644 --- a/examples/host/cdc_msc_hid/src/cdc_app.c +++ b/examples/host/cdc_msc_hid/src/cdc_app.c @@ -27,20 +27,11 @@ #include "tusb.h" #include "bsp/board_api.h" -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM DECLARATION -//--------------------------------------------------------------------+ - - -//------------- IMPLEMENTATION -------------// - -size_t get_console_inputs(uint8_t* buf, size_t bufsize) -{ +size_t get_console_inputs(uint8_t* buf, size_t bufsize) { size_t count = 0; - while (count < bufsize) - { + while (count < bufsize) { int ch = board_getchar(); - if ( ch <= 0 ) break; + if (ch <= 0) break; buf[count] = (uint8_t) ch; count++; @@ -49,22 +40,18 @@ size_t get_console_inputs(uint8_t* buf, size_t bufsize) return count; } -void cdc_app_task(void) -{ - uint8_t buf[64+1]; // +1 for extra null character - uint32_t const bufsize = sizeof(buf)-1; +void cdc_app_task(void) { + uint8_t buf[64 + 1]; // +1 for extra null character + uint32_t const bufsize = sizeof(buf) - 1; uint32_t count = get_console_inputs(buf, bufsize); buf[count] = 0; // loop over all mounted interfaces - for(uint8_t idx=0; idx cdc interfaces - if (count) - { + if (count) { tuh_cdc_write(idx, buf, count); tuh_cdc_write_flush(idx); } @@ -72,42 +59,51 @@ void cdc_app_task(void) } } +//--------------------------------------------------------------------+ +// TinyUSB callbacks +//--------------------------------------------------------------------+ + // Invoked when received new data -void tuh_cdc_rx_cb(uint8_t idx) -{ - uint8_t buf[64+1]; // +1 for extra null character - uint32_t const bufsize = sizeof(buf)-1; +void tuh_cdc_rx_cb(uint8_t idx) { + uint8_t buf[64 + 1]; // +1 for extra null character + uint32_t const bufsize = sizeof(buf) - 1; // forward cdc interfaces -> console uint32_t count = tuh_cdc_read(idx, buf, bufsize); buf[count] = 0; - printf((char*) buf); + printf("%s", (char*) buf); } -void tuh_cdc_mount_cb(uint8_t idx) -{ - tuh_itf_info_t itf_info = { 0 }; +// Invoked when a device with CDC interface is mounted +// idx is index of cdc interface in the internal pool. +void tuh_cdc_mount_cb(uint8_t idx) { + tuh_itf_info_t itf_info = {0}; tuh_cdc_itf_get_info(idx, &itf_info); - printf("CDC Interface is mounted: address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.desc.bInterfaceNumber); + printf("CDC Interface is mounted: address = %u, itf_num = %u\r\n", itf_info.daddr, + itf_info.desc.bInterfaceNumber); #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM - // CFG_TUH_CDC_LINE_CODING_ON_ENUM must be defined for line coding is set by tinyusb in enumeration - // otherwise you need to call tuh_cdc_set_line_coding() first - cdc_line_coding_t line_coding = { 0 }; - if ( tuh_cdc_get_local_line_coding(idx, &line_coding) ) - { - printf(" Baudrate: %lu, Stop Bits : %u\r\n", line_coding.bit_rate, line_coding.stop_bits); - printf(" Parity : %u, Data Width: %u\r\n", line_coding.parity , line_coding.data_bits); + // If CFG_TUH_CDC_LINE_CODING_ON_ENUM is defined, line coding will be set by tinyusb stack + // while eneumerating new cdc device + cdc_line_coding_t line_coding = {0}; + if (tuh_cdc_get_local_line_coding(idx, &line_coding)) { + printf(" Baudrate: %" PRIu32 ", Stop Bits : %u\r\n", line_coding.bit_rate, line_coding.stop_bits); + printf(" Parity : %u, Data Width: %u\r\n", line_coding.parity, line_coding.data_bits); } +#else + // Set Line Coding upon mounted + cdc_line_coding_t new_line_coding = { 115200, CDC_LINE_CODING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 }; + tuh_cdc_set_line_coding(idx, &new_line_coding, NULL, 0); #endif } -void tuh_cdc_umount_cb(uint8_t idx) -{ - tuh_itf_info_t itf_info = { 0 }; +// Invoked when a device with CDC interface is unmounted +void tuh_cdc_umount_cb(uint8_t idx) { + tuh_itf_info_t itf_info = {0}; tuh_cdc_itf_get_info(idx, &itf_info); - printf("CDC Interface is unmounted: address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.desc.bInterfaceNumber); + printf("CDC Interface is unmounted: address = %u, itf_num = %u\r\n", itf_info.daddr, + itf_info.desc.bInterfaceNumber); } diff --git a/examples/host/cdc_msc_hid/src/hid_app.c b/examples/host/cdc_msc_hid/src/hid_app.c index 7727ee62c..f0d42a08f 100644 --- a/examples/host/cdc_msc_hid/src/hid_app.c +++ b/examples/host/cdc_msc_hid/src/hid_app.c @@ -160,7 +160,9 @@ static void process_kbd_report(hid_keyboard_report_t const *report) putchar(ch); if ( ch == '\r' ) putchar('\n'); // added new line for enter key + #ifndef __ICCARM__ // TODO IAR doesn't support stream control ? fflush(stdout); // flush right away, else nanolib will wait for newline + #endif } } // TODO example skips key released diff --git a/examples/host/cdc_msc_hid/src/main.c b/examples/host/cdc_msc_hid/src/main.c index 405bf8c06..a3b80e030 100644 --- a/examples/host/cdc_msc_hid/src/main.c +++ b/examples/host/cdc_msc_hid/src/main.c @@ -34,13 +34,17 @@ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ void led_blinking_task(void); - extern void cdc_app_task(void); extern void hid_app_task(void); +#if CFG_TUH_ENABLED && CFG_TUH_MAX3421 +// API to read/rite MAX3421's register. Implemented by TinyUSB +extern uint8_t tuh_max3421_reg_read(uint8_t rhport, uint8_t reg, bool in_isr); +extern bool tuh_max3421_reg_write(uint8_t rhport, uint8_t reg, uint8_t data, bool in_isr); +#endif + /*------------- MAIN -------------*/ -int main(void) -{ +int main(void) { board_init(); printf("TinyUSB Host CDC MSC HID Example\r\n"); @@ -52,8 +56,13 @@ int main(void) board_init_after_tusb(); } - while (1) - { +#if CFG_TUH_ENABLED && CFG_TUH_MAX3421 + // FeatherWing MAX3421E use MAX3421E's GPIO0 for VBUS enable + enum { IOPINS1_ADDR = 20u << 3, /* 0xA0 */ }; + tuh_max3421_reg_write(BOARD_TUH_RHPORT, IOPINS1_ADDR, 0x01, false); +#endif + + while (1) { // tinyusb host task tuh_task(); @@ -67,14 +76,12 @@ int main(void) // TinyUSB Callbacks //--------------------------------------------------------------------+ -void tuh_mount_cb(uint8_t dev_addr) -{ +void tuh_mount_cb(uint8_t dev_addr) { // application set-up printf("A device with address %d is mounted\r\n", dev_addr); } -void tuh_umount_cb(uint8_t dev_addr) -{ +void tuh_umount_cb(uint8_t dev_addr) { // application tear-down printf("A device with address %d is unmounted \r\n", dev_addr); } @@ -83,15 +90,14 @@ void tuh_umount_cb(uint8_t dev_addr) //--------------------------------------------------------------------+ // Blinking Task //--------------------------------------------------------------------+ -void led_blinking_task(void) -{ +void led_blinking_task(void) { const uint32_t interval_ms = 1000; static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms - if ( board_millis() - start_ms < interval_ms) return; // not enough time + if (board_millis() - start_ms < interval_ms) return; // not enough time start_ms += interval_ms; board_led_write(led_state); diff --git a/examples/host/cdc_msc_hid/src/msc_app.c b/examples/host/cdc_msc_hid/src/msc_app.c index e9c9676b8..1d7e18e6e 100644 --- a/examples/host/cdc_msc_hid/src/msc_app.c +++ b/examples/host/cdc_msc_hid/src/msc_app.c @@ -48,8 +48,8 @@ bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_da uint32_t const block_count = tuh_msc_get_block_count(dev_addr, cbw->lun); uint32_t const block_size = tuh_msc_get_block_size(dev_addr, cbw->lun); - printf("Disk Size: %lu MB\r\n", block_count / ((1024*1024)/block_size)); - printf("Block Count = %lu, Block Size: %lu\r\n", block_count, block_size); + printf("Disk Size: %" PRIu32 " MB\r\n", block_count / ((1024*1024)/block_size)); + printf("Block Count = %" PRIu32 ", Block Size: %" PRIu32 "\r\n", block_count, block_size); return true; } diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h index abb75f068..a59a0ffb9 100644 --- a/examples/host/cdc_msc_hid/src/tusb_config.h +++ b/examples/host/cdc_msc_hid/src/tusb_config.h @@ -30,28 +30,8 @@ extern "C" { #endif -//--------------------------------------------------------------------+ -// Board Specific Configuration -//--------------------------------------------------------------------+ - -#if CFG_TUSB_MCU == OPT_MCU_RP2040 -// change to 1 if using pico-pio-usb as host controller for raspberry rp2040 -#define CFG_TUH_RPI_PIO_USB 0 -#define BOARD_TUH_RHPORT CFG_TUH_RPI_PIO_USB -#endif - -// RHPort number used for host can be defined by board.mk, default to port 0 -#ifndef BOARD_TUH_RHPORT -#define BOARD_TUH_RHPORT 0 -#endif - -// RHPort max operational speed can defined by board.mk -#ifndef BOARD_TUH_MAX_SPEED -#define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED -#endif - //-------------------------------------------------------------------- -// COMMON CONFIGURATION +// Common Configuration //-------------------------------------------------------------------- // defined by compiler flags for flexibility @@ -67,12 +47,6 @@ #define CFG_TUSB_DEBUG 0 #endif -// Enable Host stack -#define CFG_TUH_ENABLED 1 - -// Default is max speed that hardware controller could support with on-chip PHY -#define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED - /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. @@ -85,11 +59,43 @@ #endif #ifndef CFG_TUH_MEM_ALIGN -#define CFG_TUH_MEM_ALIGN __attribute__ ((aligned(4))) +#define CFG_TUH_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- -// CONFIGURATION +// Host Configuration +//-------------------------------------------------------------------- + +// Enable Host stack +#define CFG_TUH_ENABLED 1 + +#if CFG_TUSB_MCU == OPT_MCU_RP2040 + // #define CFG_TUH_RPI_PIO_USB 1 // use pio-usb as host controller + // #define CFG_TUH_MAX3421 1 // use max3421 as host controller + + // host roothub port is 1 if using either pio-usb or max3421 + #if (defined(CFG_TUH_RPI_PIO_USB) && CFG_TUH_RPI_PIO_USB) || (defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421) + #define BOARD_TUH_RHPORT 1 + #endif +#endif + +// Default is max speed that hardware controller could support with on-chip PHY +#define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED + +//------------------------- Board Specific -------------------------- + +// RHPort number used for host can be defined by board.mk, default to port 0 +#ifndef BOARD_TUH_RHPORT +#define BOARD_TUH_RHPORT 0 +#endif + +// RHPort max operational speed can defined by board.mk +#ifndef BOARD_TUH_MAX_SPEED +#define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED +#endif + +//-------------------------------------------------------------------- +// Driver Configuration //-------------------------------------------------------------------- // Size of buffer to hold descriptors and other data used for enumeration @@ -99,6 +105,7 @@ #define CFG_TUH_CDC 1 // CDC ACM #define CFG_TUH_CDC_FTDI 1 // FTDI Serial. FTDI is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_CDC_CP210X 1 // CP210x Serial. CP210X is not part of CDC class, only to re-use CDC driver API +#define CFG_TUH_CDC_CH34X 1 // CH340 or CH341 Serial. CH34X is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_HID (3*CFG_TUH_DEVICE_MAX) // typical keyboard + mouse device can have 3-4 HID interfaces #define CFG_TUH_MSC 1 #define CFG_TUH_VENDOR 0 @@ -118,7 +125,7 @@ // Set Line Coding on enumeration/mounted, value for cdc_line_coding_t // bit rate = 115200, 1 stop bit, no parity, 8 bit data width -#define CFG_TUH_CDC_LINE_CODING_ON_ENUM { 115200, CDC_LINE_CONDING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 } +#define CFG_TUH_CDC_LINE_CODING_ON_ENUM { 115200, CDC_LINE_CODING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 } #ifdef __cplusplus diff --git a/examples/host/cdc_msc_hid_freertos/CMakeLists.txt b/examples/host/cdc_msc_hid_freertos/CMakeLists.txt new file mode 100644 index 000000000..2e95a18e0 --- /dev/null +++ b/examples/host/cdc_msc_hid_freertos/CMakeLists.txt @@ -0,0 +1,36 @@ +cmake_minimum_required(VERSION 3.17) + +include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) + +# gets PROJECT name for the example (e.g. -) +family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR}) + +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}) + +# Espressif has its own cmake build system +if(FAMILY STREQUAL "espressif") + return() +endif() + +add_executable(${PROJECT}) + +# Example source +target_sources(${PROJECT} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src/cdc_app.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/freertos_hook.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/hid_app.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/msc_app.c + ) + +# Example include +target_include_directories(${PROJECT} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src + ) + +# Configure compilation flags and libraries for the example without RTOS. +# See the corresponding function in hw/bsp/FAMILY/family.cmake for details. +family_configure_host_example(${PROJECT} freertos) diff --git a/examples/host/cdc_msc_hid_freertos/Makefile b/examples/host/cdc_msc_hid_freertos/Makefile new file mode 100644 index 000000000..bf4725f47 --- /dev/null +++ b/examples/host/cdc_msc_hid_freertos/Makefile @@ -0,0 +1,34 @@ +include ../../build_system/make/make.mk + +FREERTOS_SRC = lib/FreeRTOS-Kernel +FREERTOS_PORTABLE_PATH= $(FREERTOS_SRC)/portable/$(if $(findstring iar,$(TOOLCHAIN)),IAR,GCC) + +INC += \ + src \ + src/FreeRTOSConfig \ + $(TOP)/hw \ + $(TOP)/$(FREERTOS_SRC)/include \ + $(TOP)/$(FREERTOS_PORTABLE_SRC) \ + +# Example source +EXAMPLE_SOURCE = \ + src/cdc_app.c \ + src/freertos_hook.c \ + src/hid_app.c \ + src/main.c \ + src/msc_app.c \ + +SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) + +# FreeRTOS source, all files in port folder +SRC_C += \ + $(FREERTOS_SRC)/list.c \ + $(FREERTOS_SRC)/queue.c \ + $(FREERTOS_SRC)/tasks.c \ + $(FREERTOS_SRC)/timers.c \ + $(subst $(TOP)/,,$(wildcard $(TOP)/$(FREERTOS_PORTABLE_SRC)/*.c)) + +SRC_S += \ + $(subst $(TOP)/,,$(wildcard $(TOP)/$(FREERTOS_PORTABLE_SRC)/*.s)) + +include ../../build_system/make/rules.mk diff --git a/examples/host/cdc_msc_hid_freertos/only.txt b/examples/host/cdc_msc_hid_freertos/only.txt new file mode 100644 index 000000000..81d993ffa --- /dev/null +++ b/examples/host/cdc_msc_hid_freertos/only.txt @@ -0,0 +1,12 @@ +mcu:LPC175X_6X +mcu:LPC177X_8X +mcu:LPC18XX +mcu:LPC40XX +mcu:LPC43XX +mcu:MIMXRT1XXX +mcu:MIMXRT10XX +mcu:MIMXRT11XX +mcu:MSP432E4 +mcu:RX65X +mcu:RAXXX +mcu:MAX3421 diff --git a/examples/host/cdc_msc_hid_freertos/skip.txt b/examples/host/cdc_msc_hid_freertos/skip.txt new file mode 100644 index 000000000..2ba4438fd --- /dev/null +++ b/examples/host/cdc_msc_hid_freertos/skip.txt @@ -0,0 +1 @@ +mcu:RP2040 diff --git a/examples/host/cdc_msc_hid_freertos/src/CMakeLists.txt b/examples/host/cdc_msc_hid_freertos/src/CMakeLists.txt new file mode 100644 index 000000000..6f057c106 --- /dev/null +++ b/examples/host/cdc_msc_hid_freertos/src/CMakeLists.txt @@ -0,0 +1,6 @@ +# This file is for ESP-IDF only +idf_component_register(SRCS "cdc_app.c" "hid_app.c" "main.c" "msc_app.c" + INCLUDE_DIRS "." + REQUIRES boards tinyusb_src) + +target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-error=format) diff --git a/examples/host/cdc_msc_hid_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h b/examples/host/cdc_msc_hid_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..bd754518d --- /dev/null +++ b/examples/host/cdc_msc_hid_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,199 @@ +/* + * 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 MCU header +#include "bsp/board_mcu.h" + +#if CFG_TUSB_MCU == OPT_MCU_ESP32S2 || CFG_TUSB_MCU == OPT_MCU_ESP32S3 + #error "ESP32-Sx should use IDF's FreeRTOSConfig.h" +#endif + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wredundant-decls" +#endif + +// TODO fix later +// FIXME cause redundant-decls warnings +#if CFG_TUSB_MCU == OPT_MCU_MM32F327X + extern u32 SystemCoreClock; +#else + extern uint32_t SystemCoreClock; +#endif + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + +#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 4 +#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 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* 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 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#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 0 +#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 + +#ifdef __RX__ +/* Renesas RX series */ +#define vSoftwareInterruptISR INT_Excep_ICU_SWINT +#define vTickISR INT_Excep_CMT0_CMI0 +#define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2) +#define configKERNEL_INTERRUPT_PRIORITY 1 +#define configMAX_SYSCALL_INTERRUPT_PRIORITY 4 + +#else + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ +#if defined(__NVIC_PRIO_BITS) + // For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h + #define configPRIO_BITS __NVIC_PRIO_BITS + +#elif defined(__ECLIC_INTCTLBITS) + // RISC-V Bumblebee core from nuclei + #define configPRIO_BITS __ECLIC_INTCTLBITS + +#elif defined(__IASMARM__) + // FIXME: IAR Assembler cannot include mcu header directly to get __NVIC_PRIO_BITS. + // Therefore we will hard coded it to minimum value of 2 to get pass ci build. + // IAR user must update this to correct value of the target MCU + #message "configPRIO_BITS is hard coded to 2 to pass IAR build only. User should update it per MCU" + #define configPRIO_BITS 2 + +#else + #error "FreeRTOS configPRIO_BITS to be defined" +#endif + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< cdc interfaces + tuh_cdc_write(idx, buf, count); + tuh_cdc_write_flush(idx); + } + } + } + + vTaskDelay(1); + } +} + +//--------------------------------------------------------------------+ +// TinyUSB Callbacks +//--------------------------------------------------------------------+ + +// Invoked when received new data +void tuh_cdc_rx_cb(uint8_t idx) { + uint8_t buf[64 + 1]; // +1 for extra null character + uint32_t const bufsize = sizeof(buf) - 1; + + // forward cdc interfaces -> console + uint32_t count = tuh_cdc_read(idx, buf, bufsize); + buf[count] = 0; + + printf("%s", (char *) buf); +} + +void tuh_cdc_mount_cb(uint8_t idx) { + tuh_itf_info_t itf_info = { 0 }; + tuh_cdc_itf_get_info(idx, &itf_info); + + printf("CDC Interface is mounted: address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.desc.bInterfaceNumber); + +#ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM + // CFG_TUH_CDC_LINE_CODING_ON_ENUM must be defined for line coding is set by tinyusb in enumeration + // otherwise you need to call tuh_cdc_set_line_coding() first + cdc_line_coding_t line_coding = { 0 }; + if (tuh_cdc_get_local_line_coding(idx, &line_coding)) { + printf(" Baudrate: %" PRIu32 ", Stop Bits : %u\r\n", line_coding.bit_rate, line_coding.stop_bits); + printf(" Parity : %u, Data Width: %u\r\n", line_coding.parity, line_coding.data_bits); + } +#endif +} + +void tuh_cdc_umount_cb(uint8_t idx) { + tuh_itf_info_t itf_info = { 0 }; + tuh_cdc_itf_get_info(idx, &itf_info); + + printf("CDC Interface is unmounted: address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.desc.bInterfaceNumber); +} diff --git a/examples/host/cdc_msc_hid_freertos/src/freertos_hook.c b/examples/host/cdc_msc_hid_freertos/src/freertos_hook.c new file mode 100644 index 000000000..07d159fd5 --- /dev/null +++ b/examples/host/cdc_msc_hid_freertos/src/freertos_hook.c @@ -0,0 +1,111 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 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. + * + */ + +//--------------------------------------------------------------------+ +// INCLUDE +//--------------------------------------------------------------------+ +#include "FreeRTOS.h" +#include "task.h" +#include "common/tusb_common.h" + +void vApplicationMallocFailedHook(void) { + taskDISABLE_INTERRUPTS(); + TU_ASSERT(false,); +} + +void vApplicationStackOverflowHook(xTaskHandle pxTask, char *pcTaskName) { + (void) pxTask; + (void) pcTaskName; + + taskDISABLE_INTERRUPTS(); + TU_ASSERT(false,); +} + +/* configSUPPORT_STATIC_ALLOCATION is set to 1, so the application must provide an + * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is + * used by the Idle task. */ +void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, + uint32_t *pulIdleTaskStackSize) { + /* If the buffers to be provided to the Idle task are declared inside this + * function then they must be declared static - otherwise they will be allocated on + * the stack and so not exists after this function exits. */ + static StaticTask_t xIdleTaskTCB; + static StackType_t uxIdleTaskStack[configMINIMAL_STACK_SIZE]; + + /* Pass out a pointer to the StaticTask_t structure in which the Idle task's + state will be stored. */ + *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; + + /* Pass out the array that will be used as the Idle task's stack. */ + *ppxIdleTaskStackBuffer = uxIdleTaskStack; + + /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configMINIMAL_STACK_SIZE is specified in words, not bytes. */ + *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; +} + +/* configSUPPORT_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the + * application must provide an implementation of vApplicationGetTimerTaskMemory() + * to provide the memory that is used by the Timer service task. */ +void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, + uint32_t *pulTimerTaskStackSize) { + /* If the buffers to be provided to the Timer task are declared inside this + * function then they must be declared static - otherwise they will be allocated on + * the stack and so not exists after this function exits. */ + static StaticTask_t xTimerTaskTCB; + static StackType_t uxTimerTaskStack[configTIMER_TASK_STACK_DEPTH]; + + /* Pass out a pointer to the StaticTask_t structure in which the Timer + task's state will be stored. */ + *ppxTimerTaskTCBBuffer = &xTimerTaskTCB; + + /* Pass out the array that will be used as the Timer task's stack. */ + *ppxTimerTaskStackBuffer = uxTimerTaskStack; + + /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configTIMER_TASK_STACK_DEPTH is specified in words, not bytes. */ + *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; +} + +#if CFG_TUSB_MCU == OPT_MCU_RX63X | CFG_TUSB_MCU == OPT_MCU_RX65X +#include "iodefine.h" +void vApplicationSetupTimerInterrupt(void) +{ + /* Enable CMT0 */ + SYSTEM.PRCR.WORD = (0xA5u<<8) | TU_BIT(1); + MSTP(CMT0) = 0; + SYSTEM.PRCR.WORD = (0xA5u<<8); + + CMT0.CMCNT = 0; + CMT0.CMCOR = (unsigned short)(((configPERIPHERAL_CLOCK_HZ/configTICK_RATE_HZ)-1)/128); + CMT0.CMCR.WORD = TU_BIT(6) | 2; + IR(CMT0, CMI0) = 0; + IPR(CMT0, CMI0) = configKERNEL_INTERRUPT_PRIORITY; + IEN(CMT0, CMI0) = 1; + CMT.CMSTR0.BIT.STR0 = 1; +} +#endif diff --git a/examples/host/cdc_msc_hid_freertos/src/hid_app.c b/examples/host/cdc_msc_hid_freertos/src/hid_app.c new file mode 100644 index 000000000..9ea5c1be0 --- /dev/null +++ b/examples/host/cdc_msc_hid_freertos/src/hid_app.c @@ -0,0 +1,267 @@ +/* + * 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. + * + */ + +#include "bsp/board_api.h" +#include "tusb.h" + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ + +// If your host terminal support ansi escape code such as TeraTerm +// it can be use to simulate mouse cursor movement within terminal +#define USE_ANSI_ESCAPE 0 + +#define MAX_REPORT 4 + +static uint8_t const keycode2ascii[128][2] = { HID_KEYCODE_TO_ASCII }; + +// Each HID instance can has multiple reports +static struct { + uint8_t report_count; + tuh_hid_report_info_t report_info[MAX_REPORT]; +} hid_info[CFG_TUH_HID]; + +static void process_kbd_report(hid_keyboard_report_t const *report); +static void process_mouse_report(hid_mouse_report_t const *report); +static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t const *report, uint16_t len); + +void hid_app_init(void) { + // nothing to do +} + +//--------------------------------------------------------------------+ +// TinyUSB Callbacks +//--------------------------------------------------------------------+ + +// Invoked when device with hid interface is mounted +// Report descriptor is also available for use. tuh_hid_parse_report_descriptor() +// can be used to parse common/simple enough descriptor. +// Note: if report descriptor length > CFG_TUH_ENUMERATION_BUFSIZE, it will be skipped +// therefore report_desc = NULL, desc_len = 0 +void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const *desc_report, uint16_t desc_len) { + printf("HID device address = %d, instance = %d is mounted\r\n", dev_addr, instance); + + // Interface protocol (hid_interface_protocol_enum_t) + const char *protocol_str[] = { "None", "Keyboard", "Mouse" }; + uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance); + + printf("HID Interface Protocol = %s\r\n", protocol_str[itf_protocol]); + + // By default host stack will use activate boot protocol on supported interface. + // Therefore for this simple example, we only need to parse generic report descriptor (with built-in parser) + if (itf_protocol == HID_ITF_PROTOCOL_NONE) { + hid_info[instance].report_count = tuh_hid_parse_report_descriptor(hid_info[instance].report_info, MAX_REPORT, + desc_report, desc_len); + printf("HID has %u reports \r\n", hid_info[instance].report_count); + } + + // request to receive report + // tuh_hid_report_received_cb() will be invoked when report is available + if (!tuh_hid_receive_report(dev_addr, instance)) { + printf("Error: cannot request to receive report\r\n"); + } +} + +// Invoked when device with hid interface is un-mounted +void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) { + printf("HID device address = %d, instance = %d is unmounted\r\n", dev_addr, instance); +} + +// Invoked when received report from device via interrupt endpoint +void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const *report, uint16_t len) { + uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance); + + switch (itf_protocol) { + case HID_ITF_PROTOCOL_KEYBOARD: + TU_LOG2("HID receive boot keyboard report\r\n"); + process_kbd_report((hid_keyboard_report_t const *) report); + break; + + case HID_ITF_PROTOCOL_MOUSE: + TU_LOG2("HID receive boot mouse report\r\n"); + process_mouse_report((hid_mouse_report_t const *) report); + break; + + default: + // Generic report requires matching ReportID and contents with previous parsed report info + process_generic_report(dev_addr, instance, report, len); + break; + } + + // continue to request to receive report + if (!tuh_hid_receive_report(dev_addr, instance)) { + printf("Error: cannot request to receive report\r\n"); + } +} + +//--------------------------------------------------------------------+ +// Keyboard +//--------------------------------------------------------------------+ + +// look up new key in previous keys +static inline bool find_key_in_report(hid_keyboard_report_t const *report, uint8_t keycode) { + for (uint8_t i = 0; i < 6; i++) { + if (report->keycode[i] == keycode) return true; + } + + return false; +} + +static void process_kbd_report(hid_keyboard_report_t const *report) { + static hid_keyboard_report_t prev_report = { 0, 0, { 0 } }; // previous report to check key released + + //------------- example code ignore control (non-printable) key affects -------------// + for (uint8_t i = 0; i < 6; i++) { + if (report->keycode[i]) { + if (find_key_in_report(&prev_report, report->keycode[i])) { + // exist in previous report means the current key is holding + } else { + // not existed in previous report means the current key is pressed + bool const is_shift = report->modifier & (KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT); + uint8_t ch = keycode2ascii[report->keycode[i]][is_shift ? 1 : 0]; + putchar(ch); + if (ch == '\r') putchar('\n'); // added new line for enter key + + #ifndef __ICCARM__ // TODO IAR doesn't support stream control ? + fflush(stdout); // flush right away, else nanolib will wait for newline + #endif + } + } + // TODO example skips key released + } + + prev_report = *report; +} + +//--------------------------------------------------------------------+ +// Mouse +//--------------------------------------------------------------------+ + +void cursor_movement(int8_t x, int8_t y, int8_t wheel) { +#if USE_ANSI_ESCAPE + // Move X using ansi escape + if ( x < 0) { + printf(ANSI_CURSOR_BACKWARD(%d), (-x)); // move left + }else if ( x > 0) { + printf(ANSI_CURSOR_FORWARD(%d), x); // move right + } + + // Move Y using ansi escape + if ( y < 0) { + printf(ANSI_CURSOR_UP(%d), (-y)); // move up + }else if ( y > 0) { + printf(ANSI_CURSOR_DOWN(%d), y); // move down + } + + // Scroll using ansi escape + if (wheel < 0) { + printf(ANSI_SCROLL_UP(%d), (-wheel)); // scroll up + }else if (wheel > 0) { + printf(ANSI_SCROLL_DOWN(%d), wheel); // scroll down + } + + printf("\r\n"); +#else + printf("(%d %d %d)\r\n", x, y, wheel); +#endif +} + +static void process_mouse_report(hid_mouse_report_t const *report) { + static hid_mouse_report_t prev_report = { 0 }; + + //------------- button state -------------// + uint8_t button_changed_mask = report->buttons ^ prev_report.buttons; + if (button_changed_mask & report->buttons) { + printf(" %c%c%c ", + report->buttons & MOUSE_BUTTON_LEFT ? 'L' : '-', + report->buttons & MOUSE_BUTTON_MIDDLE ? 'M' : '-', + report->buttons & MOUSE_BUTTON_RIGHT ? 'R' : '-'); + } + + //------------- cursor movement -------------// + cursor_movement(report->x, report->y, report->wheel); +} + +//--------------------------------------------------------------------+ +// Generic Report +//--------------------------------------------------------------------+ +static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t const *report, uint16_t len) { + (void) dev_addr; + + uint8_t const rpt_count = hid_info[instance].report_count; + tuh_hid_report_info_t *rpt_info_arr = hid_info[instance].report_info; + tuh_hid_report_info_t *rpt_info = NULL; + + if (rpt_count == 1 && rpt_info_arr[0].report_id == 0) { + // Simple report without report ID as 1st byte + rpt_info = &rpt_info_arr[0]; + } else { + // Composite report, 1st byte is report ID, data starts from 2nd byte + uint8_t const rpt_id = report[0]; + + // Find report id in the array + for (uint8_t i = 0; i < rpt_count; i++) { + if (rpt_id == rpt_info_arr[i].report_id) { + rpt_info = &rpt_info_arr[i]; + break; + } + } + + report++; + len--; + } + + if (!rpt_info) { + printf("Couldn't find report info !\r\n"); + return; + } + + // For complete list of Usage Page & Usage checkout src/class/hid/hid.h. For examples: + // - Keyboard : Desktop, Keyboard + // - Mouse : Desktop, Mouse + // - Gamepad : Desktop, Gamepad + // - Consumer Control (Media Key) : Consumer, Consumer Control + // - System Control (Power key) : Desktop, System Control + // - Generic (vendor) : 0xFFxx, xx + if (rpt_info->usage_page == HID_USAGE_PAGE_DESKTOP) { + switch (rpt_info->usage) { + case HID_USAGE_DESKTOP_KEYBOARD: + TU_LOG1("HID receive keyboard report\r\n"); + // Assume keyboard follow boot report layout + process_kbd_report((hid_keyboard_report_t const *) report); + break; + + case HID_USAGE_DESKTOP_MOUSE: + TU_LOG1("HID receive mouse report\r\n"); + // Assume mouse follow boot report layout + process_mouse_report((hid_mouse_report_t const *) report); + break; + + default: + break; + } + } +} diff --git a/examples/host/cdc_msc_hid_freertos/src/main.c b/examples/host/cdc_msc_hid_freertos/src/main.c new file mode 100644 index 000000000..fa799aede --- /dev/null +++ b/examples/host/cdc_msc_hid_freertos/src/main.c @@ -0,0 +1,180 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 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. + * + */ + +#include +#include +#include + +#include "bsp/board_api.h" +#include "tusb.h" + +#if TUP_MCU_ESPRESSIF + // ESP-IDF need "freertos/" prefix in include path. + // CFG_TUSB_OS_INC_PATH should be defined accordingly. + #include "freertos/FreeRTOS.h" + #include "freertos/semphr.h" + #include "freertos/queue.h" + #include "freertos/task.h" + #include "freertos/timers.h" + + #define USBH_STACK_SIZE 4096 +#else + #include "FreeRTOS.h" + #include "semphr.h" + #include "queue.h" + #include "task.h" + #include "timers.h" + + // Increase stack size when debug log is enabled + #define USBH_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) +#endif + + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF PROTOTYPES +//--------------------------------------------------------------------+ +/* Blink pattern + * - 250 ms : device not mounted + * - 1000 ms : device mounted + * - 2500 ms : device is suspended + */ +enum { + BLINK_NOT_MOUNTED = 250, + BLINK_MOUNTED = 1000, + BLINK_SUSPENDED = 2500, +}; + +// static timer & task +#if configSUPPORT_STATIC_ALLOCATION +StaticTimer_t blinky_tmdef; + +StackType_t usb_host_stack[USBH_STACK_SIZE]; +StaticTask_t usb_host_taskdef; +#endif + +TimerHandle_t blinky_tm; + +static void led_blinky_cb(TimerHandle_t xTimer); +static void usb_host_task(void* param); + +extern void cdc_app_init(void); +extern void hid_app_init(void); +extern void msc_app_init(void); + +#if CFG_TUH_ENABLED && CFG_TUH_MAX3421 +// API to read/rite MAX3421's register. Implemented by TinyUSB +extern uint8_t tuh_max3421_reg_read(uint8_t rhport, uint8_t reg, bool in_isr); +extern bool tuh_max3421_reg_write(uint8_t rhport, uint8_t reg, uint8_t data, bool in_isr); +#endif + +/*------------- MAIN -------------*/ +int main(void) { + board_init(); + + printf("TinyUSB Host CDC MSC HID with FreeRTOS Example\r\n"); + + // Create soft timer for blinky, task for tinyusb stack +#if configSUPPORT_STATIC_ALLOCATION + blinky_tm = xTimerCreateStatic(NULL, pdMS_TO_TICKS(BLINK_MOUNTED), true, NULL, led_blinky_cb, &blinky_tmdef); + xTaskCreateStatic(usb_host_task, "usbh", USBH_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_host_stack, &usb_host_taskdef); +#else + blinky_tm = xTimerCreate(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb); + xTaskCreate(usb_host_task, "usbd", USBH_STACK_SIZE, NULL, configMAX_PRIORITIES-1, NULL); +#endif + + xTimerStart(blinky_tm, 0); + + // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 +#if !TUP_MCU_ESPRESSIF + vTaskStartScheduler(); +#endif + + return 0; +} + +#if TUP_MCU_ESPRESSIF +void app_main(void) { + main(); +} +#endif + +// USB Host task +// This top level thread process all usb events and invoke callbacks +static void usb_host_task(void *param) { + (void) param; + + // init host stack on configured roothub port + if (!tuh_init(BOARD_TUH_RHPORT)) { + printf("Failed to init USB Host Stack\r\n"); + vTaskSuspend(NULL); + } + + if (board_init_after_tusb) { + board_init_after_tusb(); + } + +#if CFG_TUH_ENABLED && CFG_TUH_MAX3421 + // FeatherWing MAX3421E use MAX3421E's GPIO0 for VBUS enable + enum { IOPINS1_ADDR = 20u << 3, /* 0xA0 */ }; + tuh_max3421_reg_write(BOARD_TUH_RHPORT, IOPINS1_ADDR, 0x01, false); +#endif + + cdc_app_init(); + hid_app_init(); + msc_app_init(); + + // RTOS forever loop + while (1) { + // put this thread to waiting state until there is new events + tuh_task(); + + // following code only run if tuh_task() process at least 1 event + } +} + +//--------------------------------------------------------------------+ +// TinyUSB Callbacks +//--------------------------------------------------------------------+ + +void tuh_mount_cb(uint8_t dev_addr) { + // application set-up + printf("A device with address %d is mounted\r\n", dev_addr); +} + +void tuh_umount_cb(uint8_t dev_addr) { + // application tear-down + printf("A device with address %d is unmounted \r\n", dev_addr); +} + +//--------------------------------------------------------------------+ +// BLINKING TASK +//--------------------------------------------------------------------+ +static void led_blinky_cb(TimerHandle_t xTimer) { + (void) xTimer; + static bool led_state = false; + + board_led_write(led_state); + led_state = 1 - led_state; // toggle +} diff --git a/examples/host/cdc_msc_hid_freertos/src/msc_app.c b/examples/host/cdc_msc_hid_freertos/src/msc_app.c new file mode 100644 index 000000000..9ffd5d965 --- /dev/null +++ b/examples/host/cdc_msc_hid_freertos/src/msc_app.c @@ -0,0 +1,67 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 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. + * + */ + +#include "tusb.h" + +static scsi_inquiry_resp_t inquiry_resp; + +void msc_app_init(void) { + // nothing to do +} + +bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const *cb_data) { + msc_cbw_t const *cbw = cb_data->cbw; + msc_csw_t const *csw = cb_data->csw; + + if (csw->status != 0) { + printf("Inquiry failed\r\n"); + return false; + } + + // Print out Vendor ID, Product ID and Rev + printf("%.8s %.16s rev %.4s\r\n", inquiry_resp.vendor_id, inquiry_resp.product_id, inquiry_resp.product_rev); + + // Get capacity of device + uint32_t const block_count = tuh_msc_get_block_count(dev_addr, cbw->lun); + uint32_t const block_size = tuh_msc_get_block_size(dev_addr, cbw->lun); + + printf("Disk Size: %" PRIu32 " MB\r\n", block_count / ((1024 * 1024) / block_size)); + printf("Block Count = %" PRIu32 ", Block Size: %" PRIu32 "\r\n", block_count, block_size); + + return true; +} + +//------------- IMPLEMENTATION -------------// +void tuh_msc_mount_cb(uint8_t dev_addr) { + printf("A MassStorage device is mounted\r\n"); + + uint8_t const lun = 0; + tuh_msc_inquiry(dev_addr, lun, &inquiry_resp, inquiry_complete_cb, 0); +} + +void tuh_msc_umount_cb(uint8_t dev_addr) { + (void) dev_addr; + printf("A MassStorage device is unmounted\r\n"); +} diff --git a/examples/host/cdc_msc_hid_freertos/src/tusb_config.h b/examples/host/cdc_msc_hid_freertos/src/tusb_config.h new file mode 100644 index 000000000..0aab2cd2f --- /dev/null +++ b/examples/host/cdc_msc_hid_freertos/src/tusb_config.h @@ -0,0 +1,140 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 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. + * + */ + +#ifndef _TUSB_CONFIG_H_ +#define _TUSB_CONFIG_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +//-------------------------------------------------------------------- +// Common Configuration +//-------------------------------------------------------------------- + +// defined by compiler flags for flexibility +#ifndef CFG_TUSB_MCU +#error CFG_TUSB_MCU must be defined +#endif + +#ifndef CFG_TUSB_OS +#define CFG_TUSB_OS OPT_OS_FREERTOS +#endif + +// Espressif IDF requires "freertos/" prefix in include path +#if TUP_MCU_ESPRESSIF +#define CFG_TUSB_OS_INC_PATH freertos/ +#endif + +#ifndef CFG_TUSB_DEBUG +#define CFG_TUSB_DEBUG 0 +#endif + +/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. + * Tinyusb use follows macros to declare transferring memory so that they can be put + * into those specific section. + * e.g + * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) + * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) + */ +#ifndef CFG_TUH_MEM_SECTION +#define CFG_TUH_MEM_SECTION +#endif + +#ifndef CFG_TUH_MEM_ALIGN +#define CFG_TUH_MEM_ALIGN __attribute__ ((aligned(4))) +#endif + +//-------------------------------------------------------------------- +// Host Configuration +//-------------------------------------------------------------------- + +// Enable Host stack +#define CFG_TUH_ENABLED 1 + +#if CFG_TUSB_MCU == OPT_MCU_RP2040 + // #define CFG_TUH_RPI_PIO_USB 1 // use pio-usb as host controller + // #define CFG_TUH_MAX3421 1 // use max3421 as host controller + + // host roothub port is 1 if using either pio-usb or max3421 + #if (defined(CFG_TUH_RPI_PIO_USB) && CFG_TUH_RPI_PIO_USB) || (defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421) + #define BOARD_TUH_RHPORT 1 + #endif +#endif + +// Default is max speed that hardware controller could support with on-chip PHY +#define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED + +//------------------------- Board Specific -------------------------- + +// RHPort number used for host can be defined by board.mk, default to port 0 +#ifndef BOARD_TUH_RHPORT +#define BOARD_TUH_RHPORT 0 +#endif + +// RHPort max operational speed can defined by board.mk +#ifndef BOARD_TUH_MAX_SPEED +#define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED +#endif + +//-------------------------------------------------------------------- +// Driver Configuration +//-------------------------------------------------------------------- + +// Size of buffer to hold descriptors and other data used for enumeration +#define CFG_TUH_ENUMERATION_BUFSIZE 256 + +#define CFG_TUH_HUB 1 // number of supported hubs +#define CFG_TUH_CDC 1 // CDC ACM +#define CFG_TUH_CDC_FTDI 1 // FTDI Serial. FTDI is not part of CDC class, only to re-use CDC driver API +#define CFG_TUH_CDC_CP210X 1 // CP210x Serial. CP210X is not part of CDC class, only to re-use CDC driver API +#define CFG_TUH_CDC_CH34X 1 // CH340 or CH341 Serial. CH34X is not part of CDC class, only to re-use CDC driver API +#define CFG_TUH_HID (3*CFG_TUH_DEVICE_MAX) // typical keyboard + mouse device can have 3-4 HID interfaces +#define CFG_TUH_MSC 1 +#define CFG_TUH_VENDOR 0 + +// max device support (excluding hub device): 1 hub typically has 4 ports +#define CFG_TUH_DEVICE_MAX (3*CFG_TUH_HUB + 1) + +//------------- HID -------------// +#define CFG_TUH_HID_EPIN_BUFSIZE 64 +#define CFG_TUH_HID_EPOUT_BUFSIZE 64 + +//------------- CDC -------------// + +// Set Line Control state on enumeration/mounted: +// DTR ( bit 0), RTS (bit 1) +#define CFG_TUH_CDC_LINE_CONTROL_ON_ENUM 0x03 + +// Set Line Coding on enumeration/mounted, value for cdc_line_coding_t +// bit rate = 115200, 1 stop bit, no parity, 8 bit data width +#define CFG_TUH_CDC_LINE_CODING_ON_ENUM { 115200, CDC_LINE_CODING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 } + + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_CONFIG_H_ */ diff --git a/examples/host/hid_controller/CMakeLists.txt b/examples/host/hid_controller/CMakeLists.txt index 3fb630aaa..c1b500dd8 100644 --- a/examples/host/hid_controller/CMakeLists.txt +++ b/examples/host/hid_controller/CMakeLists.txt @@ -10,6 +10,11 @@ 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}) +# Espressif has its own cmake build system +if(FAMILY STREQUAL "espressif") + return() +endif() + add_executable(${PROJECT}) # Example source diff --git a/examples/host/hid_controller/Makefile b/examples/host/hid_controller/Makefile index cda2977bc..1377f1f90 100644 --- a/examples/host/hid_controller/Makefile +++ b/examples/host/hid_controller/Makefile @@ -1,4 +1,4 @@ -include ../../make.mk +include ../../build_system/make/make.mk INC += \ src \ @@ -11,14 +11,4 @@ EXAMPLE_SOURCE += \ SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) -# TinyUSB Host Stack source -SRC_C += \ - src/class/cdc/cdc_host.c \ - src/class/hid/hid_host.c \ - src/class/msc/msc_host.c \ - src/host/hub.c \ - src/host/usbh.c \ - src/portable/ohci/ohci.c \ - src/portable/nxp/lpc17_40/hcd_lpc17_40.c - -include ../../rules.mk +include ../../build_system/make/rules.mk diff --git a/examples/host/hid_controller/only.txt b/examples/host/hid_controller/only.txt index f8aa2186f..fee10f9e2 100644 --- a/examples/host/hid_controller/only.txt +++ b/examples/host/hid_controller/only.txt @@ -1,3 +1,4 @@ +mcu:KINETIS_KL mcu:LPC175X_6X mcu:LPC177X_8X mcu:LPC18XX @@ -10,3 +11,4 @@ mcu:RP2040 mcu:MSP432E4 mcu:RX65X mcu:RAXXX +mcu:MAX3421 diff --git a/examples/host/hid_controller/src/tusb_config.h b/examples/host/hid_controller/src/tusb_config.h index d37fc02d2..3ac591d8f 100644 --- a/examples/host/hid_controller/src/tusb_config.h +++ b/examples/host/hid_controller/src/tusb_config.h @@ -30,28 +30,8 @@ extern "C" { #endif -//--------------------------------------------------------------------+ -// Board Specific Configuration -//--------------------------------------------------------------------+ - - #if CFG_TUSB_MCU == OPT_MCU_RP2040 -// change to 1 if using pico-pio-usb as host controller for raspberry rp2040 -#define CFG_TUH_RPI_PIO_USB 0 -#define BOARD_TUH_RHPORT CFG_TUH_RPI_PIO_USB -#endif - -// RHPort number used for host can be defined by board.mk, default to port 0 -#ifndef BOARD_TUH_RHPORT -#define BOARD_TUH_RHPORT 0 -#endif - -// RHPort max operational speed can defined by board.mk -#ifndef BOARD_TUH_MAX_SPEED -#define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED -#endif - //-------------------------------------------------------------------- -// COMMON CONFIGURATION +// Common Configuration //-------------------------------------------------------------------- // defined by compiler flags for flexibility @@ -67,12 +47,6 @@ #define CFG_TUSB_DEBUG 0 #endif -// Enable Host stack -#define CFG_TUH_ENABLED 1 - -// Default is max speed that hardware controller could support with on-chip PHY -#define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED - /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. @@ -85,11 +59,43 @@ #endif #ifndef CFG_TUH_MEM_ALIGN -#define CFG_TUH_MEM_ALIGN __attribute__ ((aligned(4))) +#define CFG_TUH_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- -// CONFIGURATION +// Host Configuration +//-------------------------------------------------------------------- + +// Enable Host stack +#define CFG_TUH_ENABLED 1 + +#if CFG_TUSB_MCU == OPT_MCU_RP2040 + // #define CFG_TUH_RPI_PIO_USB 1 // use pio-usb as host controller + // #define CFG_TUH_MAX3421 1 // use max3421 as host controller + + // host roothub port is 1 if using either pio-usb or max3421 + #if (defined(CFG_TUH_RPI_PIO_USB) && CFG_TUH_RPI_PIO_USB) || (defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421) + #define BOARD_TUH_RHPORT 1 + #endif +#endif + +// Default is max speed that hardware controller could support with on-chip PHY +#define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED + +//------------------------- Board Specific -------------------------- + +// RHPort number used for host can be defined by board.mk, default to port 0 +#ifndef BOARD_TUH_RHPORT +#define BOARD_TUH_RHPORT 0 +#endif + +// RHPort max operational speed can defined by board.mk +#ifndef BOARD_TUH_MAX_SPEED +#define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED +#endif + +//-------------------------------------------------------------------- +// Driver Configuration //-------------------------------------------------------------------- // Size of buffer to hold descriptors and other data used for enumeration diff --git a/examples/host/msc_file_explorer/CMakeLists.txt b/examples/host/msc_file_explorer/CMakeLists.txt index a35a7f0fb..1a57c7466 100644 --- a/examples/host/msc_file_explorer/CMakeLists.txt +++ b/examples/host/msc_file_explorer/CMakeLists.txt @@ -10,6 +10,11 @@ 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}) +# Espressif has its own cmake build system +if(FAMILY STREQUAL "espressif") + return() +endif() + add_executable(${PROJECT}) # Example source @@ -22,11 +27,13 @@ target_sources(${PROJECT} PUBLIC ) # Suppress warnings on fatfs -set_source_files_properties( - ${TOP}/lib/fatfs/source/ff.c - PROPERTIES - COMPILE_FLAGS "-Wno-conversion -Wno-cast-qual" -) +if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + set_source_files_properties( + ${TOP}/lib/fatfs/source/ff.c + PROPERTIES + COMPILE_FLAGS "-Wno-conversion -Wno-cast-qual" + ) +endif () # Example include target_include_directories(${PROJECT} PUBLIC diff --git a/examples/host/msc_file_explorer/Makefile b/examples/host/msc_file_explorer/Makefile index 1fda72b18..c7d6a7cae 100644 --- a/examples/host/msc_file_explorer/Makefile +++ b/examples/host/msc_file_explorer/Makefile @@ -1,4 +1,4 @@ -include ../../make.mk +include ../../build_system/make/make.mk FATFS_PATH = lib/fatfs/source @@ -24,14 +24,4 @@ SRC_C += \ # suppress warning caused by fatfs CFLAGS += -Wno-error=cast-qual -# TinyUSB Host Stack source -SRC_C += \ - src/class/cdc/cdc_host.c \ - src/class/hid/hid_host.c \ - src/class/msc/msc_host.c \ - src/host/hub.c \ - src/host/usbh.c \ - src/portable/ohci/ohci.c \ - src/portable/nxp/lpc17_40/hcd_lpc17_40.c - -include ../../rules.mk +include ../../build_system/make/rules.mk diff --git a/examples/host/msc_file_explorer/only.txt b/examples/host/msc_file_explorer/only.txt index f8aa2186f..fee10f9e2 100644 --- a/examples/host/msc_file_explorer/only.txt +++ b/examples/host/msc_file_explorer/only.txt @@ -1,3 +1,4 @@ +mcu:KINETIS_KL mcu:LPC175X_6X mcu:LPC177X_8X mcu:LPC18XX @@ -10,3 +11,4 @@ mcu:RP2040 mcu:MSP432E4 mcu:RX65X mcu:RAXXX +mcu:MAX3421 diff --git a/examples/host/msc_file_explorer/src/main.c b/examples/host/msc_file_explorer/src/main.c index 73f3e9eb5..f6b6810f5 100644 --- a/examples/host/msc_file_explorer/src/main.c +++ b/examples/host/msc_file_explorer/src/main.c @@ -72,8 +72,7 @@ extern bool msc_app_init(void); extern void msc_app_task(void); /*------------- MAIN -------------*/ -int main(void) -{ +int main(void) { board_init(); printf("TinyUSB Host MassStorage Explorer Example\r\n"); @@ -87,8 +86,7 @@ int main(void) msc_app_init(); - while (1) - { + while (1) { // tinyusb host task tuh_task(); @@ -103,28 +101,25 @@ int main(void) // TinyUSB Callbacks //--------------------------------------------------------------------+ -void tuh_mount_cb(uint8_t dev_addr) -{ +void tuh_mount_cb(uint8_t dev_addr) { (void) dev_addr; } -void tuh_umount_cb(uint8_t dev_addr) -{ +void tuh_umount_cb(uint8_t dev_addr) { (void) dev_addr; } //--------------------------------------------------------------------+ // Blinking Task //--------------------------------------------------------------------+ -void led_blinking_task(void) -{ +void led_blinking_task(void) { const uint32_t interval_ms = 1000; static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms - if ( board_millis() - start_ms < interval_ms) return; // not enough time + if (board_millis() - start_ms < interval_ms) return; // not enough time start_ms += interval_ms; board_led_write(led_state); diff --git a/examples/host/msc_file_explorer/src/msc_app.c b/examples/host/msc_file_explorer/src/msc_app.c index 323dfb9e7..ddd39c674 100644 --- a/examples/host/msc_file_explorer/src/msc_app.c +++ b/examples/host/msc_file_explorer/src/msc_app.c @@ -66,7 +66,10 @@ bool msc_app_init(void) for(size_t i=0; icbw; @@ -111,7 +113,7 @@ bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_da uint32_t const block_count = tuh_msc_get_block_count(dev_addr, cbw->lun); uint32_t const block_size = tuh_msc_get_block_size(dev_addr, cbw->lun); - printf("Disk Size: %lu MB\r\n", block_count / ((1024*1024)/block_size)); + printf("Disk Size: %" PRIu32 " MB\r\n", block_count / ((1024*1024)/block_size)); // printf("Block Count = %lu, Block Size: %lu\r\n", block_count, block_size); // For simplicity: we only mount 1 LUN per device @@ -538,10 +540,10 @@ void cli_cmd_ls(EmbeddedCli *cli, char *args, void *context) printf("%-40s", fno.fname); if (fno.fsize < 1024) { - printf("%lu B\r\n", fno.fsize); + printf("%" PRIu32 " B\r\n", fno.fsize); }else { - printf("%lu KB\r\n", fno.fsize / 1024); + printf("%" PRIu32 " KB\r\n", fno.fsize / 1024); } } } diff --git a/examples/host/msc_file_explorer/src/tusb_config.h b/examples/host/msc_file_explorer/src/tusb_config.h index 1e0d067bf..c798b4383 100644 --- a/examples/host/msc_file_explorer/src/tusb_config.h +++ b/examples/host/msc_file_explorer/src/tusb_config.h @@ -30,28 +30,8 @@ extern "C" { #endif -//--------------------------------------------------------------------+ -// Board Specific Configuration -//--------------------------------------------------------------------+ - -#if CFG_TUSB_MCU == OPT_MCU_RP2040 -// change to 1 if using pico-pio-usb as host controller for raspberry rp2040 -#define CFG_TUH_RPI_PIO_USB 0 -#define BOARD_TUH_RHPORT CFG_TUH_RPI_PIO_USB -#endif - -// RHPort number used for host can be defined by board.mk, default to port 0 -#ifndef BOARD_TUH_RHPORT -#define BOARD_TUH_RHPORT 0 -#endif - -// RHPort max operational speed can defined by board.mk -#ifndef BOARD_TUH_MAX_SPEED -#define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED -#endif - //-------------------------------------------------------------------- -// COMMON CONFIGURATION +// Common Configuration //-------------------------------------------------------------------- // defined by compiler flags for flexibility @@ -67,12 +47,6 @@ #define CFG_TUSB_DEBUG 0 #endif -// Enable Host stack -#define CFG_TUH_ENABLED 1 - -// Default is max speed that hardware controller could support with on-chip PHY -#define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED - /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put * into those specific section. @@ -85,11 +59,43 @@ #endif #ifndef CFG_TUH_MEM_ALIGN -#define CFG_TUH_MEM_ALIGN __attribute__ ((aligned(4))) +#define CFG_TUH_MEM_ALIGN __attribute__ ((aligned(4))) #endif //-------------------------------------------------------------------- -// CONFIGURATION +// Host Configuration +//-------------------------------------------------------------------- + +// Enable Host stack +#define CFG_TUH_ENABLED 1 + +#if CFG_TUSB_MCU == OPT_MCU_RP2040 + // #define CFG_TUH_RPI_PIO_USB 1 // use pio-usb as host controller + // #define CFG_TUH_MAX3421 1 // use max3421 as host controller + + // host roothub port is 1 if using either pio-usb or max3421 + #if (defined(CFG_TUH_RPI_PIO_USB) && CFG_TUH_RPI_PIO_USB) || (defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421) + #define BOARD_TUH_RHPORT 1 + #endif +#endif + +// Default is max speed that hardware controller could support with on-chip PHY +#define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED + +//------------------------- Board Specific -------------------------- + +// RHPort number used for host can be defined by board.mk, default to port 0 +#ifndef BOARD_TUH_RHPORT +#define BOARD_TUH_RHPORT 0 +#endif + +// RHPort max operational speed can defined by board.mk +#ifndef BOARD_TUH_MAX_SPEED +#define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED +#endif + +//-------------------------------------------------------------------- +// Driver Configuration //-------------------------------------------------------------------- // Size of buffer to hold descriptors and other data used for enumeration diff --git a/examples/typec/power_delivery/Makefile b/examples/typec/power_delivery/Makefile index 2a3d854fb..7fa475da5 100644 --- a/examples/typec/power_delivery/Makefile +++ b/examples/typec/power_delivery/Makefile @@ -1,4 +1,4 @@ -include ../../make.mk +include ../../build_system/make/make.mk INC += \ src \ @@ -8,4 +8,4 @@ INC += \ EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) -include ../../rules.mk +include ../../build_system/make/rules.mk diff --git a/hw/bsp/board.c b/hw/bsp/board.c index 417630a03..bb339f613 100644 --- a/hw/bsp/board.c +++ b/hw/bsp/board.c @@ -46,15 +46,13 @@ #if !(defined __SES_ARM) && !(defined __SES_RISCV) && !(defined __CROSSWORKS_ARM) #include "SEGGER_RTT.h" -TU_ATTR_USED int sys_write (int fhdl, const void *buf, size_t count) -{ +TU_ATTR_USED int sys_write(int fhdl, const char *buf, size_t count) { (void) fhdl; - SEGGER_RTT_Write(0, (const char*) buf, (int) count); - return count; + SEGGER_RTT_Write(0, (const char *) buf, (int) count); + return (int) count; } -TU_ATTR_USED int sys_read (int fhdl, char *buf, size_t count) -{ +TU_ATTR_USED int sys_read(int fhdl, char *buf, size_t count) { (void) fhdl; int rd = (int) SEGGER_RTT_Read(0, buf, count); return (rd > 0) ? rd : -1; @@ -64,11 +62,9 @@ TU_ATTR_USED int sys_read (int fhdl, char *buf, size_t count) #elif defined(LOGGER_SWO) // Logging with SWO for ARM Cortex - #include "board_mcu.h" -TU_ATTR_USED int sys_write (int fhdl, const void *buf, size_t count) -{ +TU_ATTR_USED int sys_write (int fhdl, const char *buf, size_t count) { (void) fhdl; uint8_t const* buf8 = (uint8_t const*) buf; @@ -79,8 +75,7 @@ TU_ATTR_USED int sys_write (int fhdl, const void *buf, size_t count) return (int) count; } -TU_ATTR_USED int sys_read (int fhdl, char *buf, size_t count) -{ +TU_ATTR_USED int sys_read (int fhdl, char *buf, size_t count) { (void) fhdl; (void) buf; (void) count; @@ -90,14 +85,12 @@ TU_ATTR_USED int sys_read (int fhdl, char *buf, size_t count) #else // Default logging with on-board UART -TU_ATTR_USED int sys_write (int fhdl, const void *buf, size_t count) -{ +TU_ATTR_USED int sys_write (int fhdl, const char *buf, size_t count) { (void) fhdl; return board_uart_write(buf, (int) count); } -TU_ATTR_USED int sys_read (int fhdl, char *buf, size_t count) -{ +TU_ATTR_USED int sys_read (int fhdl, char *buf, size_t count) { (void) fhdl; int rd = board_uart_read((uint8_t*) buf, (int) count); return (rd > 0) ? rd : -1; @@ -105,8 +98,39 @@ TU_ATTR_USED int sys_read (int fhdl, char *buf, size_t count) #endif -int board_getchar(void) -{ - char c; - return ( sys_read(0, &c, 1) > 0 ) ? (int) c : (-1); +//TU_ATTR_USED int _close(int fhdl) { +// (void) fhdl; +// return 0; +//} + +//TU_ATTR_USED int _fstat(int file, struct stat *st) { +// memset(st, 0, sizeof(*st)); +// st->st_mode = S_IFCHR; +//} + +// Clang use picolibc +#if defined(__clang__) +static int cl_putc(char c, FILE *f) { + (void) f; + return sys_write(0, &c, 1); +} + +static int cl_getc(FILE* f) { + (void) f; + char c; + return sys_read(0, &c, 1) > 0 ? c : -1; +} + +static FILE __stdio = FDEV_SETUP_STREAM(cl_putc, cl_getc, NULL, _FDEV_SETUP_RW); +FILE *const stdin = &__stdio; +__strong_reference(stdin, stdout); +__strong_reference(stdin, stderr); +#endif + +//--------------------------------------------------------------------+ +// Board API +//--------------------------------------------------------------------+ +int board_getchar(void) { + char c; + return (sys_read(0, &c, 1) > 0) ? (int) c : (-1); } diff --git a/hw/bsp/board_api.h b/hw/bsp/board_api.h index a7dcabfcc..eee9ed9c5 100644 --- a/hw/bsp/board_api.h +++ b/hw/bsp/board_api.h @@ -32,10 +32,30 @@ extern "C" { #endif #include +#include #include +#include #include "tusb.h" +#if CFG_TUSB_OS == OPT_OS_FREERTOS +#if TUP_MCU_ESPRESSIF + // ESP-IDF need "freertos/" prefix in include path. + // CFG_TUSB_OS_INC_PATH should be defined accordingly. + #include "freertos/FreeRTOS.h" + #include "freertos/semphr.h" + #include "freertos/queue.h" + #include "freertos/task.h" + #include "freertos/timers.h" +#else + #include "FreeRTOS.h" + #include "semphr.h" + #include "queue.h" + #include "task.h" + #include "timers.h" +#endif +#endif + // Define the default baudrate #ifndef CFG_BOARD_UART_BAUDRATE #define CFG_BOARD_UART_BAUDRATE 115200 ///< Default baud rate @@ -97,6 +117,10 @@ static inline uint32_t board_millis(void) { return (((uint64_t)rt_tick_get()) * 1000 / RT_TICK_PER_SECOND); } +#elif CFG_TUSB_OS == OPT_OS_CUSTOM +// Implement your own board_millis() in any of .c file +uint32_t board_millis(void); + #else #error "board_millis() is not implemented for this OS" #endif @@ -118,6 +142,7 @@ static inline size_t board_usb_get_serial(uint16_t desc_str1[], size_t max_chars uint8_t uid[16] TU_ATTR_ALIGNED(4); size_t uid_len; + // TODO work with make, but not working with esp32s3 cmake if ( board_get_unique_id ) { uid_len = board_get_unique_id(uid, sizeof(uid)); }else { diff --git a/hw/bsp/board_mcu.h b/hw/bsp/board_mcu.h index e5d2bb608..013eb1c83 100644 --- a/hw/bsp/board_mcu.h +++ b/hw/bsp/board_mcu.h @@ -40,22 +40,22 @@ // Include order follows OPT_MCU_ number #if TU_CHECK_MCU(OPT_MCU_LPC11UXX, OPT_MCU_LPC13XX, OPT_MCU_LPC15XX) || \ - TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC18XX) || \ - TU_CHECK_MCU(OPT_MCU_LPC40XX, OPT_MCU_LPC43XX) + TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC18XX) || \ + TU_CHECK_MCU(OPT_MCU_LPC40XX, OPT_MCU_LPC43XX) #include "chip.h" #elif TU_CHECK_MCU(OPT_MCU_LPC51UXX, OPT_MCU_LPC54XXX, OPT_MCU_LPC55XX, OPT_MCU_MCXN9) #include "fsl_device_registers.h" -#elif TU_CHECK_MCU(OPT_MCU_KINETIS_KL, OPT_MCU_KINETIS_K32L) +#elif TU_CHECK_MCU(OPT_MCU_KINETIS_KL, OPT_MCU_KINETIS_K32L, OPT_MCU_KINETIS_K) #include "fsl_device_registers.h" #elif CFG_TUSB_MCU == OPT_MCU_NRF5X #include "nrf.h" #elif CFG_TUSB_MCU == OPT_MCU_SAMD11 || CFG_TUSB_MCU == OPT_MCU_SAMD21 || \ - CFG_TUSB_MCU == OPT_MCU_SAMD51 || CFG_TUSB_MCU == OPT_MCU_SAME5X || \ - CFG_TUSB_MCU == OPT_MCU_SAML22 || CFG_TUSB_MCU == OPT_MCU_SAML21 + CFG_TUSB_MCU == OPT_MCU_SAMD51 || CFG_TUSB_MCU == OPT_MCU_SAME5X || \ + CFG_TUSB_MCU == OPT_MCU_SAML22 || CFG_TUSB_MCU == OPT_MCU_SAML21 #include "sam.h" #elif CFG_TUSB_MCU == OPT_MCU_SAMG @@ -83,6 +83,9 @@ #elif CFG_TUSB_MCU == OPT_MCU_STM32G4 #include "stm32g4xx.h" +#elif CFG_TUSB_MCU == OPT_MCU_STM32H5 + #include "stm32h5xx.h" + #elif CFG_TUSB_MCU == OPT_MCU_STM32H7 #include "stm32h7xx.h" @@ -161,6 +164,9 @@ #elif CFG_TUSB_MCU == OPT_MCU_TM4C123 #include "TM4C123.h" +#elif CFG_TUSB_MCU == OPT_MCU_CH32F20X + #include "ch32f20x.h" + #elif TU_CHECK_MCU(OPT_MCU_BCM2711, OPT_MCU_BCM2835, OPT_MCU_BCM2837) // no header needed diff --git a/hw/bsp/broadcom_32bit/boards/raspberrypi_zero/board.cmake b/hw/bsp/broadcom_32bit/boards/raspberrypi_zero/board.cmake new file mode 100644 index 000000000..2b8cc19e0 --- /dev/null +++ b/hw/bsp/broadcom_32bit/boards/raspberrypi_zero/board.cmake @@ -0,0 +1,8 @@ +set(CMAKE_SYSTEM_PROCESSOR arm1176jzf-s CACHE INTERNAL "System Processor") +#set(SUFFIX "") + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + BCM_VERSION=2835 + ) +endfunction() diff --git a/hw/bsp/broadcom_32bit/boards/raspberrypi_zero_w/board.h b/hw/bsp/broadcom_32bit/boards/raspberrypi_zero/board.h similarity index 100% rename from hw/bsp/broadcom_32bit/boards/raspberrypi_zero_w/board.h rename to hw/bsp/broadcom_32bit/boards/raspberrypi_zero/board.h diff --git a/hw/bsp/broadcom_32bit/boards/raspberrypi_zero_w/board.mk b/hw/bsp/broadcom_32bit/boards/raspberrypi_zero/board.mk similarity index 77% rename from hw/bsp/broadcom_32bit/boards/raspberrypi_zero_w/board.mk rename to hw/bsp/broadcom_32bit/boards/raspberrypi_zero/board.mk index 052033230..7a248ed24 100644 --- a/hw/bsp/broadcom_32bit/boards/raspberrypi_zero_w/board.mk +++ b/hw/bsp/broadcom_32bit/boards/raspberrypi_zero/board.mk @@ -1,4 +1,4 @@ -CPU_CORE = arm1176 +CPU_CORE = arm1176jzf-s CFLAGS += -DBCM_VERSION=2835 \ -DCFG_TUSB_MCU=OPT_MCU_BCM2835 diff --git a/hw/bsp/broadcom_32bit/family.c b/hw/bsp/broadcom_32bit/family.c index 664b4dcaf..0062e2e83 100644 --- a/hw/bsp/broadcom_32bit/family.c +++ b/hw/bsp/broadcom_32bit/family.c @@ -27,6 +27,13 @@ #include "bsp/board_api.h" #include "board.h" +// Suppress warning caused by mcu driver +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" +#pragma GCC diagnostic ignored "-Wredundant-decls" +#endif + #include "broadcom/cpu.h" #include "broadcom/gpio.h" #include "broadcom/interrupts.h" @@ -34,6 +41,10 @@ #include "broadcom/caches.h" #include "broadcom/vcmailbox.h" +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + // LED #define LED_PIN 18 #define LED_STATE_ON 1 @@ -44,8 +55,7 @@ //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ -void USB_IRQHandler(void) -{ +void USB_IRQHandler(void) { tud_int_handler(0); } @@ -56,8 +66,7 @@ void USB_IRQHandler(void) //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ -void board_init(void) -{ +void board_init(void) { setup_mmu_flat_map(); init_caches(); @@ -97,24 +106,21 @@ void board_init(void) BP_EnableIRQs(); } -void board_led_write(bool state) -{ - gpio_set_value(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +void board_led_write(bool state) { + gpio_set_value(LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { return 0; } -int board_uart_read(uint8_t* buf, int len) -{ - (void) buf; (void) len; +int board_uart_read(uint8_t* buf, int 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) { for (int i = 0; i < len; i++) { const char* cbuf = buf; while (!UART1->STAT_b.TX_READY) {} @@ -127,30 +133,27 @@ int board_uart_write(void const * buf, int len) return len; } -#if CFG_TUSB_OS == OPT_OS_NONE +#if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; -void TIMER_1_IRQHandler(void) -{ +void TIMER_1_IRQHandler(void) { system_ticks++; SYSTMR->C1 += 977; SYSTMR->CS_b.M1 = 1; } -uint32_t board_millis(void) -{ +uint32_t board_millis(void) { return system_ticks; } + #endif -void HardFault_Handler (void) -{ +void HardFault_Handler(void) { // asm("bkpt"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. -void _init(void) -{ +void _init(void) { } diff --git a/hw/bsp/broadcom_32bit/family.cmake b/hw/bsp/broadcom_32bit/family.cmake new file mode 100644 index 000000000..6205d4e1b --- /dev/null +++ b/hw/bsp/broadcom_32bit/family.cmake @@ -0,0 +1,108 @@ +include_guard() + +set(SDK_DIR ${TOP}/hw/mcu/broadcom) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS BCM2835 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 () + + if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${SDK_DIR}/broadcom/link.ld) + endif () + set(LD_FILE_Clang ${LD_FILE_GNU}) + + set(STARTUP_FILE_GNU ${SDK_DIR}/broadcom/boot.s) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${SDK_DIR}/broadcom/gen/interrupt_handlers.c + ${SDK_DIR}/broadcom/gpio.c + ${SDK_DIR}/broadcom/interrupts.c + ${SDK_DIR}/broadcom/mmu.c + ${SDK_DIR}/broadcom/caches.c + ${SDK_DIR}/broadcom/vcmailbox.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_compile_options(${BOARD_TARGET} PUBLIC + -O0 + -ffreestanding + -mgeneral-regs-only + -fno-exceptions + -std=c17 + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_DIR} + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + "LINKER:--entry=_start" + --specs=nosys.specs + -nostartfiles + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + "LINKER:--entry=_start" + ) + 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_BCM2835 ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.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}) +endfunction() diff --git a/hw/bsp/broadcom_32bit/family.mk b/hw/bsp/broadcom_32bit/family.mk index cf68e21ee..e15bd93f7 100644 --- a/hw/bsp/broadcom_32bit/family.mk +++ b/hw/bsp/broadcom_32bit/family.mk @@ -1,5 +1,4 @@ MCU_DIR = hw/mcu/broadcom -DEPS_SUBMODULES += $(MCU_DIR) include $(TOP)/$(BOARD_PATH)/board.mk @@ -27,15 +26,13 @@ SRC_C += \ $(MCU_DIR)/broadcom/caches.c \ $(MCU_DIR)/broadcom/vcmailbox.c -SKIP_NANOLIB = 1 - LD_FILE = $(MCU_DIR)/broadcom/link$(SUFFIX).ld INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(MCU_DIR) -SRC_S += $(MCU_DIR)/broadcom/boot$(SUFFIX).S +SRC_S += $(MCU_DIR)/broadcom/boot$(SUFFIX).s $(BUILD)/kernel$(SUFFIX).img: $(BUILD)/$(PROJECT).elf $(OBJCOPY) -O binary $^ $@ diff --git a/hw/bsp/broadcom_64bit/boards/raspberrypi_cm4/board.cmake b/hw/bsp/broadcom_64bit/boards/raspberrypi_cm4/board.cmake new file mode 100644 index 000000000..919068f1d --- /dev/null +++ b/hw/bsp/broadcom_64bit/boards/raspberrypi_cm4/board.cmake @@ -0,0 +1,5 @@ +set(CMAKE_SYSTEM_PROCESSOR cortex-a72 CACHE INTERNAL "System Processor") +set(BCM_VERSION 2711) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2/board.cmake b/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2/board.cmake new file mode 100644 index 000000000..85f84e947 --- /dev/null +++ b/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2/board.cmake @@ -0,0 +1,5 @@ +set(CMAKE_SYSTEM_PROCESSOR cortex-a53 CACHE INTERNAL "System Processor") +set(BCM_VERSION 2837) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2w/board.h b/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2/board.h similarity index 100% rename from hw/bsp/broadcom_64bit/boards/raspberrypi_zero2w/board.h rename to hw/bsp/broadcom_64bit/boards/raspberrypi_zero2/board.h diff --git a/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2w/board.mk b/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2/board.mk similarity index 100% rename from hw/bsp/broadcom_64bit/boards/raspberrypi_zero2w/board.mk rename to hw/bsp/broadcom_64bit/boards/raspberrypi_zero2/board.mk diff --git a/hw/bsp/broadcom_64bit/family.c b/hw/bsp/broadcom_64bit/family.c index 664b4dcaf..0062e2e83 100644 --- a/hw/bsp/broadcom_64bit/family.c +++ b/hw/bsp/broadcom_64bit/family.c @@ -27,6 +27,13 @@ #include "bsp/board_api.h" #include "board.h" +// Suppress warning caused by mcu driver +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" +#pragma GCC diagnostic ignored "-Wredundant-decls" +#endif + #include "broadcom/cpu.h" #include "broadcom/gpio.h" #include "broadcom/interrupts.h" @@ -34,6 +41,10 @@ #include "broadcom/caches.h" #include "broadcom/vcmailbox.h" +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + // LED #define LED_PIN 18 #define LED_STATE_ON 1 @@ -44,8 +55,7 @@ //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ -void USB_IRQHandler(void) -{ +void USB_IRQHandler(void) { tud_int_handler(0); } @@ -56,8 +66,7 @@ void USB_IRQHandler(void) //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ -void board_init(void) -{ +void board_init(void) { setup_mmu_flat_map(); init_caches(); @@ -97,24 +106,21 @@ void board_init(void) BP_EnableIRQs(); } -void board_led_write(bool state) -{ - gpio_set_value(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +void board_led_write(bool state) { + gpio_set_value(LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { return 0; } -int board_uart_read(uint8_t* buf, int len) -{ - (void) buf; (void) len; +int board_uart_read(uint8_t* buf, int 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) { for (int i = 0; i < len; i++) { const char* cbuf = buf; while (!UART1->STAT_b.TX_READY) {} @@ -127,30 +133,27 @@ int board_uart_write(void const * buf, int len) return len; } -#if CFG_TUSB_OS == OPT_OS_NONE +#if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; -void TIMER_1_IRQHandler(void) -{ +void TIMER_1_IRQHandler(void) { system_ticks++; SYSTMR->C1 += 977; SYSTMR->CS_b.M1 = 1; } -uint32_t board_millis(void) -{ +uint32_t board_millis(void) { return system_ticks; } + #endif -void HardFault_Handler (void) -{ +void HardFault_Handler(void) { // asm("bkpt"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. -void _init(void) -{ +void _init(void) { } diff --git a/hw/bsp/broadcom_64bit/family.cmake b/hw/bsp/broadcom_64bit/family.cmake new file mode 100644 index 000000000..f373dc633 --- /dev/null +++ b/hw/bsp/broadcom_64bit/family.cmake @@ -0,0 +1,115 @@ +include_guard() + +set(SDK_DIR ${TOP}/hw/mcu/broadcom) +set(CMSIS_5 ${TOP}/lib/CMSIS_5) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/aarch64_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS BCM2711 BCM2835 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 () + + if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${SDK_DIR}/broadcom/link8.ld) + endif () + set(LD_FILE_Clang ${LD_FILE_GNU}) + + set(STARTUP_FILE_GNU ${SDK_DIR}/broadcom/boot8.s) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${SDK_DIR}/broadcom/gen/interrupt_handlers.c + ${SDK_DIR}/broadcom/gpio.c + ${SDK_DIR}/broadcom/interrupts.c + ${SDK_DIR}/broadcom/mmu.c + ${SDK_DIR}/broadcom/caches.c + ${SDK_DIR}/broadcom/vcmailbox.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_compile_options(${BOARD_TARGET} PUBLIC + -O0 + -ffreestanding + -mgeneral-regs-only + -fno-exceptions + -std=c17 + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + BCM_VERSION=${BCM_VERSION} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_DIR} + ${CMSIS_5}/CMSIS/Core_A/Include + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") +# target_compile_options(${BOARD_TARGET} PUBLIC +# ) + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + "LINKER:--entry=_start" + --specs=nosys.specs + -nostartfiles + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + "LINKER:--entry=_start" + ) + 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_BCM${BCM_VERSION} ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.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}) +endfunction() diff --git a/hw/bsp/broadcom_64bit/family.mk b/hw/bsp/broadcom_64bit/family.mk index 97af6d64a..89f798f19 100644 --- a/hw/bsp/broadcom_64bit/family.mk +++ b/hw/bsp/broadcom_64bit/family.mk @@ -1,6 +1,4 @@ MCU_DIR = hw/mcu/broadcom -DEPS_SUBMODULES += $(MCU_DIR) - include $(TOP)/$(BOARD_PATH)/board.mk CFLAGS += \ @@ -9,6 +7,7 @@ CFLAGS += \ -ffreestanding \ -nostdlib \ -nostartfiles \ + --specs=nosys.specs \ -mgeneral-regs-only \ -std=c17 @@ -26,8 +25,6 @@ SRC_C += \ $(MCU_DIR)/broadcom/caches.c \ $(MCU_DIR)/broadcom/vcmailbox.c -SKIP_NANOLIB = 1 - LD_FILE = $(MCU_DIR)/broadcom/link8.ld INC += \ @@ -35,7 +32,7 @@ INC += \ $(TOP)/$(MCU_DIR) \ $(TOP)/lib/CMSIS_5/CMSIS/Core_A/Include -SRC_S += $(MCU_DIR)/broadcom/boot8.S +SRC_S += $(MCU_DIR)/broadcom/boot8.s $(BUILD)/kernel8.img: $(BUILD)/$(PROJECT).elf $(OBJCOPY) -O binary $^ $@ diff --git a/hw/bsp/ch32f20x/boards/ch32f205r-r0/board.h b/hw/bsp/ch32f20x/boards/ch32f205r-r0/board.h new file mode 100644 index 000000000..d5849bddb --- /dev/null +++ b/hw/bsp/ch32f20x/boards/ch32f205r-r0/board.h @@ -0,0 +1,59 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2023, Denis Krasutski + * + * 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. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// LED: need to wire pin LED1 to PC0 in the P1 header +#define LED_PORT GPIOC +#define LED_PIN GPIO_Pin_1 +#define LED_STATE_ON 0 +#define LED_CLOCK_EN() RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE) + +// Button: need to wire pin KEY to PC1 in the P1 header +#define BUTTON_PORT GPIOC +#define BUTTON_PIN GPIO_Pin_0 +#define BUTTON_STATE_ACTIVE 0 +#define BUTTON_CLOCK_EN() RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE) + +// UART +#define UART_DEV USART2 +#define UART_DEV_IRQn USART2_IRQn +#define UART_DEV_IRQHandler USART2_IRQHandler +#define UART_DEV_GPIO_PORT GPIOA +#define UART_DEV_TX_PIN GPIO_Pin_2 +#define UART_DEV_CLK_EN() do { \ + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); \ + RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); \ + } while(0) + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/hw/bsp/ch32f20x/boards/ch32f205r-r0/board.mk b/hw/bsp/ch32f20x/boards/ch32f205r-r0/board.mk new file mode 100644 index 000000000..f0e9bf30f --- /dev/null +++ b/hw/bsp/ch32f20x/boards/ch32f205r-r0/board.mk @@ -0,0 +1,7 @@ +LD_FILE = $(FAMILY_PATH)/ch32f205.ld + +SRC_S += \ + $(FAMILY_PATH)/startup_gcc_ch32f20x_d8c.s + +CFLAGS += \ + -DCH32F20x_D8C diff --git a/hw/bsp/ch32f20x/ch32f205.ld b/hw/bsp/ch32f20x/ch32f205.ld new file mode 100644 index 000000000..7c8d04cc5 --- /dev/null +++ b/hw/bsp/ch32f20x/ch32f205.ld @@ -0,0 +1,111 @@ +ENTRY(Reset_Handler) + +_Min_Heap_Size = 0x200; +_Min_Stack_Size = 0x400; + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K +} +SECTIONS +{ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) + . = ALIGN(4); + } >FLASH + + .text : + { + . = ALIGN(4); + _stext = .; + *(.text) + *(.text*) + *(.glue_7) + *(.glue_7t) + *(.eh_frame) + KEEP (*(.init)) + KEEP (*(.fini)) + . = ALIGN(4); + _etext = .; + } >FLASH + .rodata : + { + . = ALIGN(4); + *(.rodata) + *(.rodata*) + . = ALIGN(4); + } >FLASH + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + _sidata = LOADADDR(.data); + .data : + { + . = ALIGN(4); + _sdata = .; + *(.data) + *(.data*) + . = ALIGN(4); + _edata = .; + } >RAM AT> FLASH + . = ALIGN(4); + .bss : + { + _sbss = .; + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + . = ALIGN(4); + _ebss = .; + __bss_end__ = _ebss; + } >RAM + ._user_heap_stack : + { + . = ALIGN(4); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + __HeapStart = .; + . = . + _Min_Heap_Size; + __HeapEnd = .; + __StackLimit = .; + . = . + _Min_Stack_Size; + __StackTop = .; + . = ALIGN(4); + } >RAM +_estack = __StackTop; +_sstack = __StackLimit; + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/ch32f20x/ch32f20x_conf.h b/hw/bsp/ch32f20x/ch32f20x_conf.h new file mode 100644 index 000000000..05199ff95 --- /dev/null +++ b/hw/bsp/ch32f20x/ch32f20x_conf.h @@ -0,0 +1,39 @@ +/********************************** (C) COPYRIGHT ******************************* + * File Name : ch32f20x_conf.h + * Author : WCH + * Version : V1.0.0 + * Date : 2021/08/08 + * Description : Library configuration file. + ********************************************************************************* + * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. + * Attention: This software (modified or not) and binary are used for + * microcontroller manufactured by Nanjing Qinheng Microelectronics. + *******************************************************************************/ +#ifndef __CH32F20x_CONF_H +#define __CH32F20x_CONF_H + +#include "ch32f20x_adc.h" +#include "ch32f20x_bkp.h" +#include "ch32f20x_can.h" +#include "ch32f20x_crc.h" +#include "ch32f20x_dac.h" +#include "ch32f20x_dbgmcu.h" +#include "ch32f20x_dma.h" +#include "ch32f20x_exti.h" +#include "ch32f20x_flash.h" +#include "ch32f20x_fsmc.h" +#include "ch32f20x_gpio.h" +#include "ch32f20x_i2c.h" +#include "ch32f20x_iwdg.h" +#include "ch32f20x_pwr.h" +#include "ch32f20x_rcc.h" +#include "ch32f20x_rtc.h" +#include "ch32f20x_sdio.h" +#include "ch32f20x_spi.h" +#include "ch32f20x_tim.h" +#include "ch32f20x_usart.h" +#include "ch32f20x_wwdg.h" +#include "ch32f20x_it.h" +#include "ch32f20x_misc.h" + +#endif /* __CH32F20x_CONF_H */ diff --git a/hw/bsp/ch32f20x/ch32f20x_it.c b/hw/bsp/ch32f20x/ch32f20x_it.c new file mode 100644 index 000000000..94e28e380 --- /dev/null +++ b/hw/bsp/ch32f20x/ch32f20x_it.c @@ -0,0 +1,35 @@ +#include "ch32f20x_it.h" + +#include "ch32f20x.h" + +/* -------------------------------------------------------------------------- */ + +void NMI_Handler(void) { + +} + +/* -------------------------------------------------------------------------- */ + +void MemManage_Handler(void) { + +} + +/* -------------------------------------------------------------------------- */ + +void BusFault_Handler(void) { + +} + +/* -------------------------------------------------------------------------- */ + +void UsageFault_Handler(void) { + +} + +/* -------------------------------------------------------------------------- */ + +void DebugMon_Handler(void) { + +} + +/* -------------------------------------------------------------------------- */ diff --git a/hw/bsp/ch32f20x/ch32f20x_it.h b/hw/bsp/ch32f20x/ch32f20x_it.h new file mode 100644 index 000000000..34f3bbf96 --- /dev/null +++ b/hw/bsp/ch32f20x/ch32f20x_it.h @@ -0,0 +1,25 @@ +/********************************** (C) COPYRIGHT ******************************* +* File Name : ch32f20x_it.h +* Author : WCH +* Version : V1.0.0 +* Date : 2021/08/08 +* Description : This file contains the headers of the interrupt handlers. +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#ifndef __CH32F20xIT_H +#define __CH32F20xIT_H + +#include "ch32f20x.h" + +void NMI_Handler(void); +void HardFault_Handler(void); +void MemManage_Handler(void); +void BusFault_Handler(void); +void UsageFault_Handler(void); +void DebugMon_Handler(void); + + +#endif /* __CH32F20xIT_H */ diff --git a/hw/bsp/ch32f20x/core_cm3.h b/hw/bsp/ch32f20x/core_cm3.h new file mode 100644 index 000000000..c35a4eec3 --- /dev/null +++ b/hw/bsp/ch32f20x/core_cm3.h @@ -0,0 +1,11 @@ +/* There is core_cm3.h wrapper just to avoid warnings from CMSIS headers */ +/* if you want use original file add to make file: + INC += \ + $(TOP)/$(CH32F20X_SDK_SRC)/CMSIS +*/ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" + +#include <../../CMSIS/core_cm3.h> + +#pragma GCC diagnostic pop diff --git a/hw/bsp/ch32f20x/debug_uart.c b/hw/bsp/ch32f20x/debug_uart.c new file mode 100644 index 000000000..a595eb6f7 --- /dev/null +++ b/hw/bsp/ch32f20x/debug_uart.c @@ -0,0 +1,105 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2023 Denis Krasutski + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ +#include + +#include "board.h" +#include "debug_uart.h" + +#define UART_RINGBUFFER_SIZE_TX 64 +#define UART_RINGBUFFER_MASK_TX (UART_RINGBUFFER_SIZE_TX-1) + +static char tx_buf[UART_RINGBUFFER_SIZE_TX]; +static unsigned int tx_produce = 0; +static volatile unsigned int tx_consume = 0; + +void UART_DEV_IRQHandler(void) +{ + if(USART_GetITStatus(UART_DEV, USART_IT_TC) != RESET) { + USART_ClearITPendingBit(UART_DEV, USART_IT_TC); + + if(tx_consume != tx_produce) { + USART_SendData(UART_DEV, tx_buf[tx_consume]); + tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX; + } + } +} + +void uart_write(char c) +{ + unsigned int tx_produce_next = (tx_produce + 1) & UART_RINGBUFFER_MASK_TX; + + NVIC_DisableIRQ(UART_DEV_IRQn); + if((tx_consume != tx_produce) || (USART_GetFlagStatus(UART_DEV, USART_FLAG_TXE) == RESET)) { + tx_buf[tx_produce] = c; + tx_produce = tx_produce_next; + } else { + USART_SendData(UART_DEV, c); + } + NVIC_EnableIRQ(UART_DEV_IRQn); +} + +void uart_sync(void) +{ + while(tx_consume != tx_produce) { + //Waiting for transfer complete + } +} + +void usart_printf_init(uint32_t baudrate) +{ + tx_produce = 0; + tx_consume = 0; + + UART_DEV_CLK_EN(); + + GPIO_InitTypeDef gpio_config = { + .GPIO_Pin = UART_DEV_TX_PIN, + .GPIO_Speed = GPIO_Speed_50MHz, + .GPIO_Mode = GPIO_Mode_AF_PP, + }; + GPIO_Init(UART_DEV_GPIO_PORT, &gpio_config); + + USART_InitTypeDef uart_config = { + .USART_BaudRate = baudrate, + .USART_WordLength = USART_WordLength_8b, + .USART_StopBits = USART_StopBits_1, + .USART_Parity = USART_Parity_No, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + .USART_Mode = USART_Mode_Tx, + }; + + USART_Init(UART_DEV, &uart_config); + USART_ITConfig(UART_DEV, USART_IT_TC, ENABLE); + USART_Cmd(UART_DEV, ENABLE); + + NVIC_InitTypeDef nvic_config = { + .NVIC_IRQChannel = UART_DEV_IRQn, + .NVIC_IRQChannelPreemptionPriority = 1, + .NVIC_IRQChannelSubPriority = 3, + .NVIC_IRQChannelCmd = ENABLE, + }; + NVIC_Init(&nvic_config); +} diff --git a/hw/bsp/ch32f20x/debug_uart.h b/hw/bsp/ch32f20x/debug_uart.h new file mode 100644 index 000000000..10284cf6f --- /dev/null +++ b/hw/bsp/ch32f20x/debug_uart.h @@ -0,0 +1,31 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2023 Denis Krasutski + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include + +void uart_write(char c); +void uart_sync(void); +void usart_printf_init(uint32_t baudrate); diff --git a/hw/bsp/ch32f20x/family.c b/hw/bsp/ch32f20x/family.c new file mode 100644 index 000000000..9717832d6 --- /dev/null +++ b/hw/bsp/ch32f20x/family.c @@ -0,0 +1,141 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2023 Denis Krasutski + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "stdio.h" +#include "debug_uart.h" + +#include "ch32f20x.h" + +#include "bsp/board_api.h" +#include "board.h" + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ + +void USBHS_IRQHandler(void) +{ + tud_int_handler(0); +} + +void board_init(void) { + + /* Disable interrupts during init */ + __disable_irq(); + +#if CFG_TUSB_OS == OPT_OS_NONE + SysTick_Config(SystemCoreClock / 1000); +#endif + +#if CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(USBHS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); +#endif + + usart_printf_init(115200); + + // USB HS Clock config + RCC_USBCLK48MConfig(RCC_USBCLK48MCLKSource_USBPHY); + RCC_USBHSPLLCLKConfig(RCC_HSBHSPLLCLKSource_HSE); + RCC_USBHSConfig(RCC_USBPLL_Div2); + RCC_USBHSPLLCKREFCLKConfig(RCC_USBHSPLLCKREFCLK_4M); + RCC_USBHSPHYPLLALIVEcmd(ENABLE); + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_USBHS, ENABLE); + + // LED + LED_CLOCK_EN(); + GPIO_InitTypeDef led_pin_config = { + .GPIO_Pin = LED_PIN, + .GPIO_Mode = GPIO_Mode_Out_OD, + .GPIO_Speed = GPIO_Speed_50MHz, + }; + GPIO_Init(LED_PORT, &led_pin_config); + + // Button + BUTTON_CLOCK_EN(); + GPIO_InitTypeDef button_pin_config = { + .GPIO_Pin = BUTTON_PIN, + .GPIO_Mode = GPIO_Mode_IPU, + .GPIO_Speed = GPIO_Speed_50MHz, + }; + GPIO_Init(BUTTON_PORT, &button_pin_config); + + /* Enable interrupts globally */ + __enable_irq(); +} + +#if CFG_TUSB_OS == OPT_OS_NONE + +volatile uint32_t system_ticks = 0; + +void SysTick_Handler(void) +{ + system_ticks++; +} + +uint32_t board_millis(void) +{ + return system_ticks; +} + +#endif + +void HardFault_Handler(void) +{ + __asm("BKPT #0\n"); +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + GPIO_WriteBit(LED_PORT, LED_PIN, state); +} + +uint32_t board_button_read(void) +{ + return BUTTON_STATE_ACTIVE == GPIO_ReadInputDataBit(BUTTON_PORT, BUTTON_PIN); +} + +int board_uart_read(uint8_t *buf, int len) +{ + (void) buf; + (void) len; + return 0; +} + +int board_uart_write(void const *buf, int len) +{ + int txsize = len; + while ( txsize-- ) + { + uart_write(*(uint8_t const*) buf); + buf++; + } + return len; +} diff --git a/hw/bsp/ch32f20x/family.mk b/hw/bsp/ch32f20x/family.mk new file mode 100644 index 000000000..c08451b9c --- /dev/null +++ b/hw/bsp/ch32f20x/family.mk @@ -0,0 +1,30 @@ +# Submodules +CH32F20X_SDK = hw/mcu/wch/ch32f20x +DEPS_SUBMODULES += $(CH32F20X_SDK) + +# WCH-SDK paths +CH32F20X_SDK_SRC = $(CH32F20X_SDK)/EVT/EXAM/SRC + +include $(TOP)/$(BOARD_PATH)/board.mk + +CPU_CORE ?= cortex-m3 + +CFLAGS += \ + -DCFG_TUSB_MCU=OPT_MCU_CH32F20X \ + -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + +SRC_C += \ + src/portable/wch/dcd_ch32_usbhs.c \ + $(CH32F20X_SDK_SRC)/StdPeriphDriver/src/ch32f20x_gpio.c \ + $(CH32F20X_SDK_SRC)/StdPeriphDriver/src/ch32f20x_misc.c \ + $(CH32F20X_SDK_SRC)/StdPeriphDriver/src/ch32f20x_rcc.c \ + $(CH32F20X_SDK_SRC)/StdPeriphDriver/src/ch32f20x_usart.c + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/$(CH32F20X_SDK_SRC)/StdPeriphDriver/inc + +# For freeRTOS port source +FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/ARM_CM3 + +flash: flash-stlink diff --git a/hw/bsp/ch32f20x/startup_gcc_ch32f20x_d8c.s b/hw/bsp/ch32f20x/startup_gcc_ch32f20x_d8c.s new file mode 100644 index 000000000..2ecac2ac1 --- /dev/null +++ b/hw/bsp/ch32f20x/startup_gcc_ch32f20x_d8c.s @@ -0,0 +1,493 @@ +/** + ****************************************************************************** + * @file startup_gcc_ch32f20x_d8c.s + * @author Denis Krasutski + * @brief CH32F205 Devices vector table + * This module performs: + * - Set the initial SP + * - Set the initial PC == Reset_Handler, + * - Set the vector table entries with the exceptions ISR address + * - Branches to main in the C library (which eventually + * calls main()). + * After Reset the Cortex-M3 processor is in Thread mode, + * priority is Privileged, and the Stack is set to Main. + ****************************************************************************** + */ + +.syntax unified +.cpu cortex-m3 +.thumb +.global g_pfnVectors +.global Default_Handler + +/* start address for the initialization values of the .data section. defined in linker script */ +.word _sidata +/* start address for the .data section. defined in linker script */ +.word _sdata +/* end address for the .data section. defined in linker script */ +.word _edata +/* start address for the .bss section. defined in linker script */ +.word _sbss +/* end address for the .bss section. defined in linker script */ +.word _ebss + +.section .text.Reset_Handler +.weak Reset_Handler +.type Reset_Handler, %function +Reset_Handler: + /* set stack pointer */ + ldr sp, =_estack + /* Call the clock system initialization function.*/ + bl SystemInit + /* Copy the data segment initializers from flash to SRAM */ + ldr r0, =_sdata + ldr r1, =_edata + ldr r2, =_sidata + movs r3, #0 + b LoopCopyDataInit +CopyDataInit: + ldr r4, [r2, r3] + str r4, [r0, r3] + adds r3, r3, #4 +LoopCopyDataInit: + adds r4, r0, r3 + cmp r4, r1 + bcc CopyDataInit + + /* Zero fill the bss segment. */ + ldr r2, =_sbss + ldr r4, =_ebss + movs r3, #0 + b LoopFillZerobss +FillZerobss: + str r3, [r2] + adds r2, r2, #4 +LoopFillZerobss: + cmp r2, r4 + bcc FillZerobss + /* Call static constructors */ + bl __libc_init_array + /* Call the application's entry point.*/ + bl main + bx lr + .size Reset_Handler, .-Reset_Handler + +.section .text.Default_Handler,"ax",%progbits +Default_Handler: +Infinite_Loop: + b Infinite_Loop + .size Default_Handler, .-Default_Handler + +/****************************************************************************** +* +* The minimal vector table for a Cortex M3. Note that the proper constructs +* must be placed on this to ensure that it ends up at physical address +* 0x0000.0000. +* +*******************************************************************************/ + .section .isr_vector,"a",%progbits + .type g_pfnVectors, %object + .size g_pfnVectors, .-g_pfnVectors + +g_pfnVectors: + .word _estack + .word Reset_Handler + .word NMI_Handler + .word HardFault_Handler + .word MemManage_Handler + .word BusFault_Handler + .word UsageFault_Handler + .word 0 + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word DebugMon_Handler + .word 0 + .word PendSV_Handler + .word SysTick_Handler + +/******************************************************************************* + External Interrupts +*******************************************************************************/ +.word WWDG_IRQHandler +.word PVD_IRQHandler +.word TAMPER_IRQHandler +.word RTC_IRQHandler +.word FLASH_IRQHandler +.word RCC_IRQHandler +.word EXTI0_IRQHandler +.word EXTI1_IRQHandler +.word EXTI2_IRQHandler +.word EXTI3_IRQHandler +.word EXTI4_IRQHandler +.word DMA1_Channel1_IRQHandler +.word DMA1_Channel2_IRQHandler +.word DMA1_Channel3_IRQHandler +.word DMA1_Channel4_IRQHandler +.word DMA1_Channel5_IRQHandler +.word DMA1_Channel6_IRQHandler +.word DMA1_Channel7_IRQHandler +.word ADC1_2_IRQHandler +.word USB_HP_CAN1_TX_IRQHandler +.word USB_LP_CAN1_RX0_IRQHandler +.word CAN1_RX1_IRQHandler +.word CAN1_SCE_IRQHandler +.word EXTI9_5_IRQHandler +.word TIM1_BRK_IRQHandler +.word TIM1_UP_IRQHandler +.word TIM1_TRG_COM_IRQHandler +.word TIM1_CC_IRQHandler +.word TIM2_IRQHandler +.word TIM3_IRQHandler +.word TIM4_IRQHandler +.word I2C1_EV_IRQHandler +.word I2C1_ER_IRQHandler +.word I2C2_EV_IRQHandler +.word I2C2_ER_IRQHandler +.word SPI1_IRQHandler +.word SPI2_IRQHandler +.word USART1_IRQHandler +.word USART2_IRQHandler +.word USART3_IRQHandler +.word EXTI15_10_IRQHandler +.word RTCAlarm_IRQHandler +.word 0 +.word TIM8_BRK_IRQHandler +.word TIM8_UP_IRQHandler +.word TIM8_TRG_COM_IRQHandler +.word TIM8_CC_IRQHandler +.word RNG_IRQHandler +.word FSMC_IRQHandler +.word SDIO_IRQHandler +.word TIM5_IRQHandler +.word SPI3_IRQHandler +.word UART4_IRQHandler +.word UART5_IRQHandler +.word TIM6_IRQHandler +.word TIM7_IRQHandler +.word DMA2_Channel1_IRQHandler +.word DMA2_Channel2_IRQHandler +.word DMA2_Channel3_IRQHandler +.word DMA2_Channel4_IRQHandler +.word DMA2_Channel5_IRQHandler +.word ETH_IRQHandler +.word ETH_WKUP_IRQHandler +.word CAN2_TX_IRQHandler +.word CAN2_RX0_IRQHandler +.word CAN2_RX1_IRQHandler +.word CAN2_SCE_IRQHandler +.word OTG_FS_IRQHandler +.word USBHSWakeup_IRQHandler +.word USBHS_IRQHandler +.word DVP_IRQHandler +.word UART6_IRQHandler +.word UART7_IRQHandler +.word UART8_IRQHandler +.word TIM9_BRK_IRQHandler +.word TIM9_UP_IRQHandler +.word TIM9_TRG_COM_IRQHandler +.word TIM9_CC_IRQHandler +.word TIM10_BRK_IRQHandler +.word TIM10_UP_IRQHandler +.word TIM10_TRG_COM_IRQHandler +.word TIM10_CC_IRQHandler +.word DMA2_Channel6_IRQHandler +.word DMA2_Channel7_IRQHandler +.word DMA2_Channel8_IRQHandler +.word DMA2_Channel9_IRQHandler +.word DMA2_Channel10_IRQHandler +.word DMA2_Channel11_IRQHandler + +/******************************************************************************* +* +* Provide weak aliases +* +*******************************************************************************/ +.weak NMI_Handler +.thumb_set NMI_Handler,Default_Handler + +.weak HardFault_Handler +.thumb_set HardFault_Handler,Default_Handler + +.weak MemManage_Handler +.thumb_set MemManage_Handler,Default_Handler + +.weak BusFault_Handler +.thumb_set BusFault_Handler,Default_Handler + +.weak UsageFault_Handler +.thumb_set UsageFault_Handler,Default_Handler + +.weak SVC_Handler +.thumb_set SVC_Handler,Default_Handler + +.weak DebugMon_Handler +.thumb_set DebugMon_Handler,Default_Handler + +.weak PendSV_Handler +.thumb_set PendSV_Handler,Default_Handler + +.weak SysTick_Handler +.thumb_set SysTick_Handler,Default_Handler + +.weak WWDG_IRQHandler +.thumb_set WWDG_IRQHandler,Default_Handler + +.weak PVD_IRQHandler +.thumb_set PVD_IRQHandler,Default_Handler + +.weak TAMPER_IRQHandler +.thumb_set TAMPER_IRQHandler,Default_Handler + +.weak RTC_IRQHandler +.thumb_set RTC_IRQHandler,Default_Handler + +.weak FLASH_IRQHandler +.thumb_set FLASH_IRQHandler,Default_Handler + +.weak RCC_IRQHandler +.thumb_set RCC_IRQHandler,Default_Handler + +.weak EXTI0_IRQHandler +.thumb_set EXTI0_IRQHandler,Default_Handler + +.weak EXTI1_IRQHandler +.thumb_set EXTI1_IRQHandler,Default_Handler + +.weak EXTI2_IRQHandler +.thumb_set EXTI2_IRQHandler,Default_Handler + +.weak EXTI3_IRQHandler +.thumb_set EXTI3_IRQHandler,Default_Handler + +.weak EXTI4_IRQHandler +.thumb_set EXTI4_IRQHandler,Default_Handler + +.weak DMA1_Channel1_IRQHandler +.thumb_set DMA1_Channel1_IRQHandler,Default_Handler + +.weak DMA1_Channel2_IRQHandler +.thumb_set DMA1_Channel2_IRQHandler,Default_Handler + +.weak DMA1_Channel3_IRQHandler +.thumb_set DMA1_Channel3_IRQHandler,Default_Handler + +.weak DMA1_Channel4_IRQHandler +.thumb_set DMA1_Channel4_IRQHandler,Default_Handler + +.weak DMA1_Channel5_IRQHandler +.thumb_set DMA1_Channel5_IRQHandler,Default_Handler + +.weak DMA1_Channel6_IRQHandler +.thumb_set DMA1_Channel6_IRQHandler,Default_Handler + +.weak DMA1_Channel7_IRQHandler +.thumb_set DMA1_Channel7_IRQHandler,Default_Handler + +.weak ADC1_2_IRQHandler +.thumb_set ADC1_2_IRQHandler,Default_Handler + +.weak USB_HP_CAN1_TX_IRQHandler +.thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler + +.weak USB_LP_CAN1_RX0_IRQHandler +.thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler + +.weak CAN1_RX1_IRQHandler +.thumb_set CAN1_RX1_IRQHandler,Default_Handler + +.weak CAN1_SCE_IRQHandler +.thumb_set CAN1_SCE_IRQHandler,Default_Handler + +.weak EXTI9_5_IRQHandler +.thumb_set EXTI9_5_IRQHandler,Default_Handler + +.weak TIM1_BRK_IRQHandler +.thumb_set TIM1_BRK_IRQHandler,Default_Handler + +.weak TIM1_UP_IRQHandler +.thumb_set TIM1_UP_IRQHandler,Default_Handler + +.weak TIM1_TRG_COM_IRQHandler +.thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler + +.weak TIM1_CC_IRQHandler +.thumb_set TIM1_CC_IRQHandler,Default_Handler + +.weak TIM2_IRQHandler +.thumb_set TIM2_IRQHandler,Default_Handler + +.weak TIM3_IRQHandler +.thumb_set TIM3_IRQHandler,Default_Handler + +.weak TIM4_IRQHandler +.thumb_set TIM4_IRQHandler,Default_Handler + +.weak I2C1_EV_IRQHandler +.thumb_set I2C1_EV_IRQHandler,Default_Handler + +.weak I2C1_ER_IRQHandler +.thumb_set I2C1_ER_IRQHandler,Default_Handler + +.weak I2C2_EV_IRQHandler +.thumb_set I2C2_EV_IRQHandler,Default_Handler + +.weak I2C2_ER_IRQHandler +.thumb_set I2C2_ER_IRQHandler,Default_Handler + +.weak SPI1_IRQHandler +.thumb_set SPI1_IRQHandler,Default_Handler + +.weak SPI2_IRQHandler +.thumb_set SPI2_IRQHandler,Default_Handler + +.weak USART1_IRQHandler +.thumb_set USART1_IRQHandler,Default_Handler + +.weak USART2_IRQHandler +.thumb_set USART2_IRQHandler,Default_Handler + +.weak USART3_IRQHandler +.thumb_set USART3_IRQHandler,Default_Handler + +.weak EXTI15_10_IRQHandler +.thumb_set EXTI15_10_IRQHandler,Default_Handler + +.weak RTCAlarm_IRQHandler +.thumb_set RTCAlarm_IRQHandler,Default_Handler + +.weak TIM8_BRK_IRQHandler +.thumb_set TIM8_BRK_IRQHandler,Default_Handler + +.weak TIM8_UP_IRQHandler +.thumb_set TIM8_UP_IRQHandler,Default_Handler + +.weak TIM8_TRG_COM_IRQHandler +.thumb_set TIM8_TRG_COM_IRQHandler,Default_Handler + +.weak TIM8_CC_IRQHandler +.thumb_set TIM8_CC_IRQHandler,Default_Handler + +.weak RNG_IRQHandler +.thumb_set RNG_IRQHandler,Default_Handler + +.weak FSMC_IRQHandler +.thumb_set FSMC_IRQHandler,Default_Handler + +.weak SDIO_IRQHandler +.thumb_set SDIO_IRQHandler,Default_Handler + +.weak TIM5_IRQHandler +.thumb_set TIM5_IRQHandler,Default_Handler + +.weak SPI3_IRQHandler +.thumb_set SPI3_IRQHandler,Default_Handler + +.weak UART4_IRQHandler +.thumb_set UART4_IRQHandler,Default_Handler + +.weak UART5_IRQHandler +.thumb_set UART5_IRQHandler,Default_Handler + +.weak TIM6_IRQHandler +.thumb_set TIM6_IRQHandler,Default_Handler + +.weak TIM7_IRQHandler +.thumb_set TIM7_IRQHandler,Default_Handler + +.weak DMA2_Channel1_IRQHandler +.thumb_set DMA2_Channel1_IRQHandler,Default_Handler + +.weak DMA2_Channel2_IRQHandler +.thumb_set DMA2_Channel2_IRQHandler,Default_Handler + +.weak DMA2_Channel3_IRQHandler +.thumb_set DMA2_Channel3_IRQHandler,Default_Handler + +.weak DMA2_Channel4_IRQHandler +.thumb_set DMA2_Channel4_IRQHandler,Default_Handler + +.weak DMA2_Channel5_IRQHandler +.thumb_set DMA2_Channel5_IRQHandler,Default_Handler + +.weak ETH_IRQHandler +.thumb_set ETH_IRQHandler,Default_Handler + +.weak ETH_WKUP_IRQHandler +.thumb_set ETH_WKUP_IRQHandler,Default_Handler + +.weak CAN2_TX_IRQHandler +.thumb_set CAN2_TX_IRQHandler,Default_Handler + +.weak CAN2_RX0_IRQHandler +.thumb_set CAN2_RX0_IRQHandler,Default_Handler + +.weak CAN2_RX1_IRQHandler +.thumb_set CAN2_RX1_IRQHandler,Default_Handler + +.weak CAN2_SCE_IRQHandler +.thumb_set CAN2_SCE_IRQHandler,Default_Handler + +.weak OTG_FS_IRQHandler +.thumb_set OTG_FS_IRQHandler,Default_Handler + +.weak USBHSWakeup_IRQHandler +.thumb_set USBHSWakeup_IRQHandler,Default_Handler + +.weak USBHS_IRQHandler +.thumb_set USBHS_IRQHandler,Default_Handler + +.weak DVP_IRQHandler +.thumb_set DVP_IRQHandler,Default_Handler + +.weak UART6_IRQHandler +.thumb_set UART6_IRQHandler,Default_Handler + +.weak UART7_IRQHandler +.thumb_set UART7_IRQHandler,Default_Handler + +.weak UART8_IRQHandler +.thumb_set UART8_IRQHandler,Default_Handler + +.weak TIM9_BRK_IRQHandler +.thumb_set TIM9_BRK_IRQHandler,Default_Handler + +.weak TIM9_UP_IRQHandler +.thumb_set TIM9_UP_IRQHandler,Default_Handler + +.weak TIM9_TRG_COM_IRQHandler +.thumb_set TIM9_TRG_COM_IRQHandler,Default_Handler + +.weak TIM9_CC_IRQHandler +.thumb_set TIM9_CC_IRQHandler,Default_Handler + +.weak TIM10_BRK_IRQHandler +.thumb_set TIM10_BRK_IRQHandler,Default_Handler + +.weak TIM10_UP_IRQHandler +.thumb_set TIM10_UP_IRQHandler,Default_Handler + +.weak TIM10_TRG_COM_IRQHandler +.thumb_set TIM10_TRG_COM_IRQHandler,Default_Handler + +.weak TIM10_CC_IRQHandler +.thumb_set TIM10_CC_IRQHandler,Default_Handler + +.weak DMA2_Channel6_IRQHandler +.thumb_set DMA2_Channel6_IRQHandler,Default_Handler + +.weak DMA2_Channel7_IRQHandler +.thumb_set DMA2_Channel7_IRQHandler,Default_Handler + +.weak DMA2_Channel8_IRQHandler +.thumb_set DMA2_Channel8_IRQHandler,Default_Handler + +.weak DMA2_Channel9_IRQHandler +.thumb_set DMA2_Channel9_IRQHandler,Default_Handler + +.weak DMA2_Channel10_IRQHandler +.thumb_set DMA2_Channel10_IRQHandler,Default_Handler + +.weak DMA2_Channel11_IRQHandler +.thumb_set DMA2_Channel11_IRQHandler,Default_Handler diff --git a/hw/bsp/ch32f20x/system_ch32f20x.c b/hw/bsp/ch32f20x/system_ch32f20x.c new file mode 100644 index 000000000..0a59b9287 --- /dev/null +++ b/hw/bsp/ch32f20x/system_ch32f20x.c @@ -0,0 +1,1122 @@ +/********************************** (C) COPYRIGHT ******************************* +* File Name : system_ch32f20x.c +* Author : WCH +* Version : V1.0.0 +* Date : 2021/08/08 +* Description : CH32F20x Device Peripheral Access Layer System Source File. +* For CH32F208 HSE = 32Mhz +* For others HSE = 8Mhz +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#include "ch32f20x.h" + +/* +* Uncomment the line corresponding to the desired System clock (SYSCLK) frequency (after +* reset the HSI is used as SYSCLK source). +* If none of the define below is enabled, the HSI is used as System clock source. +*/ + +//#define SYSCLK_FREQ_HSE HSE_VALUE +//#define SYSCLK_FREQ_48MHz_HSE 48000000 +//#define SYSCLK_FREQ_56MHz_HSE 56000000 +//#define SYSCLK_FREQ_72MHz_HSE 72000000 +#define SYSCLK_FREQ_96MHz_HSE 96000000 +//#define SYSCLK_FREQ_120MHz_HSE 120000000 +//#define SYSCLK_FREQ_144MHz_HSE 144000000 +//#define SYSCLK_FREQ_HSI HSI_VALUE +//#define SYSCLK_FREQ_48MHz_HSI 48000000 +//#define SYSCLK_FREQ_56MHz_HSI 56000000 +//#define SYSCLK_FREQ_72MHz_HSI 72000000 +//#define SYSCLK_FREQ_96MHz_HSI 96000000 +//#define SYSCLK_FREQ_120MHz_HSI 120000000 +//#define SYSCLK_FREQ_144MHz_HSI 144000000 + + +/* Uncomment the following line if you need to relocate your vector Table in Internal SRAM */ +/* #define VECT_TAB_SRAM */ + +/* Vector Table base offset field This value must be a multiple of 0x200 */ +#define VECT_TAB_OFFSET 0x0 + +/* Clock Definitions */ +#ifdef SYSCLK_FREQ_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_48MHz_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_56MHz_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_72MHz_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_96MHz_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_120MHz_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_144MHz_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_48MHz_HSI +uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSI; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_56MHz_HSI +uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSI; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_72MHz_HSI +uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSI; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_96MHz_HSI +uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz_HSI; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_120MHz_HSI +uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz_HSI; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_144MHz_HSI +uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz_HSI; /* System Clock Frequency (Core Clock) */ +#else +uint32_t SystemCoreClock = HSI_VALUE; /* System Clock Frequency (Core Clock) */ + +#endif + +__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + +/* system_private_function_proto_types */ +static void SetSysClock( void ); + +#ifdef SYSCLK_FREQ_HSE +static void SetSysClockToHSE( void ); +#elif defined SYSCLK_FREQ_48MHz_HSE +static void SetSysClockTo48_HSE( void ); +#elif defined SYSCLK_FREQ_56MHz_HSE +static void SetSysClockTo56_HSE( void ); +#elif defined SYSCLK_FREQ_72MHz_HSE +static void SetSysClockTo72_HSE( void ); +#elif defined SYSCLK_FREQ_96MHz_HSE +static void SetSysClockTo96_HSE( void ); +#elif defined SYSCLK_FREQ_120MHz_HSE +static void SetSysClockTo120_HSE( void ); +#elif defined SYSCLK_FREQ_144MHz_HSE +static void SetSysClockTo144_HSE( void ); +#elif defined SYSCLK_FREQ_48MHz_HSI +static void SetSysClockTo48_HSI( void ); +#elif defined SYSCLK_FREQ_56MHz_HSI +static void SetSysClockTo56_HSI( void ); +#elif defined SYSCLK_FREQ_72MHz_HSI +static void SetSysClockTo72_HSI( void ); +#elif defined SYSCLK_FREQ_96MHz_HSI +static void SetSysClockTo96_HSI( void ); +#elif defined SYSCLK_FREQ_120MHz_HSI +static void SetSysClockTo120_HSI( void ); +#elif defined SYSCLK_FREQ_144MHz_HSI +static void SetSysClockTo144_HSI( void ); + +#endif + + +/********************************************************************* + * @fn SystemInit + * + * @brief Setup the microcontroller system Initialize the Embedded Flash Interface, + * the PLL and update the SystemCoreClock variable. + * + * @return none + */ +void SystemInit( void ) +{ + RCC->CTLR |= ( uint32_t )0x00000001; + +#ifdef CH32F20x_D8C + RCC->CFGR0 &= ( uint32_t )0xF8FF0000; +#else + RCC->CFGR0 &= ( uint32_t )0xF0FF0000; +#endif + + RCC->CTLR &= ( uint32_t )0xFEF6FFFF; + RCC->CTLR &= ( uint32_t )0xFFFBFFFF; + RCC->CFGR0 &= ( uint32_t )0xFF80FFFF; +#ifdef CH32F20x_D8C + RCC->CTLR &= ( uint32_t )0xEBFFFFFF; + RCC->INTR = 0x00FF0000; + RCC->CFGR2 = 0x00000000; +#else + RCC->INTR = 0x009F0000; +#endif + + SetSysClock(); + +#ifdef VECT_TAB_SRAM + SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */ +#else + SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */ +#endif +} + +/********************************************************************* + * @fn SystemCoreClockUpdate + * + * @brief Update SystemCoreClock variable according to Clock Register Values. + * + * @return none + */ +void SystemCoreClockUpdate( void ) +{ + uint32_t tmp = 0, pllmull = 0, pllsource = 0; + uint8_t Pll_6_5 = 0; + +#if defined (CH32F20x_D8C) + uint8_t Pll2mull = 0; + +#endif + + tmp = RCC->CFGR0 & RCC_SWS; + + switch( tmp ) + { + case 0x00: + SystemCoreClock = HSI_VALUE; + break; + case 0x04: + SystemCoreClock = HSE_VALUE; + break; + case 0x08: + pllmull = RCC->CFGR0 & RCC_PLLMULL; + pllsource = RCC->CFGR0 & RCC_PLLSRC; + pllmull = ( pllmull >> 18 ) + 2; + +#if defined (CH32F20x_D6) || defined (CH32F20x_D8) || defined (CH32F20x_D8W) + if( pllmull == 17 ) + { + pllmull = 18; + } +#else + if( pllmull == 2 ) + { + pllmull = 18; + } + if( pllmull == 15 ) + { + pllmull = 13; /* *6.5 */ + Pll_6_5 = 1; + } + if( pllmull == 16 ) + { + pllmull = 15; + } + if( pllmull == 17 ) + { + pllmull = 16; + } +#endif + + if( pllsource == 0x00 ) + { + if(EXTEN->EXTEN_CTR & EXTEN_PLL_HSI_PRE) SystemCoreClock = HSI_VALUE * pllmull; + else SystemCoreClock = (HSI_VALUE >> 1) * pllmull; + } + else + { +#if defined (CH32F20x_D8C) + if(RCC->CFGR2 & (1<<16)){ /* PLL2 */ + SystemCoreClock = HSE_VALUE/(((RCC->CFGR2 & 0xF0)>>4) + 1); /* PREDIV2 */ + + Pll2mull = (uint8_t)((RCC->CFGR2 & 0xF00)>>8); + + if(Pll2mull == 0) SystemCoreClock = (SystemCoreClock * 5)>>1; + else if(Pll2mull == 1) SystemCoreClock = (SystemCoreClock * 25)>>1; + else if(Pll2mull == 15) SystemCoreClock = SystemCoreClock * 20; + else SystemCoreClock = SystemCoreClock * (Pll2mull + 2); + + SystemCoreClock = SystemCoreClock/((RCC->CFGR2 & 0xF) + 1); /* PREDIV1 */ + } + else{/* HSE */ + SystemCoreClock = HSE_VALUE/((RCC->CFGR2 & 0xF) + 1); /* PREDIV1 */ + } + + SystemCoreClock = SystemCoreClock * pllmull; +#else + +#if defined (CH32F20x_D8W) + if((RCC->CFGR0 & (3<<22)) == (3<<22)) + { + SystemCoreClock = ((HSE_VALUE>>1)) * pllmull; + } + else +#endif + if( ( RCC->CFGR0 & RCC_PLLXTPRE ) != ( uint32_t )RESET ) + { +#ifdef CH32F20x_D8W + SystemCoreClock = ( ( HSE_VALUE >> 2 ) >> 1 ) * pllmull; +#else + SystemCoreClock = ( HSE_VALUE >> 1 ) * pllmull; +#endif + } + else + { +#ifdef CH32F20x_D8W + SystemCoreClock = ( HSE_VALUE >> 2 ) * pllmull; +#else + SystemCoreClock = HSE_VALUE * pllmull; +#endif + + } +#endif + } + + if( Pll_6_5 == 1 ) SystemCoreClock = ( SystemCoreClock / 2 ); + + break; + default: + SystemCoreClock = HSI_VALUE; + break; + } + + tmp = AHBPrescTable[( ( RCC->CFGR0 & RCC_HPRE ) >> 4 )]; + SystemCoreClock >>= tmp; +} + + + +/********************************************************************* + * @fn SetSysClock + * + * @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClock( void ) +{ +#ifdef SYSCLK_FREQ_HSE + SetSysClockToHSE(); +#elif defined SYSCLK_FREQ_48MHz_HSE + SetSysClockTo48_HSE(); +#elif defined SYSCLK_FREQ_56MHz_HSE + SetSysClockTo56_HSE(); +#elif defined SYSCLK_FREQ_72MHz_HSE + SetSysClockTo72_HSE(); +#elif defined SYSCLK_FREQ_96MHz_HSE + SetSysClockTo96_HSE(); +#elif defined SYSCLK_FREQ_120MHz_HSE + SetSysClockTo120_HSE(); +#elif defined SYSCLK_FREQ_144MHz_HSE + SetSysClockTo144_HSE(); +#elif defined SYSCLK_FREQ_48MHz_HSI + SetSysClockTo48_HSI(); +#elif defined SYSCLK_FREQ_56MHz_HSI + SetSysClockTo56_HSI(); +#elif defined SYSCLK_FREQ_72MHz_HSI + SetSysClockTo72_HSI(); +#elif defined SYSCLK_FREQ_96MHz_HSI + SetSysClockTo96_HSI(); +#elif defined SYSCLK_FREQ_120MHz_HSI + SetSysClockTo120_HSI(); +#elif defined SYSCLK_FREQ_144MHz_HSI + SetSysClockTo144_HSI(); + +#endif + + /* If none of the define above is enabled, the HSI is used as System clock + * source (default after reset) + */ +} + + +#ifdef SYSCLK_FREQ_HSE + +/********************************************************************* + * @fn SetSysClockToHSE + * + * @brief Sets HSE as System clock source and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockToHSE( void ) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + + RCC->CTLR |= ( ( uint32_t )RCC_HSEON ); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } + while( ( HSEStatus == 0 ) && ( StartUpCounter != HSE_STARTUP_TIMEOUT ) ); + + if( ( RCC->CTLR & RCC_HSERDY ) != RESET ) + { + HSEStatus = ( uint32_t )0x01; + } + else + { + HSEStatus = ( uint32_t )0x00; + } + + if( HSEStatus == ( uint32_t )0x01 ) + { + /* HCLK = SYSCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_PPRE1_DIV1; + + /* Select HSE as system clock source + * CH32F20x_D6 (HSE=8Mhz) + * CH32F20x_D8 (HSE=8Mhz) + * CH32F20x_D8W (HSE=32Mhz) + */ + RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_SW ) ); + RCC->CFGR0 |= ( uint32_t )RCC_SW_HSE; + + /* Wait till HSE is used as system clock source */ + while( ( RCC->CFGR0 & ( uint32_t )RCC_SWS ) != ( uint32_t )0x04 ) + { + } + } + else + { + /* If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + +#elif defined SYSCLK_FREQ_48MHz_HSE + +/********************************************************************* + * @fn SetSysClockTo48_HSE + * + * @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo48_HSE( void ) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + + RCC->CTLR |= ( ( uint32_t )RCC_HSEON ); + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } + while( ( HSEStatus == 0 ) && ( StartUpCounter != HSE_STARTUP_TIMEOUT ) ); + + if( ( RCC->CTLR & RCC_HSERDY ) != RESET ) + { + HSEStatus = ( uint32_t )0x01; + } + else + { + HSEStatus = ( uint32_t )0x00; + } + + if( HSEStatus == ( uint32_t )0x01 ) + { + /* HCLK = SYSCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_PPRE1_DIV2; + + /* CH32F20x_D6-PLL configuration: PLLCLK = HSE * 6 = 48 MHz (HSE=8Mhz) + * CH32F20x_D8-PLL configuration: PLLCLK = HSE * 6 = 48 MHz (HSE=8Mhz) + * CH32F20x_D8W-PLL configuration: PLLCLK = HSE/4 * 6 = 48 MHz(HSE=32Mhz) + */ + RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL ) ); + +#if defined (CH32F20x_D6) || defined (CH32F20x_D8) || defined (CH32F20x_D8W) + RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL6 ); +#else + RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL6_EXTEN ); +#endif + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while( ( RCC->CTLR & RCC_PLLRDY ) == 0 ) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_SW ) ); + RCC->CFGR0 |= ( uint32_t )RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while( ( RCC->CFGR0 & ( uint32_t )RCC_SWS ) != ( uint32_t )0x08 ) + { + } + } + else + { + /* + * If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + +#elif defined SYSCLK_FREQ_56MHz_HSE + +/********************************************************************* + * @fn SetSysClockTo56_HSE + * + * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo56_HSE( void ) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ( ( uint32_t )RCC_HSEON ); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } + while( ( HSEStatus == 0 ) && ( StartUpCounter != HSE_STARTUP_TIMEOUT ) ); + + if( ( RCC->CTLR & RCC_HSERDY ) != RESET ) + { + HSEStatus = ( uint32_t )0x01; + } + else + { + HSEStatus = ( uint32_t )0x00; + } + + if( HSEStatus == ( uint32_t )0x01 ) + { + /* HCLK = SYSCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_PPRE1_DIV2; + + /* CH32F20x_D6-PLL configuration: PLLCLK = HSE * 7 = 56 MHz (HSE=8Mhz) + * CH32F20x_D8-PLL configuration: PLLCLK = HSE * 7 = 56 MHz (HSE=8Mhz) + * CH32F20x_D8W-PLL configuration: PLLCLK = HSE/4 * 7 = 56 MHz(HSE=32Mhz) + */ + RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL ) ); + +#if defined (CH32F20x_D6) || defined (CH32F20x_D8) || defined (CH32F20x_D8W) + RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL7 ); +#else + RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL7_EXTEN ); +#endif + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while( ( RCC->CTLR & RCC_PLLRDY ) == 0 ) + { + } + + /* Select PLL as system clock source */ + RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_SW ) ); + RCC->CFGR0 |= ( uint32_t )RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while( ( RCC->CFGR0 & ( uint32_t )RCC_SWS ) != ( uint32_t )0x08 ) + { + } + } + else + { + /* + * If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + +#elif defined SYSCLK_FREQ_72MHz_HSE + +/********************************************************************* + * @fn SetSysClockTo72_HSE + * + * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo72_HSE( void ) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ( ( uint32_t )RCC_HSEON ); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } + while( ( HSEStatus == 0 ) && ( StartUpCounter != HSE_STARTUP_TIMEOUT ) ); + + if( ( RCC->CTLR & RCC_HSERDY ) != RESET ) + { + HSEStatus = ( uint32_t )0x01; + } + else + { + HSEStatus = ( uint32_t )0x00; + } + + if( HSEStatus == ( uint32_t )0x01 ) + { + /* HCLK = SYSCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_PPRE1_DIV2; + + /* CH32F20x_D6-PLL configuration: PLLCLK = HSE * 9 = 72 MHz (HSE=8Mhz) + * CH32F20x_D8-PLL configuration: PLLCLK = HSE * 9 = 72 MHz (HSE=8Mhz) + * CH32F20x_D8W-PLL configuration: PLLCLK = HSE/4 * 9 = 72 MHz(HSE=32Mhz) + */ + RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_PLLSRC | RCC_PLLXTPRE | + RCC_PLLMULL ) ); + +#if defined (CH32F20x_D6) || defined (CH32F20x_D8) || defined (CH32F20x_D8W) + RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL9 ); +#else + RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL9_EXTEN ); +#endif + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while( ( RCC->CTLR & RCC_PLLRDY ) == 0 ) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_SW ) ); + RCC->CFGR0 |= ( uint32_t )RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while( ( RCC->CFGR0 & ( uint32_t )RCC_SWS ) != ( uint32_t )0x08 ) + { + } + } + else + { + /* + * If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + + +#elif defined SYSCLK_FREQ_96MHz_HSE + +/********************************************************************* + * @fn SetSysClockTo96_HSE + * + * @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo96_HSE( void ) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ( ( uint32_t )RCC_HSEON ); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } + while( ( HSEStatus == 0 ) && ( StartUpCounter != HSE_STARTUP_TIMEOUT ) ); + + if( ( RCC->CTLR & RCC_HSERDY ) != RESET ) + { + HSEStatus = ( uint32_t )0x01; + } + else + { + HSEStatus = ( uint32_t )0x00; + } + + if( HSEStatus == ( uint32_t )0x01 ) + { + /* HCLK = SYSCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_PPRE1_DIV2; + + /* CH32F20x_D6-PLL configuration: PLLCLK = HSE * 12 = 96 MHz (HSE=8Mhz) + * CH32F20x_D8-PLL configuration: PLLCLK = HSE * 12 = 96 MHz (HSE=8Mhz) + * CH32F20x_D8W-PLL configuration: PLLCLK = HSE/4 * 12 = 96 MHz(HSE=32Mhz) + */ + RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_PLLSRC | RCC_PLLXTPRE | + RCC_PLLMULL ) ); + +#if defined (CH32F20x_D6) || defined (CH32F20x_D8) || defined (CH32F20x_D8W) + RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL12 ); +#else + RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL12_EXTEN ); +#endif + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while( ( RCC->CTLR & RCC_PLLRDY ) == 0 ) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_SW ) ); + RCC->CFGR0 |= ( uint32_t )RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while( ( RCC->CFGR0 & ( uint32_t )RCC_SWS ) != ( uint32_t )0x08 ) + { + } + } + else + { + /* + * If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + + +#elif defined SYSCLK_FREQ_120MHz_HSE + +/********************************************************************* + * @fn SetSysClockTo120_HSE + * + * @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo120_HSE(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ((uint32_t)RCC_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if ((RCC->CTLR & RCC_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if (HSEStatus == (uint32_t)0x01) + { +#if defined (CH32F20x_D8W) + RCC->CFGR0 |= (uint32_t)(3<<22); + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV2; +#else + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; +#endif + + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* CH32F20x_D6-PLL configuration: PLLCLK = HSE * 15 = 120 MHz (HSE=8Mhz) + * CH32F20x_D8-PLL configuration: PLLCLK = HSE * 15 = 120 MHz (HSE=8Mhz) + * CH32F20x_D8W-PLL configuration: PLLCLK = HSE/2 * 15 = 240 MHz(HSE=32Mhz) + */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | + RCC_PLLMULL)); + +#if defined (CH32F20x_D6) || defined (CH32F20x_D8) || defined (CH32F20x_D8W) + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL15); +#else + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL15_EXTEN); +#endif + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } + } + else + { + /* + * If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + + + +#elif defined SYSCLK_FREQ_144MHz_HSE + +/********************************************************************* + * @fn SetSysClockTo144_HSE + * + * @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo144_HSE( void ) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ( ( uint32_t )RCC_HSEON ); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } + while( ( HSEStatus == 0 ) && ( StartUpCounter != HSE_STARTUP_TIMEOUT ) ); + + if( ( RCC->CTLR & RCC_HSERDY ) != RESET ) + { + HSEStatus = ( uint32_t )0x01; + } + else + { + HSEStatus = ( uint32_t )0x00; + } + + if( HSEStatus == ( uint32_t )0x01 ) + { + /* HCLK = SYSCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_PPRE1_DIV2; + + /* CH32F20x_D6-PLL configuration: PLLCLK = HSE * 18 = 144 MHz (HSE=8Mhz) + * CH32F20x_D8-PLL configuration: PLLCLK = HSE * 18 = 144 MHz (HSE=8Mhz) + * CH32F20x_D8W-PLL configuration: PLLCLK = HSE/4 * 18 = 144 MHz(HSE=32Mhz) + */ + RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_PLLSRC | RCC_PLLXTPRE | + RCC_PLLMULL ) ); + +#if defined (CH32F20x_D6) || defined (CH32F20x_D8) || defined (CH32F20x_D8W) + RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL18 ); +#else + RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL18_EXTEN ); +#endif + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while( ( RCC->CTLR & RCC_PLLRDY ) == 0 ) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_SW ) ); + RCC->CFGR0 |= ( uint32_t )RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while( ( RCC->CFGR0 & ( uint32_t )RCC_SWS ) != ( uint32_t )0x08 ) + { + } + } + else + { + /* + * If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + +#elif defined SYSCLK_FREQ_48MHz_HSI + +/********************************************************************* + * @fn SetSysClockTo48_HSI + * + * @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo48_HSI( void ) +{ + EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSI * 6 = 48 MHz */ + RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL ) ); + +#if defined (CH32F20x_D6) || defined (CH32F20x_D8) || defined (CH32F20x_D8W) + RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL6 ); +#else + RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL6_EXTEN ); +#endif + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while( ( RCC->CTLR & RCC_PLLRDY ) == 0 ) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_SW ) ); + RCC->CFGR0 |= ( uint32_t )RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while( ( RCC->CFGR0 & ( uint32_t )RCC_SWS ) != ( uint32_t )0x08 ) + { + } +} + +#elif defined SYSCLK_FREQ_56MHz_HSI + +/********************************************************************* + * @fn SetSysClockTo56_HSI + * + * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo56_HSI( void ) +{ + EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSI * 7 = 56 MHz */ + RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL ) ); + +#if defined (CH32F20x_D6) || defined (CH32F20x_D8) || defined (CH32F20x_D8W) + RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL7 ); +#else + RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL7_EXTEN ); +#endif + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while( ( RCC->CTLR & RCC_PLLRDY ) == 0 ) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_SW ) ); + RCC->CFGR0 |= ( uint32_t )RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while( ( RCC->CFGR0 & ( uint32_t )RCC_SWS ) != ( uint32_t )0x08 ) + { + } +} + +#elif defined SYSCLK_FREQ_72MHz_HSI + +/********************************************************************* + * @fn SetSysClockTo72_HSI + * + * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo72_HSI( void ) +{ + EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSI * 9 = 72 MHz */ + RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL ) ); + +#if defined (CH32F20x_D6) || defined (CH32F20x_D8) || defined (CH32F20x_D8W) + RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL9 ); +#else + RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL9_EXTEN ); +#endif + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while( ( RCC->CTLR & RCC_PLLRDY ) == 0 ) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_SW ) ); + RCC->CFGR0 |= ( uint32_t )RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while( ( RCC->CFGR0 & ( uint32_t )RCC_SWS ) != ( uint32_t )0x08 ) + { + } +} + + +#elif defined SYSCLK_FREQ_96MHz_HSI + +/********************************************************************* + * @fn SetSysClockTo96_HSI + * + * @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo96_HSI( void ) +{ + EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSI * 12 = 96 MHz */ + RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL ) ); + +#if defined (CH32F20x_D6) || defined (CH32F20x_D8) || defined (CH32F20x_D8W) + RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL12 ); +#else + RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL12_EXTEN ); +#endif + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while( ( RCC->CTLR & RCC_PLLRDY ) == 0 ) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_SW ) ); + RCC->CFGR0 |= ( uint32_t )RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while( ( RCC->CFGR0 & ( uint32_t )RCC_SWS ) != ( uint32_t )0x08 ) + { + } +} + + +#elif defined SYSCLK_FREQ_120MHz_HSI + +/********************************************************************* + * @fn SetSysClockTo120_HSI + * + * @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo120_HSI(void) +{ + EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSI * 15 = 120 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | + RCC_PLLMULL)); + +#if defined (CH32F20x_D6) || defined (CH32F20x_D8) || defined (CH32F20x_D8W) + RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL15 ); +#else + RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL15_EXTEN ); +#endif + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } +} + + +#elif defined SYSCLK_FREQ_144MHz_HSI + +/********************************************************************* + * @fn SetSysClockTo144_HSI + * + * @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo144_HSI( void ) +{ + EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= ( uint32_t )RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSI * 18 = 144 MHz */ + RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL ) ); + +#if defined (CH32F20x_D6) || defined (CH32F20x_D8) || defined (CH32F20x_D8W) + RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL18 ); +#else + RCC->CFGR0 |= ( uint32_t )( RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL18_EXTEN ); +#endif + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while( ( RCC->CTLR & RCC_PLLRDY ) == 0 ) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= ( uint32_t )( ( uint32_t )~( RCC_SW ) ); + RCC->CFGR0 |= ( uint32_t )RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while( ( RCC->CFGR0 & ( uint32_t )RCC_SWS ) != ( uint32_t )0x08 ) + { + } +} + + +#endif diff --git a/hw/bsp/ch32f20x/system_ch32f20x.h b/hw/bsp/ch32f20x/system_ch32f20x.h new file mode 100644 index 000000000..cf2f5328b --- /dev/null +++ b/hw/bsp/ch32f20x/system_ch32f20x.h @@ -0,0 +1,25 @@ +/********************************** (C) COPYRIGHT ******************************* +* File Name : system_ch32f20x.h +* Author : WCH +* Version : V1.0.0 +* Date : 2021/08/08 +* Description : CH32F20x Device Peripheral Access Layer System Header File. +*******************************************************************************/ +#ifndef __SYSTEM_CH32F20x_H +#define __SYSTEM_CH32F20x_H + +#ifdef __cplusplus + extern "C" { +#endif + +extern uint32_t SystemCoreClock; /* System Clock Frequency (Core Clock) */ + +/* System_Exported_Functions */ +extern void SystemInit(void); +extern void SystemCoreClockUpdate(void); + +#ifdef __cplusplus +} +#endif + +#endif /*__CH32F20x_SYSTEM_H */ diff --git a/hw/bsp/ch32v307/boards/ch32v307v_r1_1v0/board.cmake b/hw/bsp/ch32v307/boards/ch32v307v_r1_1v0/board.cmake new file mode 100644 index 000000000..9f5682042 --- /dev/null +++ b/hw/bsp/ch32v307/boards/ch32v307v_r1_1v0/board.cmake @@ -0,0 +1,4 @@ +function(update_board TARGET) +# target_compile_definitions(${TARGET} PUBLIC +# ) +endfunction() diff --git a/hw/bsp/ch32v307/boards/ch32v307v_r1_1v0/debug_uart.c b/hw/bsp/ch32v307/debug_uart.c similarity index 100% rename from hw/bsp/ch32v307/boards/ch32v307v_r1_1v0/debug_uart.c rename to hw/bsp/ch32v307/debug_uart.c diff --git a/hw/bsp/ch32v307/boards/ch32v307v_r1_1v0/debug_uart.h b/hw/bsp/ch32v307/debug_uart.h similarity index 100% rename from hw/bsp/ch32v307/boards/ch32v307v_r1_1v0/debug_uart.h rename to hw/bsp/ch32v307/debug_uart.h diff --git a/hw/bsp/ch32v307/family.cmake b/hw/bsp/ch32v307/family.cmake new file mode 100644 index 000000000..87a0f2eba --- /dev/null +++ b/hw/bsp/ch32v307/family.cmake @@ -0,0 +1,114 @@ +include_guard() + +set(SDK_DIR ${TOP}/hw/mcu/wch/ch32v307/EVT/EXAM/SRC) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR rv32imac-ilp32 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS CH32V307 CACHE INTERNAL "") +set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg") +set(OPENOCD_OPTION2 "-c wlink_reset_resume") + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif() + + if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ch32v307.ld) + endif () + set(LD_FILE_Clang ${LD_FILE_GNU}) + + if (NOT DEFINED STARTUP_FILE_GNU) + set(STARTUP_FILE_GNU ${SDK_DIR}/Startup/startup_ch32v30x_D8C.S) + endif () + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${SDK_DIR}/Core/core_riscv.c + ${SDK_DIR}/Peripheral/src/ch32v30x_gpio.c + ${SDK_DIR}/Peripheral/src/ch32v30x_misc.c + ${SDK_DIR}/Peripheral/src/ch32v30x_rcc.c + ${SDK_DIR}/Peripheral/src/ch32v30x_usart.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ch32v30x_it.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_ch32v30x.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_DIR}/Peripheral/inc + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_compile_options(${BOARD_TARGET} PUBLIC + -msmall-data-limit=8 + -mno-save-restore + -fmessage-length=0 + -fsigned-char + ) + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + message(FATAL_ERROR "Clang is not supported for MSP432E4") + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/debug_uart.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_CH32V307 ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/wch/dcd_ch32_usbhs.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_add_bin_hex(${TARGET}) + family_flash_openocd_wch(${TARGET}) +endfunction() diff --git a/hw/bsp/ch32v307/family.mk b/hw/bsp/ch32v307/family.mk index 4b06cf429..003b90539 100644 --- a/hw/bsp/ch32v307/family.mk +++ b/hw/bsp/ch32v307/family.mk @@ -6,30 +6,31 @@ CROSS_COMPILE ?= riscv-none-embed- # Submodules CH32V307_SDK = hw/mcu/wch/ch32v307 -DEPS_SUBMODULES += $(CH32V307_SDK) # WCH-SDK paths CH32V307_SDK_SRC = $(CH32V307_SDK)/EVT/EXAM/SRC include $(TOP)/$(BOARD_PATH)/board.mk +CPU_CORE ?= rv32imac-ilp32 CFLAGS += \ -flto \ - -march=rv32imac \ - -mabi=ilp32 \ -msmall-data-limit=8 \ -mno-save-restore -Os \ -fmessage-length=0 \ -fsigned-char \ -ffunction-sections \ -fdata-sections \ - -nostdlib -nostartfiles \ -DCFG_TUSB_MCU=OPT_MCU_CH32V307 \ -Xlinker --gc-sections \ -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs + SRC_C += \ - src/portable/wch/ch32v307/dcd_usbhs.c \ + src/portable/wch/dcd_ch32_usbhs.c \ $(CH32V307_SDK_SRC)/Core/core_riscv.c \ $(CH32V307_SDK_SRC)/Peripheral/src/ch32v30x_gpio.c \ $(CH32V307_SDK_SRC)/Peripheral/src/ch32v30x_misc.c \ @@ -60,5 +61,6 @@ FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V # openocd binaries will be generated in riscv-openocd-wch/src # flash target ROM bootloader +OPENOCD_WCH = /home/${USER}/app/riscv-openocd-wch/src/openocd flash: $(BUILD)/$(PROJECT).elf - openocd -f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg -c init -c halt -c "program $<" -c wlink_reset_resume -c exit + $(OPENOCD_WCH) -f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg -c init -c halt -c "program $<" -c wlink_reset_resume -c exit diff --git a/hw/bsp/da14695_dk_usb/board.mk b/hw/bsp/da14695_dk_usb/board.mk index 1f7bc1588..980b1a361 100644 --- a/hw/bsp/da14695_dk_usb/board.mk +++ b/hw/bsp/da14695_dk_usb/board.mk @@ -1,3 +1,5 @@ +MCU_FAMILY_DIR = hw/mcu/dialog/da1469x + CFLAGS += \ -flto \ -mthumb \ @@ -11,7 +13,7 @@ CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_DA1469X \ -DCFG_TUD_ENDPOINT0_SIZE=8\ -MCU_FAMILY_DIR = hw/mcu/dialog/da1469x +LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs # All source paths should be relative to the top level. LD_FILE = hw/bsp/$(BOARD)/da1469x.ld diff --git a/hw/bsp/da1469x_dk_pro/board.mk b/hw/bsp/da1469x_dk_pro/board.mk index f9bf480de..5282f93a3 100644 --- a/hw/bsp/da1469x_dk_pro/board.mk +++ b/hw/bsp/da1469x_dk_pro/board.mk @@ -1,3 +1,5 @@ +MCU_FAMILY_DIR = hw/mcu/dialog/da1469x + CFLAGS += \ -flto \ -mthumb \ @@ -11,7 +13,7 @@ CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_DA1469X \ -DCFG_TUD_ENDPOINT0_SIZE=8\ -MCU_FAMILY_DIR = hw/mcu/dialog/da1469x +LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs # All source paths should be relative to the top level. LD_FILE = hw/bsp/$(BOARD)/da1469x.ld diff --git a/hw/bsp/espressif/boards/CMakeLists.txt b/hw/bsp/espressif/boards/CMakeLists.txt index 325263c1d..8209e8747 100644 --- a/hw/bsp/espressif/boards/CMakeLists.txt +++ b/hw/bsp/espressif/boards/CMakeLists.txt @@ -4,3 +4,5 @@ idf_component_register(SRCS family.c INCLUDE_DIRS "." ${BOARD} ${hw_dir} PRIV_REQUIRES "driver" REQUIRES led_strip src tinyusb_src) + +target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-error=format) diff --git a/hw/bsp/espressif/boards/adafruit_feather_esp32_v2/board.cmake b/hw/bsp/espressif/boards/adafruit_feather_esp32_v2/board.cmake new file mode 100644 index 000000000..18c956714 --- /dev/null +++ b/hw/bsp/espressif/boards/adafruit_feather_esp32_v2/board.cmake @@ -0,0 +1,2 @@ +# Apply board specific content here +set(IDF_TARGET "esp32") diff --git a/hw/bsp/espressif/boards/adafruit_feather_esp32_v2/board.h b/hw/bsp/espressif/boards/adafruit_feather_esp32_v2/board.h new file mode 100644 index 000000000..0c53df06b --- /dev/null +++ b/hw/bsp/espressif/boards/adafruit_feather_esp32_v2/board.h @@ -0,0 +1,53 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, 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 NEOPIXEL_PIN 0 +#define NEOPIXEL_POWER_PIN 2 +#define NEOPIXEL_POWER_STATE 1 + +#define BUTTON_PIN 38 +#define BUTTON_STATE_ACTIVE 0 + +// SPI for USB host shield +#define MAX3421_SPI_HOST SPI3_HOST +#define MAX3421_SCK_PIN 5 +#define MAX3421_MOSI_PIN 19 +#define MAX3421_MISO_PIN 21 +#define MAX3421_CS_PIN 33 +#define MAX3421_INTR_PIN 15 + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/espressif/boards/adafruit_feather_esp32s2/board.h b/hw/bsp/espressif/boards/adafruit_feather_esp32s2/board.h index 1f8dc2cea..9aa2e7535 100644 --- a/hw/bsp/espressif/boards/adafruit_feather_esp32s2/board.h +++ b/hw/bsp/espressif/boards/adafruit_feather_esp32s2/board.h @@ -38,6 +38,14 @@ #define BUTTON_PIN 0 #define BUTTON_STATE_ACTIVE 0 +// SPI for USB host shield +#define MAX3421_SPI_HOST SPI2_HOST +#define MAX3421_SCK_PIN 36 +#define MAX3421_MOSI_PIN 35 +#define MAX3421_MISO_PIN 37 +#define MAX3421_CS_PIN 10 +#define MAX3421_INTR_PIN 9 + #ifdef __cplusplus } #endif diff --git a/hw/bsp/espressif/boards/adafruit_metro_esp32s2/board.h b/hw/bsp/espressif/boards/adafruit_metro_esp32s2/board.h index 2ec80ef47..137ea71ae 100644 --- a/hw/bsp/espressif/boards/adafruit_metro_esp32s2/board.h +++ b/hw/bsp/espressif/boards/adafruit_metro_esp32s2/board.h @@ -36,6 +36,14 @@ #define BUTTON_PIN 0 #define BUTTON_STATE_ACTIVE 0 +// SPI for USB host shield +#define MAX3421_SPI_HOST SPI2_HOST +#define MAX3421_SCK_PIN 36 +#define MAX3421_MOSI_PIN 35 +#define MAX3421_MISO_PIN 37 +#define MAX3421_CS_PIN 15 +#define MAX3421_INTR_PIN 14 + #ifdef __cplusplus } #endif diff --git a/hw/bsp/espressif/boards/espressif_c3_devkitc/board.cmake b/hw/bsp/espressif/boards/espressif_c3_devkitc/board.cmake new file mode 100644 index 000000000..ab4bc1a06 --- /dev/null +++ b/hw/bsp/espressif/boards/espressif_c3_devkitc/board.cmake @@ -0,0 +1,2 @@ +# Apply board specific content here +set(IDF_TARGET "esp32c3") diff --git a/hw/bsp/espressif/boards/espressif_c3_devkitc/board.h b/hw/bsp/espressif/boards/espressif_c3_devkitc/board.h new file mode 100644 index 000000000..243dd47f6 --- /dev/null +++ b/hw/bsp/espressif/boards/espressif_c3_devkitc/board.h @@ -0,0 +1,51 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, 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 NEOPIXEL_PIN 8 + +#define BUTTON_PIN 9 +#define BUTTON_STATE_ACTIVE 0 + +// SPI for USB host shield +#define MAX3421_SPI_HOST SPI2_HOST +#define MAX3421_SCK_PIN 4 +#define MAX3421_MOSI_PIN 6 +#define MAX3421_MISO_PIN 5 +#define MAX3421_CS_PIN 10 +#define MAX3421_INTR_PIN 7 + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/espressif/boards/espressif_kaluga_1/board.h b/hw/bsp/espressif/boards/espressif_kaluga_1/board.h index 0acb9c439..613e6ae0c 100644 --- a/hw/bsp/espressif/boards/espressif_kaluga_1/board.h +++ b/hw/bsp/espressif/boards/espressif_kaluga_1/board.h @@ -37,6 +37,14 @@ #define BUTTON_PIN 0 #define BUTTON_STATE_ACTIVE 0 +// SPI for USB host shield +#define MAX3421_SPI_HOST SPI2_HOST +#define MAX3421_SCK_PIN 36 +#define MAX3421_MOSI_PIN 35 +#define MAX3421_MISO_PIN 37 +#define MAX3421_CS_PIN 15 +#define MAX3421_INTR_PIN 14 + #ifdef __cplusplus } #endif diff --git a/hw/bsp/espressif/boards/espressif_s2_devkitc/board.cmake b/hw/bsp/espressif/boards/espressif_s2_devkitc/board.cmake new file mode 100644 index 000000000..abbdf7abc --- /dev/null +++ b/hw/bsp/espressif/boards/espressif_s2_devkitc/board.cmake @@ -0,0 +1,2 @@ +# Apply board specific content here +set(IDF_TARGET "esp32s2") diff --git a/hw/bsp/samd51/boards/pybadge/board.h b/hw/bsp/espressif/boards/espressif_s2_devkitc/board.h similarity index 86% rename from hw/bsp/samd51/boards/pybadge/board.h rename to hw/bsp/espressif/boards/espressif_s2_devkitc/board.h index 4629643fd..e068efef9 100644 --- a/hw/bsp/samd51/boards/pybadge/board.h +++ b/hw/bsp/espressif/boards/espressif_s2_devkitc/board.h @@ -31,18 +31,13 @@ extern "C" { #endif -// LED -#define LED_PIN 23 -#define LED_STATE_ON 1 +// Note: On the production version (v1.2) WS2812 is connected to GPIO 18, +// however earlier revision v1.1 WS2812 is connected to GPIO 17 +#define NEOPIXEL_PIN 18 -// Button -#define BUTTON_PIN 16 // D5 +#define BUTTON_PIN 0 #define BUTTON_STATE_ACTIVE 0 -// UART -#define UART_TX_PIN (32 + 17) -#define UART_RX_PIN (32 + 16) - #ifdef __cplusplus } #endif diff --git a/hw/bsp/espressif/boards/espressif_s3_devkitc/board.h b/hw/bsp/espressif/boards/espressif_s3_devkitc/board.h index fe33b5c43..a319fbc61 100644 --- a/hw/bsp/espressif/boards/espressif_s3_devkitc/board.h +++ b/hw/bsp/espressif/boards/espressif_s3_devkitc/board.h @@ -36,6 +36,14 @@ #define BUTTON_PIN 0 #define BUTTON_STATE_ACTIVE 0 +// SPI for USB host shield +#define MAX3421_SPI_HOST SPI2_HOST +#define MAX3421_SCK_PIN 39 +#define MAX3421_MOSI_PIN 42 +#define MAX3421_MISO_PIN 21 +#define MAX3421_CS_PIN 15 +#define MAX3421_INTR_PIN 14 + #ifdef __cplusplus } #endif diff --git a/hw/bsp/espressif/boards/espressif_s3_devkitm/board.h b/hw/bsp/espressif/boards/espressif_s3_devkitm/board.h index fe33b5c43..a319fbc61 100644 --- a/hw/bsp/espressif/boards/espressif_s3_devkitm/board.h +++ b/hw/bsp/espressif/boards/espressif_s3_devkitm/board.h @@ -36,6 +36,14 @@ #define BUTTON_PIN 0 #define BUTTON_STATE_ACTIVE 0 +// SPI for USB host shield +#define MAX3421_SPI_HOST SPI2_HOST +#define MAX3421_SCK_PIN 39 +#define MAX3421_MOSI_PIN 42 +#define MAX3421_MISO_PIN 21 +#define MAX3421_CS_PIN 15 +#define MAX3421_INTR_PIN 14 + #ifdef __cplusplus } #endif diff --git a/hw/bsp/espressif/boards/family.c b/hw/bsp/espressif/boards/family.c index 8f857fb71..02e478a0c 100644 --- a/hw/bsp/espressif/boards/family.c +++ b/hw/bsp/espressif/boards/family.c @@ -28,11 +28,17 @@ #include "board.h" #include "esp_rom_gpio.h" +#include "esp_mac.h" #include "hal/gpio_ll.h" + +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) #include "hal/usb_hal.h" #include "soc/usb_periph.h" +static void configure_pins(usb_hal_context_t* usb); +#endif -#include "driver/rmt.h" +#include "driver/gpio.h" +#include "driver/uart.h" #if ESP_IDF_VERSION_MAJOR > 4 #include "esp_private/periph_ctrl.h" @@ -40,20 +46,39 @@ #include "driver/periph_ctrl.h" #endif +// Note; current code use UART0 can cause device to reset while monitoring +#define USE_UART 0 +#define UART_ID UART_NUM_0 + #ifdef NEOPIXEL_PIN #include "led_strip.h" -static led_strip_t *strip; +static led_strip_handle_t led_strip; #endif -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM DECLARATION -//--------------------------------------------------------------------+ +#if CFG_TUH_ENABLED && CFG_TUH_MAX3421 +#include "driver/spi_master.h" +static void max3421_init(void); +#endif -static void configure_pins(usb_hal_context_t *usb); + +//--------------------------------------------------------------------+ +// Implementation +//--------------------------------------------------------------------+ // Initialize on-board peripherals : led, button, uart and USB -void board_init(void) -{ +void board_init(void) { +#if USE_UART + // uart init + uart_config_t uart_config = { + .baud_rate = 115200, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE + }; + uart_driver_install(UART_ID, 1024, 0, 0, NULL, 0); + uart_param_config(UART_ID, &uart_config); +#endif #ifdef NEOPIXEL_PIN #ifdef NEOPIXEL_POWER_PIN @@ -63,15 +88,22 @@ void board_init(void) #endif // WS2812 Neopixel driver with RMT peripheral - rmt_config_t config = RMT_DEFAULT_CONFIG_TX(NEOPIXEL_PIN, RMT_CHANNEL_0); - config.clk_div = 2; // set counter clock to 40MHz + led_strip_rmt_config_t rmt_config = { + .clk_src = RMT_CLK_SRC_DEFAULT, // different clock source can lead to different power consumption + .resolution_hz = 10 * 1000 * 1000, // RMT counter clock frequency, default = 10 Mhz + .flags.with_dma = false, // DMA feature is available on ESP target like ESP32-S3 + }; - rmt_config(&config); - rmt_driver_install(config.channel, 0, 0); + led_strip_config_t strip_config = { + .strip_gpio_num = NEOPIXEL_PIN, // The GPIO that connected to the LED strip's data line + .max_leds = 1, // The number of LEDs in the strip, + .led_pixel_format = LED_PIXEL_FORMAT_GRB, // Pixel format of your LED strip + .led_model = LED_MODEL_WS2812, // LED strip model + .flags.invert_out = false, // whether to invert the output signal + }; - led_strip_config_t strip_config = LED_STRIP_DEFAULT_CONFIG(1, (led_strip_dev_t) config.channel); - strip = led_strip_new_rmt_ws2812(&strip_config); - strip->clear(strip, 100); // off led + ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip)); + led_strip_clear(led_strip); // off #endif // Button @@ -79,24 +111,29 @@ void board_init(void) gpio_set_direction(BUTTON_PIN, GPIO_MODE_INPUT); gpio_set_pull_mode(BUTTON_PIN, BUTTON_STATE_ACTIVE ? GPIO_PULLDOWN_ONLY : GPIO_PULLUP_ONLY); +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) // USB Controller Hal init periph_module_reset(PERIPH_USB_MODULE); periph_module_enable(PERIPH_USB_MODULE); usb_hal_context_t hal = { - .use_external_phy = false // use built-in PHY + .use_external_phy = false // use built-in PHY }; usb_hal_init(&hal); configure_pins(&hal); +#endif + +#if CFG_TUH_ENABLED && CFG_TUH_MAX3421 + max3421_init(); +#endif } -static void configure_pins(usb_hal_context_t *usb) -{ +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +static void configure_pins(usb_hal_context_t* usb) { /* usb_periph_iopins currently configures USB_OTG as USB Device. * Introduce additional parameters in usb_hal_context_t when adding support - * for USB Host. - */ - for (const usb_iopin_dsc_t *iopin = usb_periph_iopins; iopin->pin != -1; ++iopin) { + * for USB Host. */ + for (const usb_iopin_dsc_t* iopin = usb_periph_iopins; iopin->pin != -1; ++iopin) { if ((usb->use_external_phy) || (iopin->ext_phy_only == 0)) { esp_rom_gpio_pad_select_gpio(iopin->pin); if (iopin->is_output) { @@ -115,38 +152,158 @@ static void configure_pins(usb_hal_context_t *usb) esp_rom_gpio_pad_unhold(iopin->pin); } } + if (!usb->use_external_phy) { gpio_set_drive_capability(USBPHY_DM_NUM, GPIO_DRIVE_CAP_3); gpio_set_drive_capability(USBPHY_DP_NUM, GPIO_DRIVE_CAP_3); } } +#endif -// Turn LED on or off -void board_led_write(bool state) -{ +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + // use factory default MAC as serial ID + esp_efuse_mac_get_default(id); + return 6; +} + +void board_led_write(bool state) { #ifdef NEOPIXEL_PIN - strip->set_pixel(strip, 0, (state ? 0x88 : 0x00), 0x00, 0x00); - strip->refresh(strip, 100); + led_strip_set_pixel(led_strip, 0, state ? 0x08 : 0x00, 0x00, 0x00); + led_strip_refresh(led_strip); #endif } // Get the current state of button // a '1' means active (pressed), a '0' means inactive. -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { return gpio_get_level(BUTTON_PIN) == BUTTON_STATE_ACTIVE; } // Get characters from UART -int board_uart_read(uint8_t* buf, int len) -{ - (void) buf; (void) len; - return 0; +int board_uart_read(uint8_t* buf, int len) { +#if USE_UART + return uart_read_bytes(UART_ID, buf, len, 0); +#else + return -1; +#endif } // Send characters to UART -int board_uart_write(void const * buf, int len) -{ - (void) buf; (void) len; +int board_uart_write(void const* buf, int len) { + (void) buf; + (void) len; return 0; } + +int board_getchar(void) { + uint8_t c = 0; + return board_uart_read(&c, 1) > 0 ? (int) c : (-1); +} + +//--------------------------------------------------------------------+ +// API: SPI transfer with MAX3421E, must be implemented by application +//--------------------------------------------------------------------+ +#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 + +static spi_device_handle_t max3421_spi; +SemaphoreHandle_t max3421_intr_sem; + +static void IRAM_ATTR max3421_isr_handler(void* arg) { + (void) arg; // arg is gpio num + + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + xSemaphoreGiveFromISR(max3421_intr_sem, &xHigherPriorityTaskWoken); + if (xHigherPriorityTaskWoken) { + portYIELD_FROM_ISR(); + } +} + +static void max3421_intr_task(void* param) { + (void) param; + + while (1) { + xSemaphoreTake(max3421_intr_sem, portMAX_DELAY); + tuh_int_handler(BOARD_TUH_RHPORT, false); + } +} + +static void max3421_init(void) { + // CS pin + gpio_set_direction(MAX3421_CS_PIN, GPIO_MODE_OUTPUT); + gpio_set_level(MAX3421_CS_PIN, 1); + + // SPI + spi_bus_config_t buscfg = { + .miso_io_num = MAX3421_MISO_PIN, + .mosi_io_num = MAX3421_MOSI_PIN, + .sclk_io_num = MAX3421_SCK_PIN, + .quadwp_io_num = -1, + .quadhd_io_num = -1, + .data4_io_num = -1, + .data5_io_num = -1, + .data6_io_num = -1, + .data7_io_num = -1, + .max_transfer_sz = 1024 + }; + ESP_ERROR_CHECK(spi_bus_initialize(MAX3421_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO)); + + spi_device_interface_config_t max3421_cfg = { + .mode = 0, + .clock_speed_hz = 20000000, // S2/S3 can work with 26 Mhz, but esp32 seems only work up to 20 Mhz + .spics_io_num = -1, // manual control CS + .queue_size = 1 + }; + ESP_ERROR_CHECK(spi_bus_add_device(MAX3421_SPI_HOST, &max3421_cfg, &max3421_spi)); + + // Interrupt pin + max3421_intr_sem = xSemaphoreCreateBinary(); + xTaskCreate(max3421_intr_task, "max3421 intr", 2048, NULL, configMAX_PRIORITIES - 2, NULL); + + gpio_set_direction(MAX3421_INTR_PIN, GPIO_MODE_INPUT); + gpio_set_intr_type(MAX3421_INTR_PIN, GPIO_INTR_NEGEDGE); + + gpio_install_isr_service(0); + gpio_isr_handler_add(MAX3421_INTR_PIN, max3421_isr_handler, NULL); +} + +void tuh_max3421_int_api(uint8_t rhport, bool enabled) { + (void) rhport; + if (enabled) { + gpio_intr_enable(MAX3421_INTR_PIN); + } else { + gpio_intr_disable(MAX3421_INTR_PIN); + } +} + +void tuh_max3421_spi_cs_api(uint8_t rhport, bool active) { + (void) rhport; + gpio_set_level(MAX3421_CS_PIN, active ? 0 : 1); +} + +bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const* tx_buf, uint8_t* rx_buf, size_t xfer_bytes) { + (void) rhport; + + if (tx_buf == NULL) { + // fifo read, transmit rx_buf as dummy + tx_buf = rx_buf; + } + + // length in bits + size_t const len_bits = xfer_bytes << 3; + + spi_transaction_t xact = { + .length = len_bits, + .rxlength = rx_buf ? len_bits : 0, + .tx_buffer = tx_buf, + .rx_buffer = rx_buf + }; + + ESP_ERROR_CHECK(spi_device_transmit(max3421_spi, &xact)); + return true; +} + +#endif diff --git a/hw/bsp/espressif/components/led_strip/CHANGELOG.md b/hw/bsp/espressif/components/led_strip/CHANGELOG.md new file mode 100644 index 000000000..51c0cd30c --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/CHANGELOG.md @@ -0,0 +1,38 @@ +## 2.5.0 + +- Enabled support for IDF4.4 and above + - with RMT backend only +- Added API `led_strip_set_pixel_hsv` + +## 2.4.0 + +- Support configurable SPI mode to control leds + - recommend enabling DMA when using SPI mode + +## 2.3.0 + +- Support configurable RMT channel size by setting `mem_block_symbols` + +## 2.2.0 + +- Support for 4 components RGBW leds (SK6812): + - in led_strip_config_t new fields + led_pixel_format, controlling byte format (LED_PIXEL_FORMAT_GRB, LED_PIXEL_FORMAT_GRBW) + led_model, used to configure bit timing (LED_MODEL_WS2812, LED_MODEL_SK6812) + - new API led_strip_set_pixel_rgbw + - new interface type set_pixel_rgbw + +## 2.1.0 + +- Support DMA feature, which offloads the CPU by a lot when it comes to drive a bunch of LEDs +- Support various RMT clock sources +- Acquire and release the power management lock before and after each refresh +- New driver flag: `invert_out` which can invert the led control signal by hardware + +## 2.0.0 + +- Reimplemented the driver using the new RMT driver (`driver/rmt_tx.h`) + +## 1.0.0 + +- Initial driver version, based on the legacy RMT driver (`driver/rmt.h`) diff --git a/hw/bsp/espressif/components/led_strip/CMakeLists.txt b/hw/bsp/espressif/components/led_strip/CMakeLists.txt index 8266c5a1c..15de610cc 100644 --- a/hw/bsp/espressif/components/led_strip/CMakeLists.txt +++ b/hw/bsp/espressif/components/led_strip/CMakeLists.txt @@ -1,7 +1,22 @@ -set(component_srcs "src/led_strip_rmt_ws2812.c") +include($ENV{IDF_PATH}/tools/cmake/version.cmake) -idf_component_register(SRCS "${component_srcs}" - INCLUDE_DIRS "include" - PRIV_INCLUDE_DIRS "" - PRIV_REQUIRES "driver" - REQUIRES "") +set(srcs "src/led_strip_api.c") + +if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "5.0") + if(CONFIG_SOC_RMT_SUPPORTED) + list(APPEND srcs "src/led_strip_rmt_dev.c" "src/led_strip_rmt_encoder.c") + endif() +else() + list(APPEND srcs "src/led_strip_rmt_dev_idf4.c") +endif() + +# the SPI backend driver relies on something that was added in IDF 5.1 +if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "5.1") + if(CONFIG_SOC_GPSPI_SUPPORTED) + list(APPEND srcs "src/led_strip_spi_dev.c") + endif() +endif() + +idf_component_register(SRCS ${srcs} + INCLUDE_DIRS "include" "interface" + REQUIRES "driver") diff --git a/hw/bsp/espressif/components/led_strip/LICENSE b/hw/bsp/espressif/components/led_strip/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/hw/bsp/espressif/components/led_strip/README.md b/hw/bsp/espressif/components/led_strip/README.md new file mode 100644 index 000000000..543d29642 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/README.md @@ -0,0 +1,97 @@ +# LED Strip Driver + +[![Component Registry](https://components.espressif.com/components/espressif/led_strip/badge.svg)](https://components.espressif.com/components/espressif/led_strip) + +This driver is designed for addressable LEDs like [WS2812](http://www.world-semi.com/Certifications/WS2812B.html), where each LED is controlled by a single data line. + +## Backend Controllers + +### The [RMT](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/rmt.html) Peripheral + +This is the most economical way to drive the LEDs because it only consumes one RMT channel, leaving other channels free to use. However, the memory usage increases dramatically with the number of LEDs. If the RMT hardware can't be assist by DMA, the driver will going into interrupt very frequently, thus result in a high CPU usage. What's worse, if the RMT interrupt is delayed or not serviced in time (e.g. if Wi-Fi interrupt happens on the same CPU core), the RMT transaction will be corrupted and the LEDs will display incorrect colors. If you want to use RMT to drive a large number of LEDs, you'd better to enable the DMA feature if possible [^1]. + +#### Allocate LED Strip Object with RMT Backend + +```c +#define BLINK_GPIO 0 + +led_strip_handle_t led_strip; + +/* LED strip initialization with the GPIO and pixels number*/ +led_strip_config_t strip_config = { + .strip_gpio_num = BLINK_GPIO, // The GPIO that connected to the LED strip's data line + .max_leds = 1, // The number of LEDs in the strip, + .led_pixel_format = LED_PIXEL_FORMAT_GRB, // Pixel format of your LED strip + .led_model = LED_MODEL_WS2812, // LED strip model + .flags.invert_out = false, // whether to invert the output signal (useful when your hardware has a level inverter) +}; + +led_strip_rmt_config_t rmt_config = { +#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) + .rmt_channel = 0, +#else + .clk_src = RMT_CLK_SRC_DEFAULT, // different clock source can lead to different power consumption + .resolution_hz = 10 * 1000 * 1000, // 10MHz + .flags.with_dma = false, // whether to enable the DMA feature +#endif +}; +ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip)); +``` + +You can create multiple LED strip objects with different GPIOs and pixel numbers. The backend driver will automatically allocate the RMT channel for you if there is more available. + +### The [SPI](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/spi_master.html) Peripheral + +SPI peripheral can also be used to generate the timing required by the LED strip. However this backend is not as economical as the RMT one, because it will take up the whole **bus**, unlike the RMT just takes one **channel**. You **CAN'T** connect other devices to the same SPI bus if it's been used by the led_strip, because the led_strip doesn't have the concept of "Chip Select". + +Please note, the SPI backend has a dependency of **ESP-IDF >= 5.1** + +#### Allocate LED Strip Object with SPI Backend + +```c +#define BLINK_GPIO 0 + +led_strip_handle_t led_strip; + +/* LED strip initialization with the GPIO and pixels number*/ +led_strip_config_t strip_config = { + .strip_gpio_num = BLINK_GPIO, // The GPIO that connected to the LED strip's data line + .max_leds = 1, // The number of LEDs in the strip, + .led_pixel_format = LED_PIXEL_FORMAT_GRB, // Pixel format of your LED strip + .led_model = LED_MODEL_WS2812, // LED strip model + .flags.invert_out = false, // whether to invert the output signal (useful when your hardware has a level inverter) +}; + +led_strip_spi_config_t spi_config = { + .clk_src = SPI_CLK_SRC_DEFAULT, // different clock source can lead to different power consumption + .flags.with_dma = true, // Using DMA can improve performance and help drive more LEDs + .spi_bus = SPI2_HOST, // SPI bus ID +}; +ESP_ERROR_CHECK(led_strip_new_spi_device(&strip_config, &spi_config, &led_strip)); +``` + +The number of LED strip objects can be created depends on how many free SPI buses are free to use in your project. + +## FAQ + +* Which led_strip backend should I choose? + * It depends on your application requirement and target chip's ability. + + ```mermaid + flowchart LR + A{Is RMT supported?} + A --> |No| B[SPI backend] + B --> C{Does the led strip has \n a larger number of LEDs?} + C --> |No| D[Don't have to enable the DMA of the backend] + C --> |Yes| E[Enable the DMA of the backend] + A --> |Yes| F{Does the led strip has \n a larger number of LEDs?} + F --> |Yes| G{Does RMT support DMA?} + G --> |Yes| E + G --> |No| B + F --> |No| H[RMT backend] --> D + ``` + +* How to set the brightness of the LED strip? + * You can tune the brightness by scaling the value of each R-G-B element with a **same** factor. But pay attention to the overflow of the value. + +[^1]: The RMT DMA feature is not available on all ESP chips. Please check the data sheet before using it. diff --git a/hw/bsp/espressif/components/led_strip/api.md b/hw/bsp/espressif/components/led_strip/api.md new file mode 100644 index 000000000..6581d6604 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/api.md @@ -0,0 +1,454 @@ +# API Reference + +## Header files + +- [include/led_strip.h](#file-includeled_striph) +- [include/led_strip_rmt.h](#file-includeled_strip_rmth) +- [include/led_strip_spi.h](#file-includeled_strip_spih) +- [include/led_strip_types.h](#file-includeled_strip_typesh) +- [interface/led_strip_interface.h](#file-interfaceled_strip_interfaceh) + +## File include/led_strip.h + +## Functions + +| Type | Name | +| ---: | :--- | +| esp\_err\_t | [**led\_strip\_clear**](#function-led_strip_clear) ([**led\_strip\_handle\_t**](#struct-led_strip_t) strip)
_Clear LED strip (turn off all LEDs)_ | +| esp\_err\_t | [**led\_strip\_del**](#function-led_strip_del) ([**led\_strip\_handle\_t**](#struct-led_strip_t) strip)
_Free LED strip resources._ | +| esp\_err\_t | [**led\_strip\_refresh**](#function-led_strip_refresh) ([**led\_strip\_handle\_t**](#struct-led_strip_t) strip)
_Refresh memory colors to LEDs._ | +| esp\_err\_t | [**led\_strip\_set\_pixel**](#function-led_strip_set_pixel) ([**led\_strip\_handle\_t**](#struct-led_strip_t) strip, uint32\_t index, uint32\_t red, uint32\_t green, uint32\_t blue)
_Set RGB for a specific pixel._ | +| esp\_err\_t | [**led\_strip\_set\_pixel\_hsv**](#function-led_strip_set_pixel_hsv) ([**led\_strip\_handle\_t**](#struct-led_strip_t) strip, uint32\_t index, uint16\_t hue, uint8\_t saturation, uint8\_t value)
_Set HSV for a specific pixel._ | +| esp\_err\_t | [**led\_strip\_set\_pixel\_rgbw**](#function-led_strip_set_pixel_rgbw) ([**led\_strip\_handle\_t**](#struct-led_strip_t) strip, uint32\_t index, uint32\_t red, uint32\_t green, uint32\_t blue, uint32\_t white)
_Set RGBW for a specific pixel._ | + +## Functions Documentation + +### function `led_strip_clear` + +_Clear LED strip (turn off all LEDs)_ + +```c +esp_err_t led_strip_clear ( + led_strip_handle_t strip +) +``` + +**Parameters:** + +- `strip` LED strip + +**Returns:** + +- ESP\_OK: Clear LEDs successfully +- ESP\_FAIL: Clear LEDs failed because some other error occurred + +### function `led_strip_del` + +_Free LED strip resources._ + +```c +esp_err_t led_strip_del ( + led_strip_handle_t strip +) +``` + +**Parameters:** + +- `strip` LED strip + +**Returns:** + +- ESP\_OK: Free resources successfully +- ESP\_FAIL: Free resources failed because error occurred + +### function `led_strip_refresh` + +_Refresh memory colors to LEDs._ + +```c +esp_err_t led_strip_refresh ( + led_strip_handle_t strip +) +``` + +**Parameters:** + +- `strip` LED strip + +**Returns:** + +- ESP\_OK: Refresh successfully +- ESP\_FAIL: Refresh failed because some other error occurred + +**Note:** + +: After updating the LED colors in the memory, a following invocation of this API is needed to flush colors to strip. + +### function `led_strip_set_pixel` + +_Set RGB for a specific pixel._ + +```c +esp_err_t led_strip_set_pixel ( + led_strip_handle_t strip, + uint32_t index, + uint32_t red, + uint32_t green, + uint32_t blue +) +``` + +**Parameters:** + +- `strip` LED strip +- `index` index of pixel to set +- `red` red part of color +- `green` green part of color +- `blue` blue part of color + +**Returns:** + +- ESP\_OK: Set RGB for a specific pixel successfully +- ESP\_ERR\_INVALID\_ARG: Set RGB for a specific pixel failed because of invalid parameters +- ESP\_FAIL: Set RGB for a specific pixel failed because other error occurred + +### function `led_strip_set_pixel_hsv` + +_Set HSV for a specific pixel._ + +```c +esp_err_t led_strip_set_pixel_hsv ( + led_strip_handle_t strip, + uint32_t index, + uint16_t hue, + uint8_t saturation, + uint8_t value +) +``` + +**Parameters:** + +- `strip` LED strip +- `index` index of pixel to set +- `hue` hue part of color (0 - 360) +- `saturation` saturation part of color (0 - 255) +- `value` value part of color (0 - 255) + +**Returns:** + +- ESP\_OK: Set HSV color for a specific pixel successfully +- ESP\_ERR\_INVALID\_ARG: Set HSV color for a specific pixel failed because of an invalid argument +- ESP\_FAIL: Set HSV color for a specific pixel failed because other error occurred + +### function `led_strip_set_pixel_rgbw` + +_Set RGBW for a specific pixel._ + +```c +esp_err_t led_strip_set_pixel_rgbw ( + led_strip_handle_t strip, + uint32_t index, + uint32_t red, + uint32_t green, + uint32_t blue, + uint32_t white +) +``` + +**Note:** + +Only call this function if your led strip does have the white component (e.g. SK6812-RGBW) + +**Note:** + +Also see `led_strip_set_pixel` if you only want to specify the RGB part of the color and bypass the white component + +**Parameters:** + +- `strip` LED strip +- `index` index of pixel to set +- `red` red part of color +- `green` green part of color +- `blue` blue part of color +- `white` separate white component + +**Returns:** + +- ESP\_OK: Set RGBW color for a specific pixel successfully +- ESP\_ERR\_INVALID\_ARG: Set RGBW color for a specific pixel failed because of an invalid argument +- ESP\_FAIL: Set RGBW color for a specific pixel failed because other error occurred + +## File include/led_strip_rmt.h + +## Structures and Types + +| Type | Name | +| ---: | :--- | +| struct | [**led\_strip\_rmt\_config\_t**](#struct-led_strip_rmt_config_t)
_LED Strip RMT specific configuration._ | + +## Functions + +| Type | Name | +| ---: | :--- | +| esp\_err\_t | [**led\_strip\_new\_rmt\_device**](#function-led_strip_new_rmt_device) (const [**led\_strip\_config\_t**](#struct-led_strip_config_t) \*led\_config, const [**led\_strip\_rmt\_config\_t**](#struct-led_strip_rmt_config_t) \*rmt\_config, [**led\_strip\_handle\_t**](#struct-led_strip_t) \*ret\_strip)
_Create LED strip based on RMT TX channel._ | + +## Structures and Types Documentation + +### struct `led_strip_rmt_config_t` + +_LED Strip RMT specific configuration._ + +Variables: + +- rmt\_clock\_source\_t clk_src
RMT clock source + +- struct [**led\_strip\_rmt\_config\_t**](#struct-led_strip_rmt_config_t) flags
Extra driver flags + +- size\_t mem_block_symbols
How many RMT symbols can one RMT channel hold at one time. Set to 0 will fallback to use the default size. + +- uint32\_t resolution_hz
RMT tick resolution, if set to zero, a default resolution (10MHz) will be applied + +- uint32\_t with_dma
Use DMA to transmit data + +## Functions Documentation + +### function `led_strip_new_rmt_device` + +_Create LED strip based on RMT TX channel._ + +```c +esp_err_t led_strip_new_rmt_device ( + const led_strip_config_t *led_config, + const led_strip_rmt_config_t *rmt_config, + led_strip_handle_t *ret_strip +) +``` + +**Parameters:** + +- `led_config` LED strip configuration +- `rmt_config` RMT specific configuration +- `ret_strip` Returned LED strip handle + +**Returns:** + +- ESP\_OK: create LED strip handle successfully +- ESP\_ERR\_INVALID\_ARG: create LED strip handle failed because of invalid argument +- ESP\_ERR\_NO\_MEM: create LED strip handle failed because of out of memory +- ESP\_FAIL: create LED strip handle failed because some other error + +## File include/led_strip_spi.h + +## Structures and Types + +| Type | Name | +| ---: | :--- | +| struct | [**led\_strip\_spi\_config\_t**](#struct-led_strip_spi_config_t)
_LED Strip SPI specific configuration._ | + +## Functions + +| Type | Name | +| ---: | :--- | +| esp\_err\_t | [**led\_strip\_new\_spi\_device**](#function-led_strip_new_spi_device) (const [**led\_strip\_config\_t**](#struct-led_strip_config_t) \*led\_config, const [**led\_strip\_spi\_config\_t**](#struct-led_strip_spi_config_t) \*spi\_config, [**led\_strip\_handle\_t**](#struct-led_strip_t) \*ret\_strip)
_Create LED strip based on SPI MOSI channel._ | + +## Structures and Types Documentation + +### struct `led_strip_spi_config_t` + +_LED Strip SPI specific configuration._ + +Variables: + +- spi\_clock\_source\_t clk_src
SPI clock source + +- struct [**led\_strip\_spi\_config\_t**](#struct-led_strip_spi_config_t) flags
Extra driver flags + +- spi\_host\_device\_t spi_bus
SPI bus ID. Which buses are available depends on the specific chip + +- uint32\_t with_dma
Use DMA to transmit data + +## Functions Documentation + +### function `led_strip_new_spi_device` + +_Create LED strip based on SPI MOSI channel._ + +```c +esp_err_t led_strip_new_spi_device ( + const led_strip_config_t *led_config, + const led_strip_spi_config_t *spi_config, + led_strip_handle_t *ret_strip +) +``` + +**Note:** + +Although only the MOSI line is used for generating the signal, the whole SPI bus can't be used for other purposes. + +**Parameters:** + +- `led_config` LED strip configuration +- `spi_config` SPI specific configuration +- `ret_strip` Returned LED strip handle + +**Returns:** + +- ESP\_OK: create LED strip handle successfully +- ESP\_ERR\_INVALID\_ARG: create LED strip handle failed because of invalid argument +- ESP\_ERR\_NOT\_SUPPORTED: create LED strip handle failed because of unsupported configuration +- ESP\_ERR\_NO\_MEM: create LED strip handle failed because of out of memory +- ESP\_FAIL: create LED strip handle failed because some other error + +## File include/led_strip_types.h + +## Structures and Types + +| Type | Name | +| ---: | :--- | +| enum | [**led\_model\_t**](#enum-led_model_t)
_LED strip model._ | +| enum | [**led\_pixel\_format\_t**](#enum-led_pixel_format_t)
_LED strip pixel format._ | +| struct | [**led\_strip\_config\_t**](#struct-led_strip_config_t)
_LED Strip Configuration._ | +| typedef struct [**led\_strip\_t**](#struct-led_strip_t) \* | [**led\_strip\_handle\_t**](#typedef-led_strip_handle_t)
_LED strip handle._ | + +## Structures and Types Documentation + +### enum `led_model_t` + +_LED strip model._ + +```c +enum led_model_t { + LED_MODEL_WS2812, + LED_MODEL_SK6812, + LED_MODEL_INVALID +}; +``` + +**Note:** + +Different led model may have different timing parameters, so we need to distinguish them. + +### enum `led_pixel_format_t` + +_LED strip pixel format._ + +```c +enum led_pixel_format_t { + LED_PIXEL_FORMAT_GRB, + LED_PIXEL_FORMAT_GRBW, + LED_PIXEL_FORMAT_INVALID +}; +``` + +### struct `led_strip_config_t` + +_LED Strip Configuration._ + +Variables: + +- struct [**led\_strip\_config\_t**](#struct-led_strip_config_t) flags
Extra driver flags + +- uint32\_t invert_out
Invert output signal + +- led\_model\_t led_model
LED model + +- led\_pixel\_format\_t led_pixel_format
LED pixel format + +- uint32\_t max_leds
Maximum LEDs in a single strip + +- int strip_gpio_num
GPIO number that used by LED strip + +### typedef `led_strip_handle_t` + +_LED strip handle._ + +```c +typedef struct led_strip_t* led_strip_handle_t; +``` + +## File interface/led_strip_interface.h + +## Structures and Types + +| Type | Name | +| ---: | :--- | +| struct | [**led\_strip\_t**](#struct-led_strip_t)
_LED strip interface definition._ | +| typedef struct [**led\_strip\_t**](#struct-led_strip_t) | [**led\_strip\_t**](#typedef-led_strip_t)
| + +## Structures and Types Documentation + +### struct `led_strip_t` + +_LED strip interface definition._ + +Variables: + +- esp\_err\_t(\* clear
_Clear LED strip (turn off all LEDs)_
**Parameters:** + +- `strip` LED strip +- `timeout_ms` timeout value for clearing task + +**Returns:** + +- ESP\_OK: Clear LEDs successfully +- ESP\_FAIL: Clear LEDs failed because some other error occurred + +- esp\_err\_t(\* del
_Free LED strip resources._
**Parameters:** + +- `strip` LED strip + +**Returns:** + +- ESP\_OK: Free resources successfully +- ESP\_FAIL: Free resources failed because error occurred + +- esp\_err\_t(\* refresh
_Refresh memory colors to LEDs._
**Parameters:** + +- `strip` LED strip +- `timeout_ms` timeout value for refreshing task + +**Returns:** + +- ESP\_OK: Refresh successfully +- ESP\_FAIL: Refresh failed because some other error occurred + +**Note:** + +: After updating the LED colors in the memory, a following invocation of this API is needed to flush colors to strip. + +- esp\_err\_t(\* set_pixel
_Set RGB for a specific pixel._
**Parameters:** + +- `strip` LED strip +- `index` index of pixel to set +- `red` red part of color +- `green` green part of color +- `blue` blue part of color + +**Returns:** + +- ESP\_OK: Set RGB for a specific pixel successfully +- ESP\_ERR\_INVALID\_ARG: Set RGB for a specific pixel failed because of invalid parameters +- ESP\_FAIL: Set RGB for a specific pixel failed because other error occurred + +- esp\_err\_t(\* set_pixel_rgbw
_Set RGBW for a specific pixel. Similar to_ `set_pixel`_but also set the white component._
**Parameters:** + +- `strip` LED strip +- `index` index of pixel to set +- `red` red part of color +- `green` green part of color +- `blue` blue part of color +- `white` separate white component + +**Returns:** + +- ESP\_OK: Set RGBW color for a specific pixel successfully +- ESP\_ERR\_INVALID\_ARG: Set RGBW color for a specific pixel failed because of an invalid argument +- ESP\_FAIL: Set RGBW color for a specific pixel failed because other error occurred + +### typedef `led_strip_t` + +```c +typedef struct led_strip_t led_strip_t; +``` + +Type of LED strip diff --git a/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/CMakeLists.txt b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/CMakeLists.txt new file mode 100644 index 000000000..923c46310 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/CMakeLists.txt @@ -0,0 +1,9 @@ +# For more information about build system see +# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html +# The following five lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +set(IDF_TARGET "esp32s3") +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(led_strip_rmt_ws2812) diff --git a/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/README.md b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/README.md new file mode 100644 index 000000000..ad52235d5 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/README.md @@ -0,0 +1,31 @@ +# LED Strip Example (RMT backend + WS2812) + +This example demonstrates how to blink the WS2812 LED using the [led_strip](https://components.espressif.com/component/espressif/led_strip) component. + +## How to Use Example + +### Hardware Required + +* A development board with Espressif SoC +* A USB cable for Power supply and programming +* WS2812 LED strip + +### Configure the Example + +Before project configuration and build, be sure to set the correct chip target using `idf.py set-target `. Then assign the proper GPIO in the [source file](main/led_strip_rmt_ws2812_main.c). If your led strip has multiple LEDs, don't forget update the number. + +### Build and Flash + +Run `idf.py -p PORT build flash monitor` to build, flash and monitor the project. + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +```text +I (299) gpio: GPIO[8]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 +I (309) example: Created LED strip object with RMT backend +I (309) example: Start blinking LED strip +``` diff --git a/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/CMakeLists.txt b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/CMakeLists.txt new file mode 100644 index 000000000..37b9c1458 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "led_strip_rmt_ws2812_main.c" + INCLUDE_DIRS ".") diff --git a/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/idf_component.yml b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/idf_component.yml new file mode 100644 index 000000000..916c366c7 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/idf_component.yml @@ -0,0 +1,5 @@ +## IDF Component Manager Manifest File +dependencies: + espressif/led_strip: + version: '^2' + override_path: '../../../' diff --git a/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/led_strip_rmt_ws2812_main.c b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/led_strip_rmt_ws2812_main.c new file mode 100644 index 000000000..4b20a5958 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/examples/led_strip_rmt_ws2812/main/led_strip_rmt_ws2812_main.c @@ -0,0 +1,75 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "led_strip.h" +#include "esp_log.h" +#include "esp_err.h" + +// GPIO assignment +#define LED_STRIP_BLINK_GPIO 48 +// Numbers of the LED in the strip +#define LED_STRIP_LED_NUMBERS 1 +// 10MHz resolution, 1 tick = 0.1us (led strip needs a high resolution) +#define LED_STRIP_RMT_RES_HZ (10 * 1000 * 1000) + +static const char *TAG = "example"; + +led_strip_handle_t configure_led(void) +{ + // LED strip general initialization, according to your led board design + led_strip_config_t strip_config = { + .strip_gpio_num = LED_STRIP_BLINK_GPIO, // The GPIO that connected to the LED strip's data line + .max_leds = LED_STRIP_LED_NUMBERS, // The number of LEDs in the strip, + .led_pixel_format = LED_PIXEL_FORMAT_GRB, // Pixel format of your LED strip + .led_model = LED_MODEL_WS2812, // LED strip model + .flags.invert_out = false, // whether to invert the output signal + }; + + // LED strip backend configuration: RMT + led_strip_rmt_config_t rmt_config = { +#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) + .rmt_channel = 0, +#else + .clk_src = RMT_CLK_SRC_DEFAULT, // different clock source can lead to different power consumption + .resolution_hz = LED_STRIP_RMT_RES_HZ, // RMT counter clock frequency + .flags.with_dma = false, // DMA feature is available on ESP target like ESP32-S3 +#endif + }; + + // LED Strip object handle + led_strip_handle_t led_strip; + ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip)); + ESP_LOGI(TAG, "Created LED strip object with RMT backend"); + return led_strip; +} + +void app_main(void) +{ + led_strip_handle_t led_strip = configure_led(); + bool led_on_off = false; + + ESP_LOGI(TAG, "Start blinking LED strip"); + while (1) { + if (led_on_off) { + /* Set the LED pixel using RGB from 0 (0%) to 255 (100%) for each color */ + for (int i = 0; i < LED_STRIP_LED_NUMBERS; i++) { + ESP_ERROR_CHECK(led_strip_set_pixel(led_strip, i, 5, 5, 5)); + } + /* Refresh the strip to send data */ + ESP_ERROR_CHECK(led_strip_refresh(led_strip)); + ESP_LOGI(TAG, "LED ON!"); + } else { + /* Set all LED off to clear all pixels */ + ESP_ERROR_CHECK(led_strip_clear(led_strip)); + ESP_LOGI(TAG, "LED OFF!"); + } + + led_on_off = !led_on_off; + vTaskDelay(pdMS_TO_TICKS(500)); + } +} diff --git a/hw/bsp/espressif/components/led_strip/idf_component.yml b/hw/bsp/espressif/components/led_strip/idf_component.yml new file mode 100644 index 000000000..1fd9b83ee --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/idf_component.yml @@ -0,0 +1,5 @@ +version: "2.5.2" +description: Driver for Addressable LED Strip (WS2812, etc) +url: https://github.com/espressif/idf-extra-components/tree/master/led_strip +dependencies: + idf: ">=4.4" diff --git a/hw/bsp/espressif/components/led_strip/include/led_strip.h b/hw/bsp/espressif/components/led_strip/include/led_strip.h index a9dffc325..38711744a 100644 --- a/hw/bsp/espressif/components/led_strip/include/led_strip.h +++ b/hw/bsp/espressif/components/led_strip/include/led_strip.h @@ -1,125 +1,110 @@ -// Copyright 2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once +#include +#include "esp_err.h" +#include "led_strip_rmt.h" +#include "esp_idf_version.h" + +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0) +#include "led_strip_spi.h" +#endif + #ifdef __cplusplus extern "C" { #endif -#include "esp_err.h" - /** -* @brief LED Strip Type -* -*/ -typedef struct led_strip_s led_strip_t; - -/** -* @brief LED Strip Device Type -* -*/ -typedef void *led_strip_dev_t; - -/** -* @brief Declare of LED Strip Type -* -*/ -struct led_strip_s { - /** - * @brief Set RGB for a specific pixel - * - * @param strip: LED strip - * @param index: index of pixel to set - * @param red: red part of color - * @param green: green part of color - * @param blue: blue part of color - * - * @return - * - ESP_OK: Set RGB for a specific pixel successfully - * - ESP_ERR_INVALID_ARG: Set RGB for a specific pixel failed because of invalid parameters - * - ESP_FAIL: Set RGB for a specific pixel failed because other error occurred - */ - esp_err_t (*set_pixel)(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue); - - /** - * @brief Refresh memory colors to LEDs - * - * @param strip: LED strip - * @param timeout_ms: timeout value for refreshing task - * - * @return - * - ESP_OK: Refresh successfully - * - ESP_ERR_TIMEOUT: Refresh failed because of timeout - * - ESP_FAIL: Refresh failed because some other error occurred - * - * @note: - * After updating the LED colors in the memory, a following invocation of this API is needed to flush colors to strip. - */ - esp_err_t (*refresh)(led_strip_t *strip, uint32_t timeout_ms); - - /** - * @brief Clear LED strip (turn off all LEDs) - * - * @param strip: LED strip - * @param timeout_ms: timeout value for clearing task - * - * @return - * - ESP_OK: Clear LEDs successfully - * - ESP_ERR_TIMEOUT: Clear LEDs failed because of timeout - * - ESP_FAIL: Clear LEDs failed because some other error occurred - */ - esp_err_t (*clear)(led_strip_t *strip, uint32_t timeout_ms); - - /** - * @brief Free LED strip resources - * - * @param strip: LED strip - * - * @return - * - ESP_OK: Free resources successfully - * - ESP_FAIL: Free resources failed because error occurred - */ - esp_err_t (*del)(led_strip_t *strip); -}; - -/** -* @brief LED Strip Configuration Type -* -*/ -typedef struct { - uint32_t max_leds; /*!< Maximum LEDs in a single strip */ - led_strip_dev_t dev; /*!< LED strip device (e.g. RMT channel, PWM channel, etc) */ -} led_strip_config_t; - -/** - * @brief Default configuration for LED strip + * @brief Set RGB for a specific pixel * + * @param strip: LED strip + * @param index: index of pixel to set + * @param red: red part of color + * @param green: green part of color + * @param blue: blue part of color + * + * @return + * - ESP_OK: Set RGB for a specific pixel successfully + * - ESP_ERR_INVALID_ARG: Set RGB for a specific pixel failed because of invalid parameters + * - ESP_FAIL: Set RGB for a specific pixel failed because other error occurred */ -#define LED_STRIP_DEFAULT_CONFIG(number, dev_hdl) \ - { \ - .max_leds = number, \ - .dev = dev_hdl, \ - } +esp_err_t led_strip_set_pixel(led_strip_handle_t strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue); /** -* @brief Install a new ws2812 driver (based on RMT peripheral) -* -* @param config: LED strip configuration -* @return -* LED strip instance or NULL -*/ -led_strip_t *led_strip_new_rmt_ws2812(const led_strip_config_t *config); + * @brief Set RGBW for a specific pixel + * + * @note Only call this function if your led strip does have the white component (e.g. SK6812-RGBW) + * @note Also see `led_strip_set_pixel` if you only want to specify the RGB part of the color and bypass the white component + * + * @param strip: LED strip + * @param index: index of pixel to set + * @param red: red part of color + * @param green: green part of color + * @param blue: blue part of color + * @param white: separate white component + * + * @return + * - ESP_OK: Set RGBW color for a specific pixel successfully + * - ESP_ERR_INVALID_ARG: Set RGBW color for a specific pixel failed because of an invalid argument + * - ESP_FAIL: Set RGBW color for a specific pixel failed because other error occurred + */ +esp_err_t led_strip_set_pixel_rgbw(led_strip_handle_t strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white); + +/** + * @brief Set HSV for a specific pixel + * + * @param strip: LED strip + * @param index: index of pixel to set + * @param hue: hue part of color (0 - 360) + * @param saturation: saturation part of color (0 - 255) + * @param value: value part of color (0 - 255) + * + * @return + * - ESP_OK: Set HSV color for a specific pixel successfully + * - ESP_ERR_INVALID_ARG: Set HSV color for a specific pixel failed because of an invalid argument + * - ESP_FAIL: Set HSV color for a specific pixel failed because other error occurred + */ +esp_err_t led_strip_set_pixel_hsv(led_strip_handle_t strip, uint32_t index, uint16_t hue, uint8_t saturation, uint8_t value); + +/** + * @brief Refresh memory colors to LEDs + * + * @param strip: LED strip + * + * @return + * - ESP_OK: Refresh successfully + * - ESP_FAIL: Refresh failed because some other error occurred + * + * @note: + * After updating the LED colors in the memory, a following invocation of this API is needed to flush colors to strip. + */ +esp_err_t led_strip_refresh(led_strip_handle_t strip); + +/** + * @brief Clear LED strip (turn off all LEDs) + * + * @param strip: LED strip + * + * @return + * - ESP_OK: Clear LEDs successfully + * - ESP_FAIL: Clear LEDs failed because some other error occurred + */ +esp_err_t led_strip_clear(led_strip_handle_t strip); + +/** + * @brief Free LED strip resources + * + * @param strip: LED strip + * + * @return + * - ESP_OK: Free resources successfully + * - ESP_FAIL: Free resources failed because error occurred + */ +esp_err_t led_strip_del(led_strip_handle_t strip); #ifdef __cplusplus } diff --git a/hw/bsp/espressif/components/led_strip/include/led_strip_rmt.h b/hw/bsp/espressif/components/led_strip/include/led_strip_rmt.h new file mode 100644 index 000000000..b575aeaba --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/include/led_strip_rmt.h @@ -0,0 +1,53 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include "esp_err.h" +#include "led_strip_types.h" +#include "esp_idf_version.h" + +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) +#include "driver/rmt_types.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief LED Strip RMT specific configuration + */ +typedef struct { +#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) + uint8_t rmt_channel; /*!< Specify the channel number, the legacy RMT driver doesn't support channel allocator */ +#else // new driver supports specify the clock source and clock resolution + rmt_clock_source_t clk_src; /*!< RMT clock source */ + uint32_t resolution_hz; /*!< RMT tick resolution, if set to zero, a default resolution (10MHz) will be applied */ +#endif + size_t mem_block_symbols; /*!< How many RMT symbols can one RMT channel hold at one time. Set to 0 will fallback to use the default size. */ + struct { + uint32_t with_dma: 1; /*!< Use DMA to transmit data */ + } flags; /*!< Extra driver flags */ +} led_strip_rmt_config_t; + +/** + * @brief Create LED strip based on RMT TX channel + * + * @param led_config LED strip configuration + * @param rmt_config RMT specific configuration + * @param ret_strip Returned LED strip handle + * @return + * - ESP_OK: create LED strip handle successfully + * - ESP_ERR_INVALID_ARG: create LED strip handle failed because of invalid argument + * - ESP_ERR_NO_MEM: create LED strip handle failed because of out of memory + * - ESP_FAIL: create LED strip handle failed because some other error + */ +esp_err_t led_strip_new_rmt_device(const led_strip_config_t *led_config, const led_strip_rmt_config_t *rmt_config, led_strip_handle_t *ret_strip); + +#ifdef __cplusplus +} +#endif diff --git a/hw/bsp/espressif/components/led_strip/include/led_strip_spi.h b/hw/bsp/espressif/components/led_strip/include/led_strip_spi.h new file mode 100644 index 000000000..eb3524936 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/include/led_strip_spi.h @@ -0,0 +1,46 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include "esp_err.h" +#include "driver/spi_master.h" +#include "led_strip_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief LED Strip SPI specific configuration + */ +typedef struct { + spi_clock_source_t clk_src; /*!< SPI clock source */ + spi_host_device_t spi_bus; /*!< SPI bus ID. Which buses are available depends on the specific chip */ + struct { + uint32_t with_dma: 1; /*!< Use DMA to transmit data */ + } flags; /*!< Extra driver flags */ +} led_strip_spi_config_t; + +/** + * @brief Create LED strip based on SPI MOSI channel + * @note Although only the MOSI line is used for generating the signal, the whole SPI bus can't be used for other purposes. + * + * @param led_config LED strip configuration + * @param spi_config SPI specific configuration + * @param ret_strip Returned LED strip handle + * @return + * - ESP_OK: create LED strip handle successfully + * - ESP_ERR_INVALID_ARG: create LED strip handle failed because of invalid argument + * - ESP_ERR_NOT_SUPPORTED: create LED strip handle failed because of unsupported configuration + * - ESP_ERR_NO_MEM: create LED strip handle failed because of out of memory + * - ESP_FAIL: create LED strip handle failed because some other error + */ +esp_err_t led_strip_new_spi_device(const led_strip_config_t *led_config, const led_strip_spi_config_t *spi_config, led_strip_handle_t *ret_strip); + +#ifdef __cplusplus +} +#endif diff --git a/hw/bsp/espressif/components/led_strip/include/led_strip_types.h b/hw/bsp/espressif/components/led_strip/include/led_strip_types.h new file mode 100644 index 000000000..691f0bc39 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/include/led_strip_types.h @@ -0,0 +1,54 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief LED strip pixel format + */ +typedef enum { + LED_PIXEL_FORMAT_GRB, /*!< Pixel format: GRB */ + LED_PIXEL_FORMAT_GRBW, /*!< Pixel format: GRBW */ + LED_PIXEL_FORMAT_INVALID /*!< Invalid pixel format */ +} led_pixel_format_t; + +/** + * @brief LED strip model + * @note Different led model may have different timing parameters, so we need to distinguish them. + */ +typedef enum { + LED_MODEL_WS2812, /*!< LED strip model: WS2812 */ + LED_MODEL_SK6812, /*!< LED strip model: SK6812 */ + LED_MODEL_INVALID /*!< Invalid LED strip model */ +} led_model_t; + +/** + * @brief LED strip handle + */ +typedef struct led_strip_t *led_strip_handle_t; + +/** + * @brief LED Strip Configuration + */ +typedef struct { + int strip_gpio_num; /*!< GPIO number that used by LED strip */ + uint32_t max_leds; /*!< Maximum LEDs in a single strip */ + led_pixel_format_t led_pixel_format; /*!< LED pixel format */ + led_model_t led_model; /*!< LED model */ + + struct { + uint32_t invert_out: 1; /*!< Invert output signal */ + } flags; /*!< Extra driver flags */ +} led_strip_config_t; + +#ifdef __cplusplus +} +#endif diff --git a/hw/bsp/espressif/components/led_strip/interface/led_strip_interface.h b/hw/bsp/espressif/components/led_strip/interface/led_strip_interface.h new file mode 100644 index 000000000..3de4c2715 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/interface/led_strip_interface.h @@ -0,0 +1,95 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct led_strip_t led_strip_t; /*!< Type of LED strip */ + +/** + * @brief LED strip interface definition + */ +struct led_strip_t { + /** + * @brief Set RGB for a specific pixel + * + * @param strip: LED strip + * @param index: index of pixel to set + * @param red: red part of color + * @param green: green part of color + * @param blue: blue part of color + * + * @return + * - ESP_OK: Set RGB for a specific pixel successfully + * - ESP_ERR_INVALID_ARG: Set RGB for a specific pixel failed because of invalid parameters + * - ESP_FAIL: Set RGB for a specific pixel failed because other error occurred + */ + esp_err_t (*set_pixel)(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue); + + /** + * @brief Set RGBW for a specific pixel. Similar to `set_pixel` but also set the white component + * + * @param strip: LED strip + * @param index: index of pixel to set + * @param red: red part of color + * @param green: green part of color + * @param blue: blue part of color + * @param white: separate white component + * + * @return + * - ESP_OK: Set RGBW color for a specific pixel successfully + * - ESP_ERR_INVALID_ARG: Set RGBW color for a specific pixel failed because of an invalid argument + * - ESP_FAIL: Set RGBW color for a specific pixel failed because other error occurred + */ + esp_err_t (*set_pixel_rgbw)(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white); + + /** + * @brief Refresh memory colors to LEDs + * + * @param strip: LED strip + * @param timeout_ms: timeout value for refreshing task + * + * @return + * - ESP_OK: Refresh successfully + * - ESP_FAIL: Refresh failed because some other error occurred + * + * @note: + * After updating the LED colors in the memory, a following invocation of this API is needed to flush colors to strip. + */ + esp_err_t (*refresh)(led_strip_t *strip); + + /** + * @brief Clear LED strip (turn off all LEDs) + * + * @param strip: LED strip + * @param timeout_ms: timeout value for clearing task + * + * @return + * - ESP_OK: Clear LEDs successfully + * - ESP_FAIL: Clear LEDs failed because some other error occurred + */ + esp_err_t (*clear)(led_strip_t *strip); + + /** + * @brief Free LED strip resources + * + * @param strip: LED strip + * + * @return + * - ESP_OK: Free resources successfully + * - ESP_FAIL: Free resources failed because error occurred + */ + esp_err_t (*del)(led_strip_t *strip); +}; + +#ifdef __cplusplus +} +#endif diff --git a/hw/bsp/espressif/components/led_strip/src/led_strip_api.c b/hw/bsp/espressif/components/led_strip/src/led_strip_api.c new file mode 100644 index 000000000..6eb86b8f1 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/src/led_strip_api.c @@ -0,0 +1,94 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "esp_log.h" +#include "esp_check.h" +#include "led_strip.h" +#include "led_strip_interface.h" + +static const char *TAG = "led_strip"; + +esp_err_t led_strip_set_pixel(led_strip_handle_t strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue) +{ + ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + return strip->set_pixel(strip, index, red, green, blue); +} + +esp_err_t led_strip_set_pixel_hsv(led_strip_handle_t strip, uint32_t index, uint16_t hue, uint8_t saturation, uint8_t value) +{ + ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + + uint32_t red = 0; + uint32_t green = 0; + uint32_t blue = 0; + + uint32_t rgb_max = value; + uint32_t rgb_min = rgb_max * (255 - saturation) / 255.0f; + + uint32_t i = hue / 60; + uint32_t diff = hue % 60; + + // RGB adjustment amount by hue + uint32_t rgb_adj = (rgb_max - rgb_min) * diff / 60; + + switch (i) { + case 0: + red = rgb_max; + green = rgb_min + rgb_adj; + blue = rgb_min; + break; + case 1: + red = rgb_max - rgb_adj; + green = rgb_max; + blue = rgb_min; + break; + case 2: + red = rgb_min; + green = rgb_max; + blue = rgb_min + rgb_adj; + break; + case 3: + red = rgb_min; + green = rgb_max - rgb_adj; + blue = rgb_max; + break; + case 4: + red = rgb_min + rgb_adj; + green = rgb_min; + blue = rgb_max; + break; + default: + red = rgb_max; + green = rgb_min; + blue = rgb_max - rgb_adj; + break; + } + + return strip->set_pixel(strip, index, red, green, blue); +} + +esp_err_t led_strip_set_pixel_rgbw(led_strip_handle_t strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white) +{ + ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + return strip->set_pixel_rgbw(strip, index, red, green, blue, white); +} + +esp_err_t led_strip_refresh(led_strip_handle_t strip) +{ + ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + return strip->refresh(strip); +} + +esp_err_t led_strip_clear(led_strip_handle_t strip) +{ + ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + return strip->clear(strip); +} + +esp_err_t led_strip_del(led_strip_handle_t strip) +{ + ESP_RETURN_ON_FALSE(strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + return strip->del(strip); +} diff --git a/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_dev.c b/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_dev.c new file mode 100644 index 000000000..1cbf0e45a --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_dev.c @@ -0,0 +1,164 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include "esp_log.h" +#include "esp_check.h" +#include "driver/rmt_tx.h" +#include "led_strip.h" +#include "led_strip_interface.h" +#include "led_strip_rmt_encoder.h" + +#define LED_STRIP_RMT_DEFAULT_RESOLUTION 10000000 // 10MHz resolution +#define LED_STRIP_RMT_DEFAULT_TRANS_QUEUE_SIZE 4 +// the memory size of each RMT channel, in words (4 bytes) +#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 +#define LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS 64 +#else +#define LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS 48 +#endif + +static const char *TAG = "led_strip_rmt"; + +typedef struct { + led_strip_t base; + rmt_channel_handle_t rmt_chan; + rmt_encoder_handle_t strip_encoder; + uint32_t strip_len; + uint8_t bytes_per_pixel; + uint8_t pixel_buf[]; +} led_strip_rmt_obj; + +static esp_err_t led_strip_rmt_set_pixel(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue) +{ + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + ESP_RETURN_ON_FALSE(index < rmt_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, "index out of maximum number of LEDs"); + uint32_t start = index * rmt_strip->bytes_per_pixel; + // In thr order of GRB, as LED strip like WS2812 sends out pixels in this order + rmt_strip->pixel_buf[start + 0] = green & 0xFF; + rmt_strip->pixel_buf[start + 1] = red & 0xFF; + rmt_strip->pixel_buf[start + 2] = blue & 0xFF; + if (rmt_strip->bytes_per_pixel > 3) { + rmt_strip->pixel_buf[start + 3] = 0; + } + return ESP_OK; +} + +static esp_err_t led_strip_rmt_set_pixel_rgbw(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white) +{ + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + ESP_RETURN_ON_FALSE(index < rmt_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, "index out of maximum number of LEDs"); + ESP_RETURN_ON_FALSE(rmt_strip->bytes_per_pixel == 4, ESP_ERR_INVALID_ARG, TAG, "wrong LED pixel format, expected 4 bytes per pixel"); + uint8_t *buf_start = rmt_strip->pixel_buf + index * 4; + // SK6812 component order is GRBW + *buf_start = green & 0xFF; + *++buf_start = red & 0xFF; + *++buf_start = blue & 0xFF; + *++buf_start = white & 0xFF; + return ESP_OK; +} + +static esp_err_t led_strip_rmt_refresh(led_strip_t *strip) +{ + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + rmt_transmit_config_t tx_conf = { + .loop_count = 0, + }; + + ESP_RETURN_ON_ERROR(rmt_enable(rmt_strip->rmt_chan), TAG, "enable RMT channel failed"); + ESP_RETURN_ON_ERROR(rmt_transmit(rmt_strip->rmt_chan, rmt_strip->strip_encoder, rmt_strip->pixel_buf, + rmt_strip->strip_len * rmt_strip->bytes_per_pixel, &tx_conf), TAG, "transmit pixels by RMT failed"); + ESP_RETURN_ON_ERROR(rmt_tx_wait_all_done(rmt_strip->rmt_chan, -1), TAG, "flush RMT channel failed"); + ESP_RETURN_ON_ERROR(rmt_disable(rmt_strip->rmt_chan), TAG, "disable RMT channel failed"); + return ESP_OK; +} + +static esp_err_t led_strip_rmt_clear(led_strip_t *strip) +{ + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + // Write zero to turn off all leds + memset(rmt_strip->pixel_buf, 0, rmt_strip->strip_len * rmt_strip->bytes_per_pixel); + return led_strip_rmt_refresh(strip); +} + +static esp_err_t led_strip_rmt_del(led_strip_t *strip) +{ + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + ESP_RETURN_ON_ERROR(rmt_del_channel(rmt_strip->rmt_chan), TAG, "delete RMT channel failed"); + ESP_RETURN_ON_ERROR(rmt_del_encoder(rmt_strip->strip_encoder), TAG, "delete strip encoder failed"); + free(rmt_strip); + return ESP_OK; +} + +esp_err_t led_strip_new_rmt_device(const led_strip_config_t *led_config, const led_strip_rmt_config_t *rmt_config, led_strip_handle_t *ret_strip) +{ + led_strip_rmt_obj *rmt_strip = NULL; + esp_err_t ret = ESP_OK; + ESP_GOTO_ON_FALSE(led_config && rmt_config && ret_strip, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); + ESP_GOTO_ON_FALSE(led_config->led_pixel_format < LED_PIXEL_FORMAT_INVALID, ESP_ERR_INVALID_ARG, err, TAG, "invalid led_pixel_format"); + uint8_t bytes_per_pixel = 3; + if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRBW) { + bytes_per_pixel = 4; + } else if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRB) { + bytes_per_pixel = 3; + } else { + assert(false); + } + rmt_strip = calloc(1, sizeof(led_strip_rmt_obj) + led_config->max_leds * bytes_per_pixel); + ESP_GOTO_ON_FALSE(rmt_strip, ESP_ERR_NO_MEM, err, TAG, "no mem for rmt strip"); + uint32_t resolution = rmt_config->resolution_hz ? rmt_config->resolution_hz : LED_STRIP_RMT_DEFAULT_RESOLUTION; + + // for backward compatibility, if the user does not set the clk_src, use the default value + rmt_clock_source_t clk_src = RMT_CLK_SRC_DEFAULT; + if (rmt_config->clk_src) { + clk_src = rmt_config->clk_src; + } + size_t mem_block_symbols = LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS; + // override the default value if the user sets it + if (rmt_config->mem_block_symbols) { + mem_block_symbols = rmt_config->mem_block_symbols; + } + rmt_tx_channel_config_t rmt_chan_config = { + .clk_src = clk_src, + .gpio_num = led_config->strip_gpio_num, + .mem_block_symbols = mem_block_symbols, + .resolution_hz = resolution, + .trans_queue_depth = LED_STRIP_RMT_DEFAULT_TRANS_QUEUE_SIZE, + .flags.with_dma = rmt_config->flags.with_dma, + .flags.invert_out = led_config->flags.invert_out, + }; + ESP_GOTO_ON_ERROR(rmt_new_tx_channel(&rmt_chan_config, &rmt_strip->rmt_chan), err, TAG, "create RMT TX channel failed"); + + led_strip_encoder_config_t strip_encoder_conf = { + .resolution = resolution, + .led_model = led_config->led_model + }; + ESP_GOTO_ON_ERROR(rmt_new_led_strip_encoder(&strip_encoder_conf, &rmt_strip->strip_encoder), err, TAG, "create LED strip encoder failed"); + + + rmt_strip->bytes_per_pixel = bytes_per_pixel; + rmt_strip->strip_len = led_config->max_leds; + rmt_strip->base.set_pixel = led_strip_rmt_set_pixel; + rmt_strip->base.set_pixel_rgbw = led_strip_rmt_set_pixel_rgbw; + rmt_strip->base.refresh = led_strip_rmt_refresh; + rmt_strip->base.clear = led_strip_rmt_clear; + rmt_strip->base.del = led_strip_rmt_del; + + *ret_strip = &rmt_strip->base; + return ESP_OK; +err: + if (rmt_strip) { + if (rmt_strip->rmt_chan) { + rmt_del_channel(rmt_strip->rmt_chan); + } + if (rmt_strip->strip_encoder) { + rmt_del_encoder(rmt_strip->strip_encoder); + } + free(rmt_strip); + } + return ret; +} diff --git a/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_dev_idf4.c b/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_dev_idf4.c new file mode 100644 index 000000000..a1067cd7c --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_dev_idf4.c @@ -0,0 +1,194 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include "esp_log.h" +#include "esp_check.h" +#include "driver/rmt.h" +#include "led_strip.h" +#include "led_strip_interface.h" + +static const char *TAG = "led_strip_rmt"; + +#define WS2812_T0H_NS (300) +#define WS2812_T0L_NS (900) +#define WS2812_T1H_NS (900) +#define WS2812_T1L_NS (300) + +#define SK6812_T0H_NS (300) +#define SK6812_T0L_NS (900) +#define SK6812_T1H_NS (600) +#define SK6812_T1L_NS (600) + +#define LED_STRIP_RESET_MS (10) + +// the memory size of each RMT channel, in words (4 bytes) +#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 +#define LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS 64 +#else +#define LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS 48 +#endif + +static uint32_t led_t0h_ticks = 0; +static uint32_t led_t1h_ticks = 0; +static uint32_t led_t0l_ticks = 0; +static uint32_t led_t1l_ticks = 0; + +typedef struct { + led_strip_t base; + rmt_channel_t rmt_channel; + uint32_t strip_len; + uint8_t bytes_per_pixel; + uint8_t buffer[0]; +} led_strip_rmt_obj; + +static void IRAM_ATTR ws2812_rmt_adapter(const void *src, rmt_item32_t *dest, size_t src_size, + size_t wanted_num, size_t *translated_size, size_t *item_num) +{ + if (src == NULL || dest == NULL) { + *translated_size = 0; + *item_num = 0; + return; + } + const rmt_item32_t bit0 = {{{ led_t0h_ticks, 1, led_t0l_ticks, 0 }}}; //Logical 0 + const rmt_item32_t bit1 = {{{ led_t1h_ticks, 1, led_t1l_ticks, 0 }}}; //Logical 1 + size_t size = 0; + size_t num = 0; + uint8_t *psrc = (uint8_t *)src; + rmt_item32_t *pdest = dest; + while (size < src_size && num < wanted_num) { + for (int i = 0; i < 8; i++) { + // MSB first + if (*psrc & (1 << (7 - i))) { + pdest->val = bit1.val; + } else { + pdest->val = bit0.val; + } + num++; + pdest++; + } + size++; + psrc++; + } + *translated_size = size; + *item_num = num; +} + +static esp_err_t led_strip_rmt_set_pixel(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue) +{ + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + ESP_RETURN_ON_FALSE(index < rmt_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, "index out of the maximum number of leds"); + uint32_t start = index * rmt_strip->bytes_per_pixel; + // In thr order of GRB + rmt_strip->buffer[start + 0] = green & 0xFF; + rmt_strip->buffer[start + 1] = red & 0xFF; + rmt_strip->buffer[start + 2] = blue & 0xFF; + if (rmt_strip->bytes_per_pixel > 3) { + rmt_strip->buffer[start + 3] = 0; + } + return ESP_OK; +} + +static esp_err_t led_strip_rmt_refresh(led_strip_t *strip) +{ + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + ESP_RETURN_ON_ERROR(rmt_write_sample(rmt_strip->rmt_channel, rmt_strip->buffer, rmt_strip->strip_len * rmt_strip->bytes_per_pixel, true), TAG, + "transmit RMT samples failed"); + vTaskDelay(pdMS_TO_TICKS(LED_STRIP_RESET_MS)); + return ESP_OK; +} + +static esp_err_t led_strip_rmt_clear(led_strip_t *strip) +{ + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + // Write zero to turn off all LEDs + memset(rmt_strip->buffer, 0, rmt_strip->strip_len * rmt_strip->bytes_per_pixel); + return led_strip_rmt_refresh(strip); +} + +static esp_err_t led_strip_rmt_del(led_strip_t *strip) +{ + led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base); + ESP_RETURN_ON_ERROR(rmt_driver_uninstall(rmt_strip->rmt_channel), TAG, "uninstall RMT driver failed"); + free(rmt_strip); + return ESP_OK; +} + +esp_err_t led_strip_new_rmt_device(const led_strip_config_t *led_config, const led_strip_rmt_config_t *dev_config, led_strip_handle_t *ret_strip) +{ + led_strip_rmt_obj *rmt_strip = NULL; + esp_err_t ret = ESP_OK; + ESP_RETURN_ON_FALSE(led_config && dev_config && ret_strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + ESP_RETURN_ON_FALSE(led_config->led_pixel_format < LED_PIXEL_FORMAT_INVALID, ESP_ERR_INVALID_ARG, TAG, "invalid led_pixel_format"); + ESP_RETURN_ON_FALSE(dev_config->flags.with_dma == 0, ESP_ERR_NOT_SUPPORTED, TAG, "DMA is not supported"); + + uint8_t bytes_per_pixel = 3; + if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRBW) { + bytes_per_pixel = 4; + } else if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRB) { + bytes_per_pixel = 3; + } else { + assert(false); + } + + // allocate memory for led_strip object + rmt_strip = calloc(1, sizeof(led_strip_rmt_obj) + led_config->max_leds * bytes_per_pixel); + ESP_RETURN_ON_FALSE(rmt_strip, ESP_ERR_NO_MEM, TAG, "request memory for les_strip failed"); + + // install RMT channel driver + rmt_config_t config = RMT_DEFAULT_CONFIG_TX(led_config->strip_gpio_num, dev_config->rmt_channel); + // set the minimal clock division because the LED strip needs a high clock resolution + config.clk_div = 2; + + uint8_t mem_block_num = 2; + // override the default value if the user specify the mem block size + if (dev_config->mem_block_symbols) { + mem_block_num = (dev_config->mem_block_symbols + LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS / 2) / LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS; + } + config.mem_block_num = mem_block_num; + + ESP_GOTO_ON_ERROR(rmt_config(&config), err, TAG, "RMT config failed"); + ESP_GOTO_ON_ERROR(rmt_driver_install(config.channel, 0, 0), err, TAG, "RMT install failed"); + + uint32_t counter_clk_hz = 0; + rmt_get_counter_clock((rmt_channel_t)dev_config->rmt_channel, &counter_clk_hz); + // ns -> ticks + float ratio = (float)counter_clk_hz / 1e9; + if (led_config->led_model == LED_MODEL_WS2812) { + led_t0h_ticks = (uint32_t)(ratio * WS2812_T0H_NS); + led_t0l_ticks = (uint32_t)(ratio * WS2812_T0L_NS); + led_t1h_ticks = (uint32_t)(ratio * WS2812_T1H_NS); + led_t1l_ticks = (uint32_t)(ratio * WS2812_T1L_NS); + } else if (led_config->led_model == LED_MODEL_SK6812) { + led_t0h_ticks = (uint32_t)(ratio * SK6812_T0H_NS); + led_t0l_ticks = (uint32_t)(ratio * SK6812_T0L_NS); + led_t1h_ticks = (uint32_t)(ratio * SK6812_T1H_NS); + led_t1l_ticks = (uint32_t)(ratio * SK6812_T1L_NS); + } else { + assert(false); + } + + // adapter to translates the LES strip date frame into RMT symbols + rmt_translator_init((rmt_channel_t)dev_config->rmt_channel, ws2812_rmt_adapter); + + rmt_strip->bytes_per_pixel = bytes_per_pixel; + rmt_strip->rmt_channel = (rmt_channel_t)dev_config->rmt_channel; + rmt_strip->strip_len = led_config->max_leds; + rmt_strip->base.set_pixel = led_strip_rmt_set_pixel; + rmt_strip->base.refresh = led_strip_rmt_refresh; + rmt_strip->base.clear = led_strip_rmt_clear; + rmt_strip->base.del = led_strip_rmt_del; + + *ret_strip = &rmt_strip->base; + return ESP_OK; + +err: + if (rmt_strip) { + free(rmt_strip); + } + return ret; +} diff --git a/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_encoder.c b/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_encoder.c new file mode 100644 index 000000000..d352ac07f --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_encoder.c @@ -0,0 +1,146 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_check.h" +#include "led_strip_rmt_encoder.h" + +static const char *TAG = "led_rmt_encoder"; + +typedef struct { + rmt_encoder_t base; + rmt_encoder_t *bytes_encoder; + rmt_encoder_t *copy_encoder; + int state; + rmt_symbol_word_t reset_code; +} rmt_led_strip_encoder_t; + +static size_t rmt_encode_led_strip(rmt_encoder_t *encoder, rmt_channel_handle_t channel, const void *primary_data, size_t data_size, rmt_encode_state_t *ret_state) +{ + rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); + rmt_encoder_handle_t bytes_encoder = led_encoder->bytes_encoder; + rmt_encoder_handle_t copy_encoder = led_encoder->copy_encoder; + rmt_encode_state_t session_state = 0; + rmt_encode_state_t state = 0; + size_t encoded_symbols = 0; + switch (led_encoder->state) { + case 0: // send RGB data + encoded_symbols += bytes_encoder->encode(bytes_encoder, channel, primary_data, data_size, &session_state); + if (session_state & RMT_ENCODING_COMPLETE) { + led_encoder->state = 1; // switch to next state when current encoding session finished + } + if (session_state & RMT_ENCODING_MEM_FULL) { + state |= RMT_ENCODING_MEM_FULL; + goto out; // yield if there's no free space for encoding artifacts + } + // fall-through + case 1: // send reset code + encoded_symbols += copy_encoder->encode(copy_encoder, channel, &led_encoder->reset_code, + sizeof(led_encoder->reset_code), &session_state); + if (session_state & RMT_ENCODING_COMPLETE) { + led_encoder->state = 0; // back to the initial encoding session + state |= RMT_ENCODING_COMPLETE; + } + if (session_state & RMT_ENCODING_MEM_FULL) { + state |= RMT_ENCODING_MEM_FULL; + goto out; // yield if there's no free space for encoding artifacts + } + } +out: + *ret_state = state; + return encoded_symbols; +} + +static esp_err_t rmt_del_led_strip_encoder(rmt_encoder_t *encoder) +{ + rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); + rmt_del_encoder(led_encoder->bytes_encoder); + rmt_del_encoder(led_encoder->copy_encoder); + free(led_encoder); + return ESP_OK; +} + +static esp_err_t rmt_led_strip_encoder_reset(rmt_encoder_t *encoder) +{ + rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); + rmt_encoder_reset(led_encoder->bytes_encoder); + rmt_encoder_reset(led_encoder->copy_encoder); + led_encoder->state = 0; + return ESP_OK; +} + +esp_err_t rmt_new_led_strip_encoder(const led_strip_encoder_config_t *config, rmt_encoder_handle_t *ret_encoder) +{ + esp_err_t ret = ESP_OK; + rmt_led_strip_encoder_t *led_encoder = NULL; + ESP_GOTO_ON_FALSE(config && ret_encoder, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); + ESP_GOTO_ON_FALSE(config->led_model < LED_MODEL_INVALID, ESP_ERR_INVALID_ARG, err, TAG, "invalid led model"); + led_encoder = calloc(1, sizeof(rmt_led_strip_encoder_t)); + ESP_GOTO_ON_FALSE(led_encoder, ESP_ERR_NO_MEM, err, TAG, "no mem for led strip encoder"); + led_encoder->base.encode = rmt_encode_led_strip; + led_encoder->base.del = rmt_del_led_strip_encoder; + led_encoder->base.reset = rmt_led_strip_encoder_reset; + rmt_bytes_encoder_config_t bytes_encoder_config; + if (config->led_model == LED_MODEL_SK6812) { + bytes_encoder_config = (rmt_bytes_encoder_config_t) { + .bit0 = { + .level0 = 1, + .duration0 = 0.3 * config->resolution / 1000000, // T0H=0.3us + .level1 = 0, + .duration1 = 0.9 * config->resolution / 1000000, // T0L=0.9us + }, + .bit1 = { + .level0 = 1, + .duration0 = 0.6 * config->resolution / 1000000, // T1H=0.6us + .level1 = 0, + .duration1 = 0.6 * config->resolution / 1000000, // T1L=0.6us + }, + .flags.msb_first = 1 // SK6812 transfer bit order: G7...G0R7...R0B7...B0(W7...W0) + }; + } else if (config->led_model == LED_MODEL_WS2812) { + // different led strip might have its own timing requirements, following parameter is for WS2812 + bytes_encoder_config = (rmt_bytes_encoder_config_t) { + .bit0 = { + .level0 = 1, + .duration0 = 0.3 * config->resolution / 1000000, // T0H=0.3us + .level1 = 0, + .duration1 = 0.9 * config->resolution / 1000000, // T0L=0.9us + }, + .bit1 = { + .level0 = 1, + .duration0 = 0.9 * config->resolution / 1000000, // T1H=0.9us + .level1 = 0, + .duration1 = 0.3 * config->resolution / 1000000, // T1L=0.3us + }, + .flags.msb_first = 1 // WS2812 transfer bit order: G7...G0R7...R0B7...B0 + }; + } else { + assert(false); + } + ESP_GOTO_ON_ERROR(rmt_new_bytes_encoder(&bytes_encoder_config, &led_encoder->bytes_encoder), err, TAG, "create bytes encoder failed"); + rmt_copy_encoder_config_t copy_encoder_config = {}; + ESP_GOTO_ON_ERROR(rmt_new_copy_encoder(©_encoder_config, &led_encoder->copy_encoder), err, TAG, "create copy encoder failed"); + + uint32_t reset_ticks = config->resolution / 1000000 * 50 / 2; // reset code duration defaults to 50us + led_encoder->reset_code = (rmt_symbol_word_t) { + .level0 = 0, + .duration0 = reset_ticks, + .level1 = 0, + .duration1 = reset_ticks, + }; + *ret_encoder = &led_encoder->base; + return ESP_OK; +err: + if (led_encoder) { + if (led_encoder->bytes_encoder) { + rmt_del_encoder(led_encoder->bytes_encoder); + } + if (led_encoder->copy_encoder) { + rmt_del_encoder(led_encoder->copy_encoder); + } + free(led_encoder); + } + return ret; +} diff --git a/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_encoder.h b/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_encoder.h new file mode 100644 index 000000000..ba71e60ab --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_encoder.h @@ -0,0 +1,38 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include "driver/rmt_encoder.h" +#include "led_strip_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Type of led strip encoder configuration + */ +typedef struct { + uint32_t resolution; /*!< Encoder resolution, in Hz */ + led_model_t led_model; /*!< LED model */ +} led_strip_encoder_config_t; + +/** + * @brief Create RMT encoder for encoding LED strip pixels into RMT symbols + * + * @param[in] config Encoder configuration + * @param[out] ret_encoder Returned encoder handle + * @return + * - ESP_ERR_INVALID_ARG for any invalid arguments + * - ESP_ERR_NO_MEM out of memory when creating led strip encoder + * - ESP_OK if creating encoder successfully + */ +esp_err_t rmt_new_led_strip_encoder(const led_strip_encoder_config_t *config, rmt_encoder_handle_t *ret_encoder); + +#ifdef __cplusplus +} +#endif diff --git a/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_ws2812.c b/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_ws2812.c deleted file mode 100644 index fd1746cad..000000000 --- a/hw/bsp/espressif/components/led_strip/src/led_strip_rmt_ws2812.c +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright 2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#include -#include -#include -#include "esp_log.h" -#include "esp_attr.h" -#include "led_strip.h" -#include "driver/rmt.h" - -static const char *TAG = "ws2812"; -#define STRIP_CHECK(a, str, goto_tag, ret_value, ...) \ - do \ - { \ - if (!(a)) \ - { \ - ESP_LOGE(TAG, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ - ret = ret_value; \ - goto goto_tag; \ - } \ - } while (0) - -#define WS2812_T0H_NS (350) -#define WS2812_T0L_NS (1000) -#define WS2812_T1H_NS (1000) -#define WS2812_T1L_NS (350) -#define WS2812_RESET_US (280) - -static uint32_t ws2812_t0h_ticks = 0; -static uint32_t ws2812_t1h_ticks = 0; -static uint32_t ws2812_t0l_ticks = 0; -static uint32_t ws2812_t1l_ticks = 0; - -typedef struct { - led_strip_t parent; - rmt_channel_t rmt_channel; - uint32_t strip_len; - uint8_t buffer[0]; -} ws2812_t; - -/** - * @brief Convert RGB data to RMT format. - * - * @note For WS2812, R,G,B each contains 256 different choices (i.e. uint8_t) - * - * @param[in] src: source data, to converted to RMT format - * @param[in] dest: place where to store the convert result - * @param[in] src_size: size of source data - * @param[in] wanted_num: number of RMT items that want to get - * @param[out] translated_size: number of source data that got converted - * @param[out] item_num: number of RMT items which are converted from source data - */ -static void IRAM_ATTR ws2812_rmt_adapter(const void *src, rmt_item32_t *dest, size_t src_size, - size_t wanted_num, size_t *translated_size, size_t *item_num) -{ - if (src == NULL || dest == NULL) { - *translated_size = 0; - *item_num = 0; - return; - } - const rmt_item32_t bit0 = {{{ ws2812_t0h_ticks, 1, ws2812_t0l_ticks, 0 }}}; //Logical 0 - const rmt_item32_t bit1 = {{{ ws2812_t1h_ticks, 1, ws2812_t1l_ticks, 0 }}}; //Logical 1 - size_t size = 0; - size_t num = 0; - uint8_t *psrc = (uint8_t *)src; - rmt_item32_t *pdest = dest; - while (size < src_size && num < wanted_num) { - for (int i = 0; i < 8; i++) { - // MSB first - if (*psrc & (1 << (7 - i))) { - pdest->val = bit1.val; - } else { - pdest->val = bit0.val; - } - num++; - pdest++; - } - size++; - psrc++; - } - *translated_size = size; - *item_num = num; -} - -static esp_err_t ws2812_set_pixel(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue) -{ - esp_err_t ret = ESP_OK; - ws2812_t *ws2812 = __containerof(strip, ws2812_t, parent); - STRIP_CHECK(index < ws2812->strip_len, "index out of the maximum number of leds", err, ESP_ERR_INVALID_ARG); - uint32_t start = index * 3; - // In thr order of GRB - ws2812->buffer[start + 0] = green & 0xFF; - ws2812->buffer[start + 1] = red & 0xFF; - ws2812->buffer[start + 2] = blue & 0xFF; - return ESP_OK; -err: - return ret; -} - -static esp_err_t ws2812_refresh(led_strip_t *strip, uint32_t timeout_ms) -{ - esp_err_t ret = ESP_OK; - ws2812_t *ws2812 = __containerof(strip, ws2812_t, parent); - STRIP_CHECK(rmt_write_sample(ws2812->rmt_channel, ws2812->buffer, ws2812->strip_len * 3, true) == ESP_OK, - "transmit RMT samples failed", err, ESP_FAIL); - return rmt_wait_tx_done(ws2812->rmt_channel, pdMS_TO_TICKS(timeout_ms)); -err: - return ret; -} - -static esp_err_t ws2812_clear(led_strip_t *strip, uint32_t timeout_ms) -{ - ws2812_t *ws2812 = __containerof(strip, ws2812_t, parent); - // Write zero to turn off all leds - memset(ws2812->buffer, 0, ws2812->strip_len * 3); - return ws2812_refresh(strip, timeout_ms); -} - -static esp_err_t ws2812_del(led_strip_t *strip) -{ - ws2812_t *ws2812 = __containerof(strip, ws2812_t, parent); - free(ws2812); - return ESP_OK; -} - -led_strip_t *led_strip_new_rmt_ws2812(const led_strip_config_t *config) -{ - led_strip_t *ret = NULL; - STRIP_CHECK(config, "configuration can't be null", err, NULL); - - // 24 bits per led - uint32_t ws2812_size = sizeof(ws2812_t) + config->max_leds * 3; - ws2812_t *ws2812 = calloc(1, ws2812_size); - STRIP_CHECK(ws2812, "request memory for ws2812 failed", err, NULL); - - uint32_t counter_clk_hz = 0; - STRIP_CHECK(rmt_get_counter_clock((rmt_channel_t)config->dev, &counter_clk_hz) == ESP_OK, - "get rmt counter clock failed", err, NULL); - // ns -> ticks - float ratio = (float)counter_clk_hz / 1e9; - ws2812_t0h_ticks = (uint32_t)(ratio * WS2812_T0H_NS); - ws2812_t0l_ticks = (uint32_t)(ratio * WS2812_T0L_NS); - ws2812_t1h_ticks = (uint32_t)(ratio * WS2812_T1H_NS); - ws2812_t1l_ticks = (uint32_t)(ratio * WS2812_T1L_NS); - - // set ws2812 to rmt adapter - rmt_translator_init((rmt_channel_t)config->dev, ws2812_rmt_adapter); - - ws2812->rmt_channel = (rmt_channel_t)config->dev; - ws2812->strip_len = config->max_leds; - - ws2812->parent.set_pixel = ws2812_set_pixel; - ws2812->parent.refresh = ws2812_refresh; - ws2812->parent.clear = ws2812_clear; - ws2812->parent.del = ws2812_del; - - return &ws2812->parent; -err: - return ret; -} diff --git a/hw/bsp/espressif/components/led_strip/src/led_strip_spi_dev.c b/hw/bsp/espressif/components/led_strip/src/led_strip_spi_dev.c new file mode 100644 index 000000000..12ea8fbf3 --- /dev/null +++ b/hw/bsp/espressif/components/led_strip/src/led_strip_spi_dev.c @@ -0,0 +1,209 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include "esp_log.h" +#include "esp_check.h" +#include "esp_rom_gpio.h" +#include "soc/spi_periph.h" +#include "led_strip.h" +#include "led_strip_interface.h" +#include "hal/spi_hal.h" + +#define LED_STRIP_SPI_DEFAULT_RESOLUTION (2.5 * 1000 * 1000) // 2.5MHz resolution +#define LED_STRIP_SPI_DEFAULT_TRANS_QUEUE_SIZE 4 + +#define SPI_BYTES_PER_COLOR_BYTE 3 +#define SPI_BITS_PER_COLOR_BYTE (SPI_BYTES_PER_COLOR_BYTE * 8) + +static const char *TAG = "led_strip_spi"; + +typedef struct { + led_strip_t base; + spi_host_device_t spi_host; + spi_device_handle_t spi_device; + uint32_t strip_len; + uint8_t bytes_per_pixel; + uint8_t pixel_buf[]; +} led_strip_spi_obj; + +// please make sure to zero-initialize the buf before calling this function +static void __led_strip_spi_bit(uint8_t data, uint8_t *buf) +{ + // Each color of 1 bit is represented by 3 bits of SPI, low_level:100 ,high_level:110 + // So a color byte occupies 3 bytes of SPI. + *(buf + 2) |= data & BIT(0) ? BIT(2) | BIT(1) : BIT(2); + *(buf + 2) |= data & BIT(1) ? BIT(5) | BIT(4) : BIT(5); + *(buf + 2) |= data & BIT(2) ? BIT(7) : 0x00; + *(buf + 1) |= BIT(0); + *(buf + 1) |= data & BIT(3) ? BIT(3) | BIT(2) : BIT(3); + *(buf + 1) |= data & BIT(4) ? BIT(6) | BIT(5) : BIT(6); + *(buf + 0) |= data & BIT(5) ? BIT(1) | BIT(0) : BIT(1); + *(buf + 0) |= data & BIT(6) ? BIT(4) | BIT(3) : BIT(4); + *(buf + 0) |= data & BIT(7) ? BIT(7) | BIT(6) : BIT(7); +} + +static esp_err_t led_strip_spi_set_pixel(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue) +{ + led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); + ESP_RETURN_ON_FALSE(index < spi_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, "index out of maximum number of LEDs"); + // LED_PIXEL_FORMAT_GRB takes 72bits(9bytes) + uint32_t start = index * spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE; + memset(spi_strip->pixel_buf + start, 0, spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE); + __led_strip_spi_bit(green, &spi_strip->pixel_buf[start]); + __led_strip_spi_bit(red, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE]); + __led_strip_spi_bit(blue, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 2]); + if (spi_strip->bytes_per_pixel > 3) { + __led_strip_spi_bit(0, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 3]); + } + return ESP_OK; +} + +static esp_err_t led_strip_spi_set_pixel_rgbw(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white) +{ + led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); + ESP_RETURN_ON_FALSE(index < spi_strip->strip_len, ESP_ERR_INVALID_ARG, TAG, "index out of maximum number of LEDs"); + ESP_RETURN_ON_FALSE(spi_strip->bytes_per_pixel == 4, ESP_ERR_INVALID_ARG, TAG, "wrong LED pixel format, expected 4 bytes per pixel"); + // LED_PIXEL_FORMAT_GRBW takes 96bits(12bytes) + uint32_t start = index * spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE; + // SK6812 component order is GRBW + memset(spi_strip->pixel_buf + start, 0, spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE); + __led_strip_spi_bit(green, &spi_strip->pixel_buf[start]); + __led_strip_spi_bit(red, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE]); + __led_strip_spi_bit(blue, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 2]); + __led_strip_spi_bit(white, &spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 3]); + + return ESP_OK; +} + +static esp_err_t led_strip_spi_refresh(led_strip_t *strip) +{ + led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); + spi_transaction_t tx_conf; + memset(&tx_conf, 0, sizeof(tx_conf)); + + tx_conf.length = spi_strip->strip_len * spi_strip->bytes_per_pixel * SPI_BITS_PER_COLOR_BYTE; + tx_conf.tx_buffer = spi_strip->pixel_buf; + tx_conf.rx_buffer = NULL; + ESP_RETURN_ON_ERROR(spi_device_transmit(spi_strip->spi_device, &tx_conf), TAG, "transmit pixels by SPI failed"); + + return ESP_OK; +} + +static esp_err_t led_strip_spi_clear(led_strip_t *strip) +{ + led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); + //Write zero to turn off all leds + memset(spi_strip->pixel_buf, 0, spi_strip->strip_len * spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE); + uint8_t *buf = spi_strip->pixel_buf; + for (int index = 0; index < spi_strip->strip_len * spi_strip->bytes_per_pixel; index++) { + __led_strip_spi_bit(0, buf); + buf += SPI_BYTES_PER_COLOR_BYTE; + } + + return led_strip_spi_refresh(strip); +} + +static esp_err_t led_strip_spi_del(led_strip_t *strip) +{ + led_strip_spi_obj *spi_strip = __containerof(strip, led_strip_spi_obj, base); + + ESP_RETURN_ON_ERROR(spi_bus_remove_device(spi_strip->spi_device), TAG, "delete spi device failed"); + ESP_RETURN_ON_ERROR(spi_bus_free(spi_strip->spi_host), TAG, "free spi bus failed"); + + free(spi_strip); + return ESP_OK; +} + +esp_err_t led_strip_new_spi_device(const led_strip_config_t *led_config, const led_strip_spi_config_t *spi_config, led_strip_handle_t *ret_strip) +{ + led_strip_spi_obj *spi_strip = NULL; + esp_err_t ret = ESP_OK; + ESP_GOTO_ON_FALSE(led_config && spi_config && ret_strip, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); + ESP_GOTO_ON_FALSE(led_config->led_pixel_format < LED_PIXEL_FORMAT_INVALID, ESP_ERR_INVALID_ARG, err, TAG, "invalid led_pixel_format"); + uint8_t bytes_per_pixel = 3; + if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRBW) { + bytes_per_pixel = 4; + } else if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRB) { + bytes_per_pixel = 3; + } else { + assert(false); + } + uint32_t mem_caps = MALLOC_CAP_DEFAULT; + if (spi_config->flags.with_dma) { + // DMA buffer must be placed in internal SRAM + mem_caps |= MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA; + } + spi_strip = heap_caps_calloc(1, sizeof(led_strip_spi_obj) + led_config->max_leds * bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE, mem_caps); + + ESP_GOTO_ON_FALSE(spi_strip, ESP_ERR_NO_MEM, err, TAG, "no mem for spi strip"); + + spi_strip->spi_host = spi_config->spi_bus; + // for backward compatibility, if the user does not set the clk_src, use the default value + spi_clock_source_t clk_src = SPI_CLK_SRC_DEFAULT; + if (spi_config->clk_src) { + clk_src = spi_config->clk_src; + } + + spi_bus_config_t spi_bus_cfg = { + .mosi_io_num = led_config->strip_gpio_num, + //Only use MOSI to generate the signal, set -1 when other pins are not used. + .miso_io_num = -1, + .sclk_io_num = -1, + .quadwp_io_num = -1, + .quadhd_io_num = -1, + .max_transfer_sz = led_config->max_leds * bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE, + }; + ESP_GOTO_ON_ERROR(spi_bus_initialize(spi_strip->spi_host, &spi_bus_cfg, spi_config->flags.with_dma ? SPI_DMA_CH_AUTO : SPI_DMA_DISABLED), err, TAG, "create SPI bus failed"); + + if (led_config->flags.invert_out == true) { + esp_rom_gpio_connect_out_signal(led_config->strip_gpio_num, spi_periph_signal[spi_strip->spi_host].spid_out, true, false); + } + + spi_device_interface_config_t spi_dev_cfg = { + .clock_source = clk_src, + .command_bits = 0, + .address_bits = 0, + .dummy_bits = 0, + .clock_speed_hz = LED_STRIP_SPI_DEFAULT_RESOLUTION, + .mode = 0, + //set -1 when CS is not used + .spics_io_num = -1, + .queue_size = LED_STRIP_SPI_DEFAULT_TRANS_QUEUE_SIZE, + }; + + ESP_GOTO_ON_ERROR(spi_bus_add_device(spi_strip->spi_host, &spi_dev_cfg, &spi_strip->spi_device), err, TAG, "Failed to add spi device"); + + int clock_resolution_khz = 0; + spi_device_get_actual_freq(spi_strip->spi_device, &clock_resolution_khz); + // TODO: ideally we should decide the SPI_BYTES_PER_COLOR_BYTE by the real clock resolution + // But now, let's fixed the resolution, the downside is, we don't support a clock source whose frequency is not multiple of LED_STRIP_SPI_DEFAULT_RESOLUTION + ESP_GOTO_ON_FALSE(clock_resolution_khz == LED_STRIP_SPI_DEFAULT_RESOLUTION / 1000, ESP_ERR_NOT_SUPPORTED, err, + TAG, "unsupported clock resolution:%dKHz", clock_resolution_khz); + + spi_strip->bytes_per_pixel = bytes_per_pixel; + spi_strip->strip_len = led_config->max_leds; + spi_strip->base.set_pixel = led_strip_spi_set_pixel; + spi_strip->base.set_pixel_rgbw = led_strip_spi_set_pixel_rgbw; + spi_strip->base.refresh = led_strip_spi_refresh; + spi_strip->base.clear = led_strip_spi_clear; + spi_strip->base.del = led_strip_spi_del; + + *ret_strip = &spi_strip->base; + return ESP_OK; +err: + if (spi_strip) { + if (spi_strip->spi_device) { + spi_bus_remove_device(spi_strip->spi_device); + } + if (spi_strip->spi_host) { + spi_bus_free(spi_strip->spi_host); + } + free(spi_strip); + } + return ret; +} diff --git a/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt b/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt index bf8e45be2..8bdb3802e 100644 --- a/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt +++ b/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt @@ -5,51 +5,59 @@ set(includes_public) set(compile_options) set(tusb_src "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src") -if(target STREQUAL "esp32s3") - set(tusb_mcu "OPT_MCU_ESP32S3") -elseif(target STREQUAL "esp32s2") - set(tusb_mcu "OPT_MCU_ESP32S2") -else() - # CONFIG_TINYUSB dependency has been guaranteed by Kconfig logic, - # So it's not possible that cmake goes here - message(FATAL_ERROR "TinyUSB is not support on ${target}.") - return() -endif() - -list(APPEND compile_options - "-DCFG_TUSB_MCU=${tusb_mcu}" - "-DCFG_TUSB_OS=OPT_OS_FREERTOS" - #"-DCFG_TUSB_DEBUG=1" - ) - -idf_component_get_property(freertos_component_dir freertos COMPONENT_DIR) - -list(APPEND includes_public - "${tusb_src}" - # The FreeRTOS API include convention in tinyusb is different from esp-idf - #"${freertos_component_dir}/include/freertos" - ) +string(TOUPPER OPT_MCU_${target} tusb_mcu) +list(APPEND compile_definitions + CFG_TUSB_MCU=${tusb_mcu} + CFG_TUSB_OS=OPT_OS_FREERTOS + ) list(APPEND srcs - "${tusb_src}/tusb.c" - "${tusb_src}/common/tusb_fifo.c" - "${tusb_src}/device/usbd.c" - "${tusb_src}/device/usbd_control.c" - "${tusb_src}/class/cdc/cdc_device.c" - "${tusb_src}/class/dfu/dfu_rt_device.c" - "${tusb_src}/class/hid/hid_device.c" - "${tusb_src}/class/midi/midi_device.c" - "${tusb_src}/class/msc/msc_device.c" - "${tusb_src}/class/net/ecm_rndis_device.c" - "${tusb_src}/class/net/ncm_device.c" - "${tusb_src}/class/usbtmc/usbtmc_device.c" - "${tusb_src}/class/vendor/vendor_device.c" - "${tusb_src}/portable/synopsys/dwc2/dcd_dwc2.c" - ) + # common + ${tusb_src}/tusb.c + ${tusb_src}/common/tusb_fifo.c + # device + ${tusb_src}/device/usbd.c + ${tusb_src}/device/usbd_control.c + ${tusb_src}/class/audio/audio_device.c + ${tusb_src}/class/cdc/cdc_device.c + ${tusb_src}/class/dfu/dfu_device.c + ${tusb_src}/class/dfu/dfu_rt_device.c + ${tusb_src}/class/hid/hid_device.c + ${tusb_src}/class/midi/midi_device.c + ${tusb_src}/class/msc/msc_device.c + ${tusb_src}/class/net/ecm_rndis_device.c + ${tusb_src}/class/net/ncm_device.c + ${tusb_src}/class/usbtmc/usbtmc_device.c + ${tusb_src}/class/vendor/vendor_device.c + ${tusb_src}/class/video/video_device.c + ${tusb_src}/portable/synopsys/dwc2/dcd_dwc2.c + # host + ${tusb_src}/host/usbh.c + ${tusb_src}/host/hub.c + ${tusb_src}/class/cdc/cdc_host.c + ${tusb_src}/class/hid/hid_host.c + ${tusb_src}/class/msc/msc_host.c + ${tusb_src}/class/vendor/vendor_host.c + ) + +# use max3421 as host controller +if (MAX3421_HOST STREQUAL "1") + list(APPEND srcs ${tusb_src}/portable/analog/max3421/hcd_max3421.c) + list(APPEND compile_definitions CFG_TUH_MAX3421=1) +endif () + +if (DEFINED LOG) + list(APPEND compile_definitions CFG_TUSB_DEBUG=${LOG}) + if (LOG STREQUAL "4") + # no inline for debug level 4 + list(APPEND compile_definitions TU_ATTR_ALWAYS_INLINE=) + endif () +endif() idf_component_register(SRCS ${srcs} - INCLUDE_DIRS ${includes_public} - REQUIRES src - ) + INCLUDE_DIRS ${tusb_src} + REQUIRES src + ) -target_compile_options(${COMPONENT_LIB} PUBLIC ${compile_options}) +target_compile_definitions(${COMPONENT_LIB} PUBLIC ${compile_definitions}) +target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-error=format) diff --git a/hw/bsp/espressif/family.cmake b/hw/bsp/espressif/family.cmake index 92a9bcb04..eb97401c3 100644 --- a/hw/bsp/espressif/family.cmake +++ b/hw/bsp/espressif/family.cmake @@ -3,11 +3,7 @@ cmake_minimum_required(VERSION 3.5) # Apply board specific content i.e IDF_TARGET must be set before project.cmake is included include("${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake") -if(IDF_TARGET STREQUAL "esp32s2") - set(FAMILY_MCUS ESP32S2) -elseif(IDF_TARGET STREQUAL "esp32s3") - set(FAMILY_MCUS ESP32S3) -endif() +string(TOUPPER ${IDF_TARGET} FAMILY_MCUS) # Add example src and bsp directories set(EXTRA_COMPONENT_DIRS "src" "${CMAKE_CURRENT_LIST_DIR}/boards" "${CMAKE_CURRENT_LIST_DIR}/components") diff --git a/hw/bsp/f1c100s/board.h b/hw/bsp/f1c100s/board.h deleted file mode 100644 index 0ef9a1700..000000000 --- a/hw/bsp/f1c100s/board.h +++ /dev/null @@ -1 +0,0 @@ -// Nothing valuable here diff --git a/hw/bsp/f1c100s/board.mk b/hw/bsp/f1c100s/board.mk deleted file mode 100644 index 9062483b0..000000000 --- a/hw/bsp/f1c100s/board.mk +++ /dev/null @@ -1,52 +0,0 @@ -DEPS_SUBMODULES += hw/mcu/allwinner - -DEFINES += -D__ARM32_ARCH__=5 -D__ARM926EJS__ - -CFLAGS += \ - -ffreestanding \ - -std=gnu99 \ - -march=armv5te \ - -mtune=arm926ej-s \ - -mfloat-abi=soft \ - -marm \ - -mno-thumb-interwork \ - -Wno-unused-parameter \ - -Wno-float-equal \ - -DCFG_TUSB_MCU=OPT_MCU_F1C100S \ - -Wno-error=cast-align \ - -Wno-error=address-of-packed-member \ - $(DEFINES) - -LD_FILE = hw/mcu/allwinner/f1c100s/f1c100s.ld -LDFLAGS += -nostdlib -lgcc -MCU_DIR = hw/mcu/allwinner/f1c100s - -SRC_C += \ - src/portable/sunxi/dcd_sunxi_musb.c \ - $(MCU_DIR)/machine/sys-uart.c \ - $(MCU_DIR)/machine/exception.c \ - $(MCU_DIR)/machine/sys-clock.c \ - $(MCU_DIR)/machine/sys-copyself.c \ - $(MCU_DIR)/machine/sys-dram.c \ - $(MCU_DIR)/machine/sys-mmu.c \ - $(MCU_DIR)/machine/sys-spi-flash.c \ - $(MCU_DIR)/machine/f1c100s-intc.c \ - $(MCU_DIR)/lib/malloc.c \ - $(MCU_DIR)/lib/printf.c - -SRC_S += \ - $(MCU_DIR)/machine/start.S \ - $(MCU_DIR)/lib/memcpy.S \ - $(MCU_DIR)/lib/memset.S - -INC += \ - $(TOP)/$(MCU_DIR)/include \ - $(TOP)/$(BOARD_PATH) - -# flash target using xfel -flash: flash-xfel - -exec: $(BUILD)/$(PROJECT).bin - xfel ddr - xfel write 0x80000000 $< - xfel exec 0x80000000 diff --git a/hw/bsp/f1c100s/boards/f1c100s/board.cmake b/hw/bsp/f1c100s/boards/f1c100s/board.cmake new file mode 100644 index 000000000..98ed56c57 --- /dev/null +++ b/hw/bsp/f1c100s/boards/f1c100s/board.cmake @@ -0,0 +1,3 @@ +function(update_board TARGET) + # nothing to do +endfunction() diff --git a/hw/bsp/f1c100s/boards/f1c100s/board.h b/hw/bsp/f1c100s/boards/f1c100s/board.h new file mode 100644 index 000000000..3b56a3a57 --- /dev/null +++ b/hw/bsp/f1c100s/boards/f1c100s/board.h @@ -0,0 +1,6 @@ +#ifndef BOARD_H +#define BOARD_H + +// Nothing valuable here + +#endif diff --git a/hw/bsp/f1c100s/boards/f1c100s/board.mk b/hw/bsp/f1c100s/boards/f1c100s/board.mk new file mode 100644 index 000000000..be830bd8c --- /dev/null +++ b/hw/bsp/f1c100s/boards/f1c100s/board.mk @@ -0,0 +1 @@ +# nothing to do diff --git a/hw/bsp/f1c100s/f1c100s.c b/hw/bsp/f1c100s/family.c similarity index 78% rename from hw/bsp/f1c100s/f1c100s.c rename to hw/bsp/f1c100s/family.c index 272b756f2..6df4a0ed8 100644 --- a/hw/bsp/f1c100s/f1c100s.c +++ b/hw/bsp/f1c100s/family.c @@ -39,10 +39,9 @@ extern void sys_uart_putc(char c); static void timer_init(void); -void board_init(void) -{ +void board_init(void) { arch_local_irq_disable(); - do_init_mem_pool(); + do_init_mem_pool(); f1c100s_intc_init(); timer_init(); printf("Timer INIT done\n"); @@ -50,42 +49,38 @@ void board_init(void) } // No LED, no button -void board_led_write(bool state) -{ - +void board_led_write(bool state) { + (void) state; } -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { return 0; } -int board_uart_read(uint8_t* buf, int len) -{ +int board_uart_read(uint8_t* buf, int 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) { int txsize = len; while (txsize--) { - sys_uart_putc(*(uint8_t const*)buf); + sys_uart_putc(*(uint8_t const*) buf); buf++; } return len; } -#if CFG_TUSB_OS == OPT_OS_NONE +#if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; -uint32_t board_millis(void) -{ +uint32_t board_millis(void) { return system_ticks; } -static void timer_handler(void) -{ - volatile uint32_t *temp_addr = (uint32_t *)(0x01C20C00 + 0x04); +static void timer_handler(void) { + volatile uint32_t* temp_addr = (uint32_t*) (0x01C20C00 + 0x04); /* clear timer */ *temp_addr |= 0x01; @@ -95,36 +90,37 @@ static void timer_handler(void) static void timer_init(void) { uint32_t temp; - volatile uint32_t *temp_addr; + volatile uint32_t* temp_addr; /* reload value */ temp = 12000000 / 1000; - temp_addr = (uint32_t *)(0x01C20C00 + 0x14); + temp_addr = (uint32_t*) (0x01C20C00 + 0x14); *temp_addr = temp; /* continuous | /2 | 24Mhz | reload*/ temp = (0x00 << 7) | (0x01 << 4) | (0x01 << 2) | (0x00 << 1); - temp_addr = (uint32_t *)(0x01C20C00 + 0x10); + temp_addr = (uint32_t*) (0x01C20C00 + 0x10); *temp_addr &= 0xffffff00; *temp_addr |= temp; /* open timer irq */ temp = 0x01 << 0; - temp_addr = (uint32_t *)(0x01C20C00); + temp_addr = (uint32_t*) (0x01C20C00); *temp_addr |= temp; /* set init value */ - temp_addr = (uint32_t *)(0x01C20C00 + 0x18); + temp_addr = (uint32_t*) (0x01C20C00 + 0x18); *temp_addr = 0; /* begin run timer */ temp = 0x01 << 0; - temp_addr = (uint32_t *)(0x01C20C00 + 0x10); + temp_addr = (uint32_t*) (0x01C20C00 + 0x10); *temp_addr |= temp; f1c100s_intc_set_isr(F1C100S_IRQ_TIMER0, timer_handler); f1c100s_intc_enable_irq(F1C100S_IRQ_TIMER0); } + #else static void timer_init(void) { } #endif diff --git a/hw/bsp/f1c100s/family.cmake b/hw/bsp/f1c100s/family.cmake new file mode 100644 index 000000000..0903a0143 --- /dev/null +++ b/hw/bsp/f1c100s/family.cmake @@ -0,0 +1,114 @@ +include_guard() + +set(SDK_DIR ${TOP}/hw/mcu/allwinner/f1c100s) + +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR arm926ej-s CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS F1C100S 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 () + + # LD_FILE and STARTUP_FILE can be defined in board.cmake + if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${SDK_DIR}/f1c100s.ld) + endif () + set(LD_FILE_Clang ${LD_FILE_GNU}) + + if (NOT DEFINED STARTUP_FILE_GNU) + set(STARTUP_FILE_GNU ${SDK_DIR}/machine/start.S) + endif () + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${SDK_DIR}/lib/malloc.c + ${SDK_DIR}/lib/printf.c + ${SDK_DIR}/lib/memcpy.S + ${SDK_DIR}/lib/memset.S + ${SDK_DIR}/machine/sys-uart.c + ${SDK_DIR}/machine/exception.c + ${SDK_DIR}/machine/sys-clock.c + ${SDK_DIR}/machine/sys-copyself.c + ${SDK_DIR}/machine/sys-dram.c + ${SDK_DIR}/machine/sys-mmu.c + ${SDK_DIR}/machine/sys-spi-flash.c + ${SDK_DIR}/machine/f1c100s-intc.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + + target_compile_definitions(${BOARD_TARGET} PUBLIC + __ARM32_ARCH__=5 + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_DIR}/include + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -lgcc + --specs=nosys.specs --specs=nano.specs + "LINKER:--defsym=__bss_end__=__bss_end" + "LINKER:--defsym=__bss_start__=__bss_start" + "LINKER:--defsym=end=__bss_end" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + ) + 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_F1C100S ${RTOS}) + target_sources(${TARGET}-tinyusb PRIVATE + ${TOP}/src/portable/sunxi/dcd_sunxi_musb.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}) +endfunction() diff --git a/hw/bsp/f1c100s/family.mk b/hw/bsp/f1c100s/family.mk new file mode 100644 index 000000000..be416e72e --- /dev/null +++ b/hw/bsp/f1c100s/family.mk @@ -0,0 +1,58 @@ +SDK_DIR = hw/mcu/allwinner/f1c100s + +include $(TOP)/$(BOARD_PATH)/board.mk +CPU_CORE ?= arm926ej-s + +#CFLAGS += \ +# -march=armv5te \ +# -mtune=arm926ej-s \ +# -mfloat-abi=soft \ +# -marm \ + +CFLAGS += \ + -ffreestanding \ + -std=gnu99 \ + -mno-thumb-interwork \ + -D__ARM32_ARCH__=5 \ + -D__ARM926EJS__ \ + -Wno-float-equal \ + -Wno-unused-parameter \ + -DCFG_TUSB_MCU=OPT_MCU_F1C100S \ + -Wno-error=array-bounds \ + +LD_FILE = ${SDK_DIR}/f1c100s.ld + +# TODO may skip nanolib +LDFLAGS += \ + -nostdlib -lgcc \ + --specs=nosys.specs --specs=nano.specs \ + +SRC_C += \ + src/portable/sunxi/dcd_sunxi_musb.c \ + ${SDK_DIR}/machine/sys-uart.c \ + ${SDK_DIR}/machine/exception.c \ + ${SDK_DIR}/machine/sys-clock.c \ + ${SDK_DIR}/machine/sys-copyself.c \ + ${SDK_DIR}/machine/sys-dram.c \ + ${SDK_DIR}/machine/sys-mmu.c \ + ${SDK_DIR}/machine/sys-spi-flash.c \ + ${SDK_DIR}/machine/f1c100s-intc.c \ + ${SDK_DIR}/lib/malloc.c \ + ${SDK_DIR}/lib/printf.c + +SRC_S += \ + ${SDK_DIR}/machine/start.S \ + ${SDK_DIR}/lib/memcpy.S \ + ${SDK_DIR}/lib/memset.S + +INC += \ + $(TOP)/${SDK_DIR}/include \ + $(TOP)/$(BOARD_PATH) + +# flash target using xfel +flash: flash-xfel + +exec: $(BUILD)/$(PROJECT).bin + xfel ddr + xfel write 0x80000000 $< + xfel exec 0x80000000 diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index 7c89427c0..df4f616ef 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -6,12 +6,33 @@ include(CMakePrintHelpers) set(TOP "${CMAKE_CURRENT_LIST_DIR}/../..") get_filename_component(TOP ${TOP} ABSOLUTE) -# Default to gcc +#------------------------------------------------------------- +# Toolchain +# Can be changed via -DTOOLCHAIN=gcc|iar or -DCMAKE_C_COMPILER= +#------------------------------------------------------------- +# Detect toolchain based on CMAKE_C_COMPILER +if (DEFINED CMAKE_C_COMPILER) + string(FIND ${CMAKE_C_COMPILER} "iccarm" IS_IAR) + string(FIND ${CMAKE_C_COMPILER} "clang" IS_CLANG) + string(FIND ${CMAKE_C_COMPILER} "gcc" IS_GCC) + + if (NOT IS_IAR EQUAL -1) + set(TOOLCHAIN iar) + elseif (NOT IS_CLANG EQUAL -1) + set(TOOLCHAIN clang) + elseif (NOT IS_GCC EQUAL -1) + set(TOOLCHAIN gcc) + endif () +endif () + +# default to gcc if (NOT DEFINED TOOLCHAIN) set(TOOLCHAIN gcc) endif () -# FAMILY not defined, try to detect it from BOARD +#------------------------------------------------------------- +# FAMILY and BOARD +#------------------------------------------------------------- if (NOT DEFINED FAMILY) if (NOT DEFINED BOARD) message(FATAL_ERROR "You must set a FAMILY variable for the build (e.g. rp2040, espressif). @@ -40,6 +61,7 @@ if (NOT FAMILY STREQUAL rp2040) # enable LTO if supported skip rp2040 include(CheckIPOSupported) check_ipo_supported(RESULT IPO_SUPPORTED) + cmake_print_variables(IPO_SUPPORTED) if (IPO_SUPPORTED) set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) endif() @@ -71,24 +93,37 @@ set(WARNING_FLAGS_GNU -Wredundant-decls ) -set(WARNINGS_FLAGS_IAR "") +set(WARNING_FLAGS_IAR "") +#------------------------------------------------------------- +# Functions +#------------------------------------------------------------- # Filter example based on only.txt and skip.txt function(family_filter RESULT DIR) get_filename_component(DIR ${DIR} ABSOLUTE BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) - if (EXISTS "${DIR}/only.txt") - file(READ "${DIR}/only.txt" ONLYS) - # Replace newlines with semicolon so that it is treated as a list by CMake - string(REPLACE "\n" ";" ONLYS_LINES ${ONLYS}) + if (EXISTS "${DIR}/skip.txt") + file(STRINGS "${DIR}/skip.txt" SKIPS_LINES) + foreach(MCU IN LISTS FAMILY_MCUS) + # For each line in only.txt + foreach(_line ${SKIPS_LINES}) + # If mcu:xxx exists for this mcu then skip + if (${_line} STREQUAL "mcu:${MCU}" OR ${_line} STREQUAL "board:${BOARD}" OR ${_line} STREQUAL "family:${FAMILY}") + set(${RESULT} 0 PARENT_SCOPE) + return() + endif() + endforeach() + endforeach() + endif () - # For each mcu + if (EXISTS "${DIR}/only.txt") + file(STRINGS "${DIR}/only.txt" ONLYS_LINES) foreach(MCU IN LISTS FAMILY_MCUS) # For each line in only.txt foreach(_line ${ONLYS_LINES}) # If mcu:xxx exists for this mcu or board:xxx then include - if (${_line} STREQUAL "mcu:${MCU}" OR ${_line} STREQUAL "board:${BOARD}") + if (${_line} STREQUAL "mcu:${MCU}" OR ${_line} STREQUAL "board:${BOARD}" OR ${_line} STREQUAL "family:${FAMILY}") set(${RESULT} 1 PARENT_SCOPE) return() endif() @@ -97,29 +132,8 @@ function(family_filter RESULT DIR) # Didn't find it in only file so don't build set(${RESULT} 0 PARENT_SCOPE) - - elseif (EXISTS "${DIR}/skip.txt") - file(READ "${DIR}/skip.txt" SKIPS) - # Replace newlines with semicolon so that it is treated as a list by CMake - string(REPLACE "\n" ";" SKIPS_LINES ${SKIPS}) - - # For each mcu - foreach(MCU IN LISTS FAMILY_MCUS) - # For each line in only.txt - foreach(_line ${SKIPS_LINES}) - # If mcu:xxx exists for this mcu then skip - if (${_line} STREQUAL "mcu:${MCU}") - set(${RESULT} 0 PARENT_SCOPE) - return() - endif() - endforeach() - endforeach() - - # Didn't find in skip file so build - set(${RESULT} 1 PARENT_SCOPE) else() - - # Didn't find skip or only file so build + # only.txt not exist so build set(${RESULT} 1 PARENT_SCOPE) endif() endfunction() @@ -190,16 +204,25 @@ function(family_configure_common TARGET RTOS) ) # run size after build - add_custom_command(TARGET ${TARGET} POST_BUILD - COMMAND ${CMAKE_SIZE} $ - ) - + find_program(SIZE_EXE ${CMAKE_SIZE}) + if(NOT ${SIZE_EXE} STREQUAL SIZE_EXE-NOTFOUND) + add_custom_command(TARGET ${TARGET} POST_BUILD + COMMAND ${SIZE_EXE} $ + ) + endif () # Add warnings flags target_compile_options(${TARGET} PUBLIC ${WARNING_FLAGS_${CMAKE_C_COMPILER_ID}}) # Generate linker map file if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PUBLIC "LINKER:-Map=$.map") + if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 12.0) + target_link_options(${TARGET} PUBLIC "LINKER:--no-warn-rwx-segments") + endif () + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${TARGET} PUBLIC "LINKER:-Map=$.map") + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${TARGET} PUBLIC "LINKER:--map=$.map") endif() # ETM Trace option @@ -216,6 +239,7 @@ function(family_configure_common TARGET RTOS) if (NOT TARGET segger_rtt) add_library(segger_rtt STATIC ${TOP}/lib/SEGGER_RTT/RTT/SEGGER_RTT.c) target_include_directories(segger_rtt PUBLIC ${TOP}/lib/SEGGER_RTT/RTT) +# target_compile_definitions(segger_rtt PUBLIC SEGGER_RTT_MODE_DEFAULT=SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) endif() target_link_libraries(${TARGET} PUBLIC segger_rtt) endif () @@ -252,6 +276,15 @@ function(family_add_tinyusb TARGET OPT_MCU RTOS) # link tinyusb with freeRTOS kernel target_link_libraries(${TARGET}-tinyusb PUBLIC freertos_kernel) endif () + + # use max3421 as host controller + if (MAX3421_HOST STREQUAL "1") + target_compile_definitions(${TARGET}-tinyusb_config INTERFACE CFG_TUH_MAX3421=1) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/analog/max3421/hcd_max3421.c + ) + endif () + endfunction() @@ -278,13 +311,11 @@ function(family_configure_device_example TARGET RTOS) family_configure_example(${TARGET} ${RTOS}) endfunction() - # Configure host example with RTOS function(family_configure_host_example TARGET RTOS) family_configure_example(${TARGET} ${RTOS}) endfunction() - # Configure host + device example with RTOS function(family_configure_dual_usb_example TARGET RTOS) family_configure_example(${TARGET} ${RTOS}) @@ -354,8 +385,12 @@ function(family_flash_jlink TARGET) set(JLINKEXE JLinkExe) endif () + if (NOT DEFINED JLINK_IF) + set(JLINK_IF swd) + endif () + file(GENERATE - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}.jlink + OUTPUT $/${TARGET}.jlink CONTENT "halt loadfile $ r @@ -365,7 +400,7 @@ exit" add_custom_target(${TARGET}-jlink DEPENDS ${TARGET} - COMMAND ${JLINKEXE} -device ${JLINK_DEVICE} -if swd -JTAGConf -1,-1 -speed auto -CommandFile ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}.jlink + COMMAND ${JLINKEXE} -device ${JLINK_DEVICE} -if ${JLINK_IF} -JTAGConf -1,-1 -speed auto -CommandFile $/${TARGET}.jlink ) endfunction() @@ -383,6 +418,36 @@ function(family_flash_stlink TARGET) endfunction() +# Add flash openocd target +function(family_flash_openocd TARGET) + if (NOT DEFINED OPENOCD) + set(OPENOCD openocd) + endif () + + if (NOT DEFINED OPENOCD_OPTION2) + set(OPENOCD_OPTION2 "") + endif () + + separate_arguments(OPTION_LIST UNIX_COMMAND ${OPENOCD_OPTION}) + separate_arguments(OPTION_LIST2 UNIX_COMMAND ${OPENOCD_OPTION2}) + + # note skip verify since it has issue with rp2040 + add_custom_target(${TARGET}-openocd + DEPENDS ${TARGET} + COMMAND ${OPENOCD} ${OPTION_LIST} -c "program $ reset" ${OPTION_LIST2} -c exit + VERBATIM + ) +endfunction() + +# Add flash openocd-wch target +function(family_flash_openocd_wch TARGET) + if (NOT DEFINED OPENOCD) + set(OPENOCD $ENV{HOME}/app/riscv-openocd-wch/src/openocd) + endif () + + family_flash_openocd(${TARGET}) +endfunction() + # Add flash pycod target function(family_flash_pyocd TARGET) if (NOT DEFINED PYOC) @@ -396,6 +461,18 @@ function(family_flash_pyocd TARGET) endfunction() +# Add flash teensy_cli target +function(family_flash_teensy TARGET) + if (NOT DEFINED TEENSY_CLI) + set(TEENSY_CLI teensy_loader_cli) + endif () + + add_custom_target(${TARGET}-teensy + DEPENDS ${TARGET} + COMMAND ${TEENSY_CLI} --mcu=${TEENSY_MCU} -w -s $/${TARGET}.hex + ) +endfunction() + # Add flash using NXP's LinkServer (redserver) # https://www.nxp.com/design/software/development-software/mcuxpresso-software-and-tools-/linkserver-for-microcontrollers:LINKERSERVER function(family_flash_nxplink TARGET) @@ -426,6 +503,21 @@ function(family_flash_dfu_util TARGET OPTION) ) endfunction() +function(family_flash_msp430flasher TARGET) + if (NOT DEFINED MSP430Flasher) + set(MSP430FLASHER MSP430Flasher) + endif () + + # set LD_LIBRARY_PATH to find libmsp430.so (directory containing MSP430Flasher) + find_program(MSP430FLASHER_PATH MSP430Flasher) + get_filename_component(MSP430FLASHER_PARENT_DIR "${MSP430FLASHER_PATH}" DIRECTORY) + add_custom_target(${TARGET}-msp430flasher + DEPENDS ${TARGET} + COMMAND ${CMAKE_COMMAND} -E env LD_LIBRARY_PATH=${MSP430FLASHER_PARENT_DIR} + ${MSP430FLASHER} -w $/${TARGET}.hex -z [VCC] + ) +endfunction() + #---------------------------------- # Family specific #---------------------------------- @@ -437,5 +529,10 @@ if (NOT FAMILY_MCUS) set(FAMILY_MCUS ${FAMILY}) endif() +# if use max3421 as host controller, expand FAMILY_MCUS to include max3421 +if (MAX3421_HOST STREQUAL "1") + set(FAMILY_MCUS ${FAMILY_MCUS} MAX3421) +endif () + # save it in case of re-inclusion set(FAMILY_MCUS ${FAMILY_MCUS} CACHE INTERNAL "") diff --git a/hw/bsp/fomu/boards/fomu/board.cmake b/hw/bsp/fomu/boards/fomu/board.cmake new file mode 100644 index 000000000..9f5682042 --- /dev/null +++ b/hw/bsp/fomu/boards/fomu/board.cmake @@ -0,0 +1,4 @@ +function(update_board TARGET) +# target_compile_definitions(${TARGET} PUBLIC +# ) +endfunction() diff --git a/hw/bsp/fomu/fomu.c b/hw/bsp/fomu/family.c similarity index 99% rename from hw/bsp/fomu/fomu.c rename to hw/bsp/fomu/family.c index d155b743d..ccf2b12f4 100644 --- a/hw/bsp/fomu/fomu.c +++ b/hw/bsp/fomu/family.c @@ -26,10 +26,11 @@ #include #include -#include "../board_api.h" #include "csr.h" #include "irq.h" +#include "bsp/board_api.h" + //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ diff --git a/hw/bsp/fomu/family.cmake b/hw/bsp/fomu/family.cmake new file mode 100644 index 000000000..8d5ab144c --- /dev/null +++ b/hw/bsp/fomu/family.cmake @@ -0,0 +1,91 @@ +include_guard() + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR rv32i-ilp32 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS VALENTYUSB_EPTRI 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() + + if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/fomu.ld) + endif () + set(LD_FILE_Clang ${LD_FILE_GNU}) + + if (NOT DEFINED STARTUP_FILE_GNU) + set(STARTUP_FILE_GNU ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/crt0-vexriscv.S) + endif () + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/include + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + message(FATAL_ERROR "Clang is not supported for MSP432E4") + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_VALENTYUSB_EPTRI ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/valentyusb/eptri/dcd_eptri.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_add_bin_hex(${TARGET}) +endfunction() diff --git a/hw/bsp/fomu/family.mk b/hw/bsp/fomu/family.mk index d0b819120..d4b6eaea6 100644 --- a/hw/bsp/fomu/family.mk +++ b/hw/bsp/fomu/family.mk @@ -1,13 +1,16 @@ -CFLAGS += \ - -flto \ - -march=rv32i \ - -mabi=ilp32 \ - -nostdlib \ - -DCFG_TUSB_MCU=OPT_MCU_VALENTYUSB_EPTRI - # Toolchain from https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack CROSS_COMPILE = riscv-none-embed- +CPU_CORE ?= rv32i-ilp32 + +CFLAGS += \ + -flto \ + -DCFG_TUSB_MCU=OPT_MCU_VALENTYUSB_EPTRI + +LDFLAGS_GCC += \ + -nostdlib \ + --specs=nosys.specs --specs=nano.specs \ + # All source paths should be relative to the top level. LD_FILE = $(FAMILY_PATH)/fomu.ld diff --git a/hw/bsp/fomu/fomu.ld b/hw/bsp/fomu/fomu.ld index 13278d2ad..0b0cf2612 100644 --- a/hw/bsp/fomu/fomu.ld +++ b/hw/bsp/fomu/fomu.ld @@ -11,7 +11,7 @@ MEMORY { } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x2000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; /* Section Definitions */ SECTIONS diff --git a/hw/bsp/gd32vf103/boards/sipeed_longan_nano/board.cmake b/hw/bsp/gd32vf103/boards/sipeed_longan_nano/board.cmake new file mode 100644 index 000000000..403ac08cf --- /dev/null +++ b/hw/bsp/gd32vf103/boards/sipeed_longan_nano/board.cmake @@ -0,0 +1,13 @@ +set(JLINK_DEVICE gd32vf103cbt6) + +set(SDK_BSP_DIR ${SOC_DIR}/Board/gd32vf103c_longan_nano) +set(LD_FILE_GNU ${SDK_BSP_DIR}/Source/GCC/gcc_gd32vf103xb_flashxip.ld) + +function(update_board TARGET) + target_sources(${TARGET} PUBLIC + ${SDK_BSP_DIR}/Source/gd32vf103c_longan_nano.c + ) + target_include_directories(${TARGET} PUBLIC + ${SDK_BSP_DIR}/Include + ) +endfunction() diff --git a/hw/bsp/gd32vf103/boards/sipeed_longan_nano/board.mk b/hw/bsp/gd32vf103/boards/sipeed_longan_nano/board.mk index 3b8944452..fc49b7317 100644 --- a/hw/bsp/gd32vf103/boards/sipeed_longan_nano/board.mk +++ b/hw/bsp/gd32vf103/boards/sipeed_longan_nano/board.mk @@ -10,4 +10,3 @@ INC += $(TOP)/$(LONGAN_NANO_SDK_BSP)/Include # Longan Nano 128k ROM 32k RAM JLINK_DEVICE = gd32vf103cbt6 -#JLINK_DEVICE = gd32vf103c8t6 # Longan Nano Lite 64k ROM 20k RAM diff --git a/hw/bsp/gd32vf103/family.c b/hw/bsp/gd32vf103/family.c index 27d7e87bb..d4a819fb3 100644 --- a/hw/bsp/gd32vf103/family.c +++ b/hw/bsp/gd32vf103/family.c @@ -24,11 +24,11 @@ * This file is part of the TinyUSB stack. */ -#include "board.h" #include "drv_usb_hw.h" #include "drv_usb_dev.h" -#include "../board_api.h" +#include "bsp/board_api.h" +#include "board.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler diff --git a/hw/bsp/gd32vf103/family.cmake b/hw/bsp/gd32vf103/family.cmake new file mode 100644 index 000000000..5f4a3da8d --- /dev/null +++ b/hw/bsp/gd32vf103/family.cmake @@ -0,0 +1,119 @@ +include_guard() + +set(SDK_DIR ${TOP}/hw/mcu/gd/nuclei-sdk) +set(SOC_DIR ${SDK_DIR}/SoC/gd32vf103) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR rv32imac-ilp32 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS GD32VF103 CACHE INTERNAL "") + +set(JLINK_IF jtag) + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif() + + if (NOT DEFINED LD_FILE_GNU) + message(FATAL_ERROR "LD_FILE_GNU is not defined") + endif () + set(LD_FILE_Clang ${LD_FILE_GNU}) + + if (NOT DEFINED STARTUP_FILE_GNU) + set(STARTUP_FILE_GNU + ${SOC_DIR}/Common/Source/GCC/startup_gd32vf103.S + ${SOC_DIR}/Common/Source/GCC/intexc_gd32vf103.S + ) + endif () + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_gd32vf103.c + ${SOC_DIR}/Common/Source/Drivers/gd32vf103_rcu.c + ${SOC_DIR}/Common/Source/Drivers/gd32vf103_gpio.c + ${SOC_DIR}/Common/Source/Drivers/Usb/gd32vf103_usb_hw.c + ${SOC_DIR}/Common/Source/Drivers/gd32vf103_usart.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_DIR}/NMSIS/Core/Include + ${SOC_DIR}/Common/Include + ${SOC_DIR}/Common/Include/Usb + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + DOWNLOAD_MODE=DOWNLOAD_MODE_FLASHXIP + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_compile_options(${BOARD_TARGET} PUBLIC + -mcmodel=medlow + -mstrict-align + ) + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + message(FATAL_ERROR "Clang is not supported for MSP432E4") + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ${SOC_DIR}/Common/Source/Stubs/sbrk.c + ${SOC_DIR}/Common/Source/Stubs/close.c + ${SOC_DIR}/Common/Source/Stubs/isatty.c + ${SOC_DIR}/Common/Source/Stubs/fstat.c + ${SOC_DIR}/Common/Source/Stubs/lseek.c + ${SOC_DIR}/Common/Source/Stubs/read.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_GD32VF103 ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.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}) +endfunction() diff --git a/hw/bsp/gd32vf103/family.mk b/hw/bsp/gd32vf103/family.mk index 1725559c4..28e48a6b5 100644 --- a/hw/bsp/gd32vf103/family.mk +++ b/hw/bsp/gd32vf103/family.mk @@ -9,7 +9,6 @@ CROSS_COMPILE ?= riscv-none-embed- # Submodules NUCLEI_SDK = hw/mcu/gd/nuclei-sdk -DEPS_SUBMODULES += $(NUCLEI_SDK) # Nuclei-SDK paths GD32VF103_SDK_SOC = $(NUCLEI_SDK)/SoC/gd32vf103 @@ -18,12 +17,9 @@ LIBC_STUBS = $(GD32VF103_SDK_SOC)/Common/Source/Stubs STARTUP_ASM = $(GD32VF103_SDK_SOC)/Common/Source/GCC include $(TOP)/$(BOARD_PATH)/board.mk - -SKIP_NANOLIB = 1 +CPU_CORE ?= rv32imac-ilp32 CFLAGS += \ - -march=rv32imac \ - -mabi=ilp32 \ -mcmodel=medlow \ -mstrict-align \ -nostdlib -nostartfiles \ @@ -35,10 +31,10 @@ CFLAGS += -Wno-error=unused-parameter SRC_C += \ src/portable/synopsys/dwc2/dcd_dwc2.c \ - $(GD32VF103_SDK_DRIVER)/gd32vf103_rcu.c \ $(GD32VF103_SDK_DRIVER)/gd32vf103_gpio.c \ - $(GD32VF103_SDK_DRIVER)/Usb/gd32vf103_usb_hw.c \ + $(GD32VF103_SDK_DRIVER)/gd32vf103_rcu.c \ $(GD32VF103_SDK_DRIVER)/gd32vf103_usart.c \ + $(GD32VF103_SDK_DRIVER)/Usb/gd32vf103_usb_hw.c \ $(LIBC_STUBS)/sbrk.c \ $(LIBC_STUBS)/close.c \ $(LIBC_STUBS)/isatty.c \ diff --git a/hw/bsp/imxrt/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/imxrt/FreeRTOSConfig/FreeRTOSConfig.h index b65d8f1f9..7152fda01 100644 --- a/hw/bsp/imxrt/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/imxrt/FreeRTOSConfig/FreeRTOSConfig.h @@ -59,7 +59,7 @@ #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) -#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*8*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 @@ -73,14 +73,15 @@ #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 -#define configSUPPORT_STATIC_ALLOCATION 0 -#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 /* 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 +#define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 @@ -116,23 +117,6 @@ #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 diff --git a/hw/bsp/imxrt/boards/metro_m7_1011/board.h b/hw/bsp/imxrt/boards/metro_m7_1011/board.h index 3c172ebb9..24141f5f4 100644 --- a/hw/bsp/imxrt/boards/metro_m7_1011/board.h +++ b/hw/bsp/imxrt/boards/metro_m7_1011/board.h @@ -24,30 +24,24 @@ * This file is part of the TinyUSB stack. */ +#ifndef BOARD_M7_1011_H_ +#define BOARD_M7_1011_H_ -#ifndef BOARD_H_ -#define BOARD_H_ - -#include "fsl_device_registers.h" - -// required since iMX RT10xx SDK include this file for board size +// required since iMXRT MCUX-SDK include this file for board size #define BOARD_FLASH_SIZE (8*1024*1024) -// LED -#define LED_PINMUX IOMUXC_GPIO_03_GPIOMUX_IO03 -#define LED_PORT GPIO1 -#define LED_PIN 3 +// LED: IOMUXC_GPIO_03_GPIOMUX_IO03 +#define LED_PORT BOARD_INITPINS_USER_LED_PERIPHERAL +#define LED_PIN BOARD_INITPINS_USER_LED_CHANNEL #define LED_STATE_ON 1 -// D2 as button -#define BUTTON_PINMUX IOMUXC_GPIO_13_GPIOMUX_IO13 -#define BUTTON_PORT GPIO1 -#define BUTTON_PIN 13 +// D8 as button: GPIO8 +#define BUTTON_PORT BOARD_INITPINS_USER_BUTTON_PERIPHERAL +#define BUTTON_PIN BOARD_INITPINS_USER_BUTTON_CHANNEL #define BUTTON_STATE_ACTIVE 0 -// UART +// UART: IOMUXC_GPIO_09_LPUART1_RXD, IOMUXC_GPIO_10_LPUART1_TXD #define UART_PORT LPUART1 -#define UART_RX_PINMUX IOMUXC_GPIO_09_LPUART1_RXD -#define UART_TX_PINMUX IOMUXC_GPIO_10_LPUART1_TXD +#define UART_CLK_ROOT BOARD_BOOTCLOCKRUN_UART_CLK_ROOT -#endif /* BOARD_H_ */ +#endif diff --git a/hw/bsp/imxrt/boards/metro_m7_1011/board/clock_config.c b/hw/bsp/imxrt/boards/metro_m7_1011/board/clock_config.c index 1b28b668a..d5c93222c 100644 --- a/hw/bsp/imxrt/boards/metro_m7_1011/board/clock_config.c +++ b/hw/bsp/imxrt/boards/metro_m7_1011/board/clock_config.c @@ -15,11 +15,11 @@ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo -product: Clocks v11.0 +product: Clocks v12.0 processor: MIMXRT1011xxxxx package_id: MIMXRT1011DAE5A mcu_data: ksdk2_0 -processor_version: 13.0.2 +processor_version: 14.0.0 board: MIMXRT1010-EVK * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ diff --git a/hw/bsp/imxrt/boards/metro_m7_1011/board/clock_config.h b/hw/bsp/imxrt/boards/metro_m7_1011/board/clock_config.h index 119fd94bd..cc627cf6a 100644 --- a/hw/bsp/imxrt/boards/metro_m7_1011/board/clock_config.h +++ b/hw/bsp/imxrt/boards/metro_m7_1011/board/clock_config.h @@ -36,36 +36,36 @@ void BOARD_InitBootClocks(void); #define BOARD_BOOTCLOCKRUN_CORE_CLOCK 500000000U /*!< Core clock frequency: 500000000Hz */ /* Clock outputs (values are in Hz): */ -#define BOARD_BOOTCLOCKRUN_ADC_ALT_CLK 40000000UL -#define BOARD_BOOTCLOCKRUN_CKIL_SYNC_CLK_ROOT 32768UL -#define BOARD_BOOTCLOCKRUN_CLKO1_CLK 0UL -#define BOARD_BOOTCLOCKRUN_CLKO2_CLK 0UL -#define BOARD_BOOTCLOCKRUN_CLK_1M 1000000UL -#define BOARD_BOOTCLOCKRUN_CLK_24M 24000000UL -#define BOARD_BOOTCLOCKRUN_CORE_CLK_ROOT 500000000UL -#define BOARD_BOOTCLOCKRUN_ENET_500M_REF_CLK 500000000UL -#define BOARD_BOOTCLOCKRUN_FLEXIO1_CLK_ROOT 30000000UL -#define BOARD_BOOTCLOCKRUN_FLEXSPI_CLK_ROOT 132000000UL -#define BOARD_BOOTCLOCKRUN_GPT1_IPG_CLK_HIGHFREQ 62500000UL -#define BOARD_BOOTCLOCKRUN_GPT2_IPG_CLK_HIGHFREQ 62500000UL -#define BOARD_BOOTCLOCKRUN_IPG_CLK_ROOT 125000000UL -#define BOARD_BOOTCLOCKRUN_LPI2C_CLK_ROOT 60000000UL -#define BOARD_BOOTCLOCKRUN_LPSPI_CLK_ROOT 105600000UL -#define BOARD_BOOTCLOCKRUN_MQS_MCLK 63529411UL -#define BOARD_BOOTCLOCKRUN_PERCLK_CLK_ROOT 62500000UL -#define BOARD_BOOTCLOCKRUN_SAI1_CLK_ROOT 63529411UL -#define BOARD_BOOTCLOCKRUN_SAI1_MCLK1 63529411UL -#define BOARD_BOOTCLOCKRUN_SAI1_MCLK2 63529411UL -#define BOARD_BOOTCLOCKRUN_SAI1_MCLK3 30000000UL -#define BOARD_BOOTCLOCKRUN_SAI3_CLK_ROOT 63529411UL -#define BOARD_BOOTCLOCKRUN_SAI3_MCLK1 63529411UL -#define BOARD_BOOTCLOCKRUN_SAI3_MCLK2 0UL -#define BOARD_BOOTCLOCKRUN_SAI3_MCLK3 30000000UL -#define BOARD_BOOTCLOCKRUN_SPDIF0_CLK_ROOT 30000000UL -#define BOARD_BOOTCLOCKRUN_SPDIF0_EXTCLK_OUT 0UL -#define BOARD_BOOTCLOCKRUN_TRACE_CLK_ROOT 132000000UL -#define BOARD_BOOTCLOCKRUN_UART_CLK_ROOT 80000000UL -#define BOARD_BOOTCLOCKRUN_USBPHY_CLK 480000000UL +#define BOARD_BOOTCLOCKRUN_ADC_ALT_CLK 40000000UL /* Clock consumers of ADC_ALT_CLK output : N/A */ +#define BOARD_BOOTCLOCKRUN_CKIL_SYNC_CLK_ROOT 32768UL /* Clock consumers of CKIL_SYNC_CLK_ROOT output : CSU, EWM, GPT1, GPT2, KPP, PIT, RTWDOG, SNVS, SPDIF, TEMPMON, USB, WDOG1, WDOG2 */ +#define BOARD_BOOTCLOCKRUN_CLKO1_CLK 0UL /* Clock consumers of CLKO1_CLK output : N/A */ +#define BOARD_BOOTCLOCKRUN_CLKO2_CLK 0UL /* Clock consumers of CLKO2_CLK output : N/A */ +#define BOARD_BOOTCLOCKRUN_CLK_1M 1000000UL /* Clock consumers of CLK_1M output : EWM, RTWDOG */ +#define BOARD_BOOTCLOCKRUN_CLK_24M 24000000UL /* Clock consumers of CLK_24M output : GPT1, GPT2 */ +#define BOARD_BOOTCLOCKRUN_CORE_CLK_ROOT 500000000UL /* Clock consumers of CORE_CLK_ROOT output : ARM, FLEXSPI */ +#define BOARD_BOOTCLOCKRUN_ENET_500M_REF_CLK 500000000UL /* Clock consumers of ENET_500M_REF_CLK output : N/A */ +#define BOARD_BOOTCLOCKRUN_FLEXIO1_CLK_ROOT 30000000UL /* Clock consumers of FLEXIO1_CLK_ROOT output : FLEXIO1 */ +#define BOARD_BOOTCLOCKRUN_FLEXSPI_CLK_ROOT 132000000UL /* Clock consumers of FLEXSPI_CLK_ROOT output : FLEXSPI */ +#define BOARD_BOOTCLOCKRUN_GPT1_IPG_CLK_HIGHFREQ 62500000UL /* Clock consumers of GPT1_ipg_clk_highfreq output : GPT1 */ +#define BOARD_BOOTCLOCKRUN_GPT2_IPG_CLK_HIGHFREQ 62500000UL /* Clock consumers of GPT2_ipg_clk_highfreq output : GPT2 */ +#define BOARD_BOOTCLOCKRUN_IPG_CLK_ROOT 125000000UL /* Clock consumers of IPG_CLK_ROOT output : ADC1, ADC_ETC, AIPSTZ1, AIPSTZ2, AOI, ARM, CCM, CSU, DCDC, DCP, DMA0, DMAMUX, EWM, FLEXIO1, FLEXRAM, FLEXSPI, GPC, GPIO1, GPIO2, GPIO5, IOMUXC, KPP, LPI2C1, LPI2C2, LPSPI1, LPSPI2, LPUART1, LPUART2, LPUART3, LPUART4, OCOTP, PWM1, RTWDOG, SAI1, SAI3, SNVS, SPDIF, SRC, TEMPMON, TRNG, USB, WDOG1, WDOG2, XBARA */ +#define BOARD_BOOTCLOCKRUN_LPI2C_CLK_ROOT 60000000UL /* Clock consumers of LPI2C_CLK_ROOT output : LPI2C1, LPI2C2 */ +#define BOARD_BOOTCLOCKRUN_LPSPI_CLK_ROOT 105600000UL /* Clock consumers of LPSPI_CLK_ROOT output : LPSPI1, LPSPI2 */ +#define BOARD_BOOTCLOCKRUN_MQS_MCLK 63529411UL /* Clock consumers of MQS_MCLK output : N/A */ +#define BOARD_BOOTCLOCKRUN_PERCLK_CLK_ROOT 62500000UL /* Clock consumers of PERCLK_CLK_ROOT output : GPT1, GPT2, PIT */ +#define BOARD_BOOTCLOCKRUN_SAI1_CLK_ROOT 63529411UL /* Clock consumers of SAI1_CLK_ROOT output : N/A */ +#define BOARD_BOOTCLOCKRUN_SAI1_MCLK1 63529411UL /* Clock consumers of SAI1_MCLK1 output : SAI1 */ +#define BOARD_BOOTCLOCKRUN_SAI1_MCLK2 63529411UL /* Clock consumers of SAI1_MCLK2 output : SAI1 */ +#define BOARD_BOOTCLOCKRUN_SAI1_MCLK3 30000000UL /* Clock consumers of SAI1_MCLK3 output : SAI1 */ +#define BOARD_BOOTCLOCKRUN_SAI3_CLK_ROOT 63529411UL /* Clock consumers of SAI3_CLK_ROOT output : N/A */ +#define BOARD_BOOTCLOCKRUN_SAI3_MCLK1 63529411UL /* Clock consumers of SAI3_MCLK1 output : SAI3 */ +#define BOARD_BOOTCLOCKRUN_SAI3_MCLK2 0UL /* Clock consumers of SAI3_MCLK2 output : SAI3 */ +#define BOARD_BOOTCLOCKRUN_SAI3_MCLK3 30000000UL /* Clock consumers of SAI3_MCLK3 output : SAI3 */ +#define BOARD_BOOTCLOCKRUN_SPDIF0_CLK_ROOT 30000000UL /* Clock consumers of SPDIF0_CLK_ROOT output : SPDIF */ +#define BOARD_BOOTCLOCKRUN_SPDIF0_EXTCLK_OUT 0UL /* Clock consumers of SPDIF0_EXTCLK_OUT output : SPDIF */ +#define BOARD_BOOTCLOCKRUN_TRACE_CLK_ROOT 132000000UL /* Clock consumers of TRACE_CLK_ROOT output : ARM */ +#define BOARD_BOOTCLOCKRUN_UART_CLK_ROOT 80000000UL /* Clock consumers of UART_CLK_ROOT output : LPUART1, LPUART2, LPUART3, LPUART4 */ +#define BOARD_BOOTCLOCKRUN_USBPHY_CLK 480000000UL /* Clock consumers of USBPHY_CLK output : TEMPMON, USB */ /*! @brief Usb1 PLL set for BOARD_BootClockRUN configuration. */ diff --git a/hw/bsp/imxrt/boards/metro_m7_1011/board/pin_mux.c b/hw/bsp/imxrt/boards/metro_m7_1011/board/pin_mux.c new file mode 100644 index 000000000..2d869b56e --- /dev/null +++ b/hw/bsp/imxrt/boards/metro_m7_1011/board/pin_mux.c @@ -0,0 +1,91 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Pins v14.0 +processor: MIMXRT1011xxxxx +package_id: MIMXRT1011DAE5A +mcu_data: ksdk2_0 +processor_version: 14.0.0 +board: MIMXRT1010-EVK +external_user_signals: {} +pin_labels: +- {pin_num: '1', pin_signal: GPIO_11, label: GPIO_11, identifier: GPIO_11} +- {pin_num: '10', pin_signal: GPIO_03, label: 'SAI1_RXD0/U10[16]', identifier: LED;USER_LED} +- {pin_num: '4', pin_signal: GPIO_08, label: 'SAI1_MCLK/U10[11]', identifier: USER_BUTTON} +power_domains: {NVCC_GPIO: '3.3'} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +#include "fsl_common.h" +#include "fsl_iomuxc.h" +#include "fsl_gpio.h" +#include "pin_mux.h" + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitBootPins + * Description : Calls initialization functions. + * + * END ****************************************************************************************************************/ +void BOARD_InitBootPins(void) { + BOARD_InitPins(); +} + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitPins: +- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '3', peripheral: LPUART1, signal: RXD, pin_signal: GPIO_09} + - {pin_num: '2', peripheral: LPUART1, signal: TXD, pin_signal: GPIO_10} + - {pin_num: '10', peripheral: GPIO1, signal: 'gpiomux_io, 03', pin_signal: GPIO_03, identifier: USER_LED, direction: OUTPUT} + - {pin_num: '4', peripheral: GPIO1, signal: 'gpiomux_io, 08', pin_signal: GPIO_08, direction: INPUT, pull_keeper_select: Pull, pull_up_down_config: Pull_Up_100K_Ohm} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + /* GPIO configuration of USER_LED on GPIO_03 (pin 10) */ + gpio_pin_config_t USER_LED_config = { + .direction = kGPIO_DigitalOutput, + .outputLogic = 0U, + .interruptMode = kGPIO_NoIntmode + }; + /* Initialize GPIO functionality on GPIO_03 (pin 10) */ + GPIO_PinInit(GPIO1, 3U, &USER_LED_config); + + /* GPIO configuration of USER_BUTTON on GPIO_08 (pin 4) */ + gpio_pin_config_t USER_BUTTON_config = { + .direction = kGPIO_DigitalInput, + .outputLogic = 0U, + .interruptMode = kGPIO_NoIntmode + }; + /* Initialize GPIO functionality on GPIO_08 (pin 4) */ + GPIO_PinInit(GPIO1, 8U, &USER_BUTTON_config); + + IOMUXC_SetPinMux(IOMUXC_GPIO_03_GPIOMUX_IO03, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_08_GPIOMUX_IO08, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_09_LPUART1_RXD, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_10_LPUART1_TXD, 0U); + IOMUXC_GPR->GPR26 = ((IOMUXC_GPR->GPR26 & + (~(BOARD_INITPINS_IOMUXC_GPR_GPR26_GPIO_SEL_MASK))) + | IOMUXC_GPR_GPR26_GPIO_SEL(0x00U) + ); + IOMUXC_SetPinConfig(IOMUXC_GPIO_08_GPIOMUX_IO08, 0xB0A0U); +} + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/imxrt/boards/metro_m7_1011/board/pin_mux.h b/hw/bsp/imxrt/boards/metro_m7_1011/board/pin_mux.h new file mode 100644 index 000000000..5a6603cbe --- /dev/null +++ b/hw/bsp/imxrt/boards/metro_m7_1011/board/pin_mux.h @@ -0,0 +1,81 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _PIN_MUX_H_ +#define _PIN_MUX_H_ + +/*********************************************************************************************************************** + * Definitions + **********************************************************************************************************************/ + +/*! @brief Direction type */ +typedef enum _pin_mux_direction +{ + kPIN_MUX_DirectionInput = 0U, /* Input direction */ + kPIN_MUX_DirectionOutput = 1U, /* Output direction */ + kPIN_MUX_DirectionInputOrOutput = 2U /* Input or output direction */ +} pin_mux_direction_t; + +/*! + * @addtogroup pin_mux + * @{ + */ + +/*********************************************************************************************************************** + * API + **********************************************************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Calls initialization functions. + * + */ +void BOARD_InitBootPins(void); + +#define BOARD_INITPINS_IOMUXC_GPR_GPR26_GPIO_SEL_MASK 0x08U /*!< Select GPIO1 or GPIO2: affected bits mask */ + +/* GPIO_09 (number 3), LPUART1_RXD/J56[2] */ +/* Routed pin properties */ +#define BOARD_INITPINS_UART1_RXD_PERIPHERAL LPUART1 /*!< Peripheral name */ +#define BOARD_INITPINS_UART1_RXD_SIGNAL RXD /*!< Signal name */ + +/* GPIO_10 (number 2), LPUART1_TXD/J56[4] */ +/* Routed pin properties */ +#define BOARD_INITPINS_UART1_TXD_PERIPHERAL LPUART1 /*!< Peripheral name */ +#define BOARD_INITPINS_UART1_TXD_SIGNAL TXD /*!< Signal name */ + +/* GPIO_03 (number 10), SAI1_RXD0/U10[16] */ +/* Routed pin properties */ +#define BOARD_INITPINS_USER_LED_PERIPHERAL GPIO1 /*!< Peripheral name */ +#define BOARD_INITPINS_USER_LED_SIGNAL gpiomux_io /*!< Signal name */ +#define BOARD_INITPINS_USER_LED_CHANNEL 3U /*!< Signal channel */ + +/* GPIO_08 (number 4), SAI1_MCLK/U10[11] */ +/* Routed pin properties */ +#define BOARD_INITPINS_USER_BUTTON_PERIPHERAL GPIO1 /*!< Peripheral name */ +#define BOARD_INITPINS_USER_BUTTON_SIGNAL gpiomux_io /*!< Signal name */ +#define BOARD_INITPINS_USER_BUTTON_CHANNEL 8U /*!< Signal channel */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitPins(void); + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif /* _PIN_MUX_H_ */ + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/imxrt/boards/metro_m7_1011/metro_m7_1011.mex b/hw/bsp/imxrt/boards/metro_m7_1011/metro_m7_1011.mex index 606ec2cfc..ef551731a 100644 --- a/hw/bsp/imxrt/boards/metro_m7_1011/metro_m7_1011.mex +++ b/hw/bsp/imxrt/boards/metro_m7_1011/metro_m7_1011.mex @@ -1,5 +1,5 @@ - + MIMXRT1011xxxxx MIMXRT1011DAE5A @@ -19,14 +19,20 @@ false - + - 13.0.2 + 14.0.0 + + + + + + @@ -42,17 +48,12 @@ true - + true - - - true - - - + true @@ -67,39 +68,7 @@ true - - - - - - - - - - - - - - - - Configures pin routing and optionally pin electrical features. - - true - core0 - true - - - - - true - - - - - true - - - + true @@ -108,188 +77,30 @@ - - - - Configures pin routing and optionally pin electrical features. - - false - core0 - true - - - - - true - - - - - true - - - - - true - - - - - - - - - - - - - - Configures pin routing and optionally pin electrical features. - - false - core0 - true - - - - - true - - - - - true - - - - - true - - - - - + + - - - - - - - - - - - - - Configures pin routing and optionally pin electrical features. - - false - core0 - true - - - - - true - - - - - true - - - - - true - - - - - true - - - - - + - - - - - - - - - - - - - Configures pin routing and optionally pin electrical features. - - false - core0 - true - - - - - true - - - - - true - - - - - true - - - - - - - - - - - - - - - - - - - - - - - - - - - + - 13.0.2 + 14.0.0 @@ -425,43 +236,8 @@ - - - - - true - - - - - 2.5.1 - - - - - true - - - - - 2.0.1 - - - - - true - - - - - 2.0.3 - - - - - - - + + 13.0.2 @@ -469,43 +245,7 @@ - - - - 0 - - - - - true - - - - - true - - - - - true - - - - - true - - - - - true - - - - - 0 - - - + @@ -555,7 +295,7 @@ - + @@ -582,7 +322,7 @@ - + @@ -594,7 +334,7 @@ - + @@ -614,44 +354,12 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -665,19 +373,19 @@ - + - + - + - + - + diff --git a/hw/bsp/imxrt/boards/metro_m7_1011_sd/board.cmake b/hw/bsp/imxrt/boards/metro_m7_1011_sd/board.cmake new file mode 100644 index 000000000..99681ab12 --- /dev/null +++ b/hw/bsp/imxrt/boards/metro_m7_1011_sd/board.cmake @@ -0,0 +1,15 @@ +set(MCU_VARIANT MIMXRT1011) + +set(JLINK_DEVICE MIMXRT1011xxx5A) +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() diff --git a/hw/bsp/imxrt/boards/metro_m7_1011_sd/board.h b/hw/bsp/imxrt/boards/metro_m7_1011_sd/board.h new file mode 100644 index 000000000..343e17f81 --- /dev/null +++ b/hw/bsp/imxrt/boards/metro_m7_1011_sd/board.h @@ -0,0 +1,47 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019, 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_METRO_M7_1011_SD_H_ +#define BOARD_METRO_M7_1011_SD_H_ + +// required since iMXRT MCUX-SDK include this file for board size +#define BOARD_FLASH_SIZE (8*1024*1024) + +// LED: IOMUXC_GPIO_03_GPIOMUX_IO03 +#define LED_PORT BOARD_INITPINS_USER_LED_PERIPHERAL +#define LED_PIN BOARD_INITPINS_USER_LED_CHANNEL +#define LED_STATE_ON 1 + +// D8 as button: GPIO8 +#define BUTTON_PORT BOARD_INITPINS_USER_BUTTON_PERIPHERAL +#define BUTTON_PIN BOARD_INITPINS_USER_BUTTON_CHANNEL +#define BUTTON_STATE_ACTIVE 0 + +// UART: IOMUXC_GPIO_09_LPUART1_RXD, IOMUXC_GPIO_10_LPUART1_TXD +#define UART_PORT LPUART1 +#define UART_CLK_ROOT BOARD_BOOTCLOCKRUN_UART_CLK_ROOT + +#endif diff --git a/hw/bsp/imxrt/boards/metro_m7_1011_sd/board.mk b/hw/bsp/imxrt/boards/metro_m7_1011_sd/board.mk new file mode 100644 index 000000000..b845194c2 --- /dev/null +++ b/hw/bsp/imxrt/boards/metro_m7_1011_sd/board.mk @@ -0,0 +1,17 @@ +CFLAGS += -DCPU_MIMXRT1011DAE5A -DCFG_EXAMPLE_VIDEO_READONLY +MCU_VARIANT = MIMXRT1011 + +# LD file with uf2 +LD_FILE = $(BOARD_PATH)/$(BOARD).ld + +# For flash-jlink target +JLINK_DEVICE = MIMXRT1011xxx5A + +# For flash-pyocd target +PYOCD_TARGET = mimxrt1010 + +# flash using pyocd +flash: flash-uf2 +flash-uf2: $(BUILD)/$(PROJECT).uf2 + @echo copying $< + @$(CP) $< /media/$(USER)/METROM7BOOT diff --git a/hw/bsp/imxrt/boards/metro_m7_1011_sd/board/clock_config.c b/hw/bsp/imxrt/boards/metro_m7_1011_sd/board/clock_config.c new file mode 100644 index 000000000..1b28b668a --- /dev/null +++ b/hw/bsp/imxrt/boards/metro_m7_1011_sd/board/clock_config.c @@ -0,0 +1,340 @@ +/* + * How to setup clock using clock driver functions: + * + * 1. Call CLOCK_InitXXXPLL() to configure corresponding PLL clock. + * + * 2. Call CLOCK_InitXXXpfd() to configure corresponding PLL pfd clock. + * + * 3. Call CLOCK_SetMux() to configure corresponding clock source for target clock out. + * + * 4. Call CLOCK_SetDiv() to configure corresponding clock divider for target clock out. + * + * 5. Call CLOCK_SetXtalFreq() to set XTAL frequency based on board settings. + * + */ + +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Clocks v11.0 +processor: MIMXRT1011xxxxx +package_id: MIMXRT1011DAE5A +mcu_data: ksdk2_0 +processor_version: 13.0.2 +board: MIMXRT1010-EVK + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ + +#include "clock_config.h" +#include "fsl_iomuxc.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ +void BOARD_InitBootClocks(void) +{ + BOARD_BootClockRUN(); +} + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockRUN +called_from_default_init: true +outputs: +- {id: ADC_ALT_CLK.outFreq, value: 40 MHz} +- {id: CKIL_SYNC_CLK_ROOT.outFreq, value: 32.768 kHz} +- {id: CLK_1M.outFreq, value: 1 MHz} +- {id: CLK_24M.outFreq, value: 24 MHz} +- {id: CORE_CLK_ROOT.outFreq, value: 500 MHz} +- {id: ENET_500M_REF_CLK.outFreq, value: 500 MHz} +- {id: FLEXIO1_CLK_ROOT.outFreq, value: 30 MHz} +- {id: FLEXSPI_CLK_ROOT.outFreq, value: 132 MHz} +- {id: GPT1_ipg_clk_highfreq.outFreq, value: 62.5 MHz} +- {id: GPT2_ipg_clk_highfreq.outFreq, value: 62.5 MHz} +- {id: IPG_CLK_ROOT.outFreq, value: 125 MHz} +- {id: LPI2C_CLK_ROOT.outFreq, value: 60 MHz} +- {id: LPSPI_CLK_ROOT.outFreq, value: 105.6 MHz} +- {id: MQS_MCLK.outFreq, value: 1080/17 MHz} +- {id: PERCLK_CLK_ROOT.outFreq, value: 62.5 MHz} +- {id: SAI1_CLK_ROOT.outFreq, value: 1080/17 MHz} +- {id: SAI1_MCLK1.outFreq, value: 1080/17 MHz} +- {id: SAI1_MCLK2.outFreq, value: 1080/17 MHz} +- {id: SAI1_MCLK3.outFreq, value: 30 MHz} +- {id: SAI3_CLK_ROOT.outFreq, value: 1080/17 MHz} +- {id: SAI3_MCLK1.outFreq, value: 1080/17 MHz} +- {id: SAI3_MCLK3.outFreq, value: 30 MHz} +- {id: SPDIF0_CLK_ROOT.outFreq, value: 30 MHz} +- {id: TRACE_CLK_ROOT.outFreq, value: 132 MHz} +- {id: UART_CLK_ROOT.outFreq, value: 80 MHz} +- {id: USBPHY_CLK.outFreq, value: 480 MHz} +settings: +- {id: CCM.ADC_ACLK_PODF.scale, value: '12', locked: true} +- {id: CCM.AHB_PODF.scale, value: '1', locked: true} +- {id: CCM.FLEXSPI_PODF.scale, value: '4', locked: true} +- {id: CCM.IPG_PODF.scale, value: '4'} +- {id: CCM.LPSPI_PODF.scale, value: '5'} +- {id: CCM.PERCLK_PODF.scale, value: '2', locked: true} +- {id: CCM.PRE_PERIPH_CLK_SEL.sel, value: CCM_ANALOG.ENET_500M_REF_CLK} +- {id: CCM.SAI1_CLK_SEL.sel, value: CCM_ANALOG.PLL3_PFD2_CLK} +- {id: CCM.SAI3_CLK_SEL.sel, value: CCM_ANALOG.PLL3_PFD2_CLK} +- {id: CCM.TRACE_CLK_SEL.sel, value: CCM_ANALOG.PLL2_MAIN_CLK} +- {id: CCM_ANALOG.PLL2.denom, value: '1'} +- {id: CCM_ANALOG.PLL2.num, value: '0'} +- {id: CCM_ANALOG.PLL2_BYPASS.sel, value: CCM_ANALOG.PLL2_OUT_CLK} +- {id: CCM_ANALOG.PLL2_PFD0_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD0} +- {id: CCM_ANALOG.PLL2_PFD1_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD1} +- {id: CCM_ANALOG.PLL2_PFD2_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD2} +- {id: CCM_ANALOG.PLL2_PFD2_DIV.scale, value: '18', locked: true} +- {id: CCM_ANALOG.PLL2_PFD2_MUL.scale, value: '18', locked: true} +- {id: CCM_ANALOG.PLL2_PFD3_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD3} +- {id: CCM_ANALOG.PLL2_PFD3_DIV.scale, value: '18', locked: true} +- {id: CCM_ANALOG.PLL2_PFD3_MUL.scale, value: '18', locked: true} +- {id: CCM_ANALOG.PLL3_BYPASS.sel, value: CCM_ANALOG.PLL3} +- {id: CCM_ANALOG.PLL3_PFD0_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD0} +- {id: CCM_ANALOG.PLL3_PFD0_DIV.scale, value: '22', locked: true} +- {id: CCM_ANALOG.PLL3_PFD0_MUL.scale, value: '18', locked: true} +- {id: CCM_ANALOG.PLL3_PFD1_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD1} +- {id: CCM_ANALOG.PLL3_PFD2_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD2} +- {id: CCM_ANALOG.PLL3_PFD3_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD3} +- {id: CCM_ANALOG.PLL3_PFD3_DIV.scale, value: '18', locked: true} +- {id: CCM_ANALOG.PLL3_PFD3_MUL.scale, value: '18', locked: true} +- {id: CCM_ANALOG.PLL6_BYPASS.sel, value: CCM_ANALOG.PLL6} +- {id: CCM_ANALOG_PLL_USB1_EN_USB_CLKS_CFG, value: Enabled} +- {id: CCM_ANALOG_PLL_USB1_EN_USB_CLKS_OUT_CFG, value: Enabled} +- {id: CCM_ANALOG_PLL_USB1_POWER_CFG, value: 'Yes'} +sources: +- {id: XTALOSC24M.RTC_OSC.outFreq, value: 32.768 kHz, enabled: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ + +/******************************************************************************* + * Variables for BOARD_BootClockRUN configuration + ******************************************************************************/ +const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN = + { + .loopDivider = 1, /* PLL loop divider, Fout = Fin * ( 20 + loopDivider*2 + numerator / denominator ) */ + .numerator = 0, /* 30 bit numerator of fractional loop divider */ + .denominator = 1, /* 30 bit denominator of fractional loop divider */ + .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ + }; +const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN = + { + .loopDivider = 0, /* PLL loop divider, Fout = Fin * 20 */ + .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ + }; +const clock_enet_pll_config_t enetPllConfig_BOARD_BootClockRUN = + { + .enableClkOutput500M = true, /* Enable the PLL providing the ENET 500MHz reference clock */ + .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ + }; +/******************************************************************************* + * Code for BOARD_BootClockRUN configuration + ******************************************************************************/ +void BOARD_BootClockRUN(void) +{ + /* Init RTC OSC clock frequency. */ + CLOCK_SetRtcXtalFreq(32768U); + /* Enable 1MHz clock output. */ + XTALOSC24M->OSC_CONFIG2 |= XTALOSC24M_OSC_CONFIG2_ENABLE_1M_MASK; + /* Use free 1MHz clock output. */ + XTALOSC24M->OSC_CONFIG2 &= ~XTALOSC24M_OSC_CONFIG2_MUX_1M_MASK; + /* Set XTAL 24MHz clock frequency. */ + CLOCK_SetXtalFreq(24000000U); + /* Enable XTAL 24MHz clock source. */ + CLOCK_InitExternalClk(0); + /* Enable internal RC. */ + CLOCK_InitRcOsc24M(); + /* Switch clock source to external OSC. */ + CLOCK_SwitchOsc(kCLOCK_XtalOsc); + /* Set Oscillator ready counter value. */ + CCM->CCR = (CCM->CCR & (~CCM_CCR_OSCNT_MASK)) | CCM_CCR_OSCNT(127); + /* Setting the VDD_SOC to 1.25V. It is necessary to config CORE to 500Mhz. */ + DCDC->REG3 = (DCDC->REG3 & (~DCDC_REG3_TRG_MASK)) | DCDC_REG3_TRG(0x12); + /* Waiting for DCDC_STS_DC_OK bit is asserted */ + while (DCDC_REG0_STS_DC_OK_MASK != (DCDC_REG0_STS_DC_OK_MASK & DCDC->REG0)) + { + } + /* Disable IPG clock gate. */ + CLOCK_DisableClock(kCLOCK_Adc1); + CLOCK_DisableClock(kCLOCK_Xbar1); + /* Set IPG_PODF. */ + CLOCK_SetDiv(kCLOCK_IpgDiv, 3); + /* Init Enet PLL. */ + CLOCK_InitEnetPll(&enetPllConfig_BOARD_BootClockRUN); + /* Disable PERCLK clock gate. */ + CLOCK_DisableClock(kCLOCK_Gpt1); + CLOCK_DisableClock(kCLOCK_Gpt1S); + CLOCK_DisableClock(kCLOCK_Gpt2); + CLOCK_DisableClock(kCLOCK_Gpt2S); + CLOCK_DisableClock(kCLOCK_Pit); + /* Set PERCLK_PODF. */ + CLOCK_SetDiv(kCLOCK_PerclkDiv, 1); + /* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd. + * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left unchanged. + * Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as well.*/ +#if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)) + /* Disable Flexspi clock gate. */ + CLOCK_DisableClock(kCLOCK_FlexSpi); + /* Set FLEXSPI_PODF. */ + CLOCK_SetDiv(kCLOCK_FlexspiDiv, 3); + /* Set Flexspi clock source. */ + CLOCK_SetMux(kCLOCK_FlexspiMux, 0); + CLOCK_SetMux(kCLOCK_FlexspiSrcMux, 0); +#endif + /* Disable ADC_ACLK_EN clock gate. */ + CCM->CSCMR2 &= ~CCM_CSCMR2_ADC_ACLK_EN_MASK; + /* Set ADC_ACLK_PODF. */ + CLOCK_SetDiv(kCLOCK_AdcDiv, 11); + /* Disable LPSPI clock gate. */ + CLOCK_DisableClock(kCLOCK_Lpspi1); + CLOCK_DisableClock(kCLOCK_Lpspi2); + /* Set LPSPI_PODF. */ + CLOCK_SetDiv(kCLOCK_LpspiDiv, 4); + /* Set Lpspi clock source. */ + CLOCK_SetMux(kCLOCK_LpspiMux, 2); + /* Disable TRACE clock gate. */ + CLOCK_DisableClock(kCLOCK_Trace); + /* Set TRACE_PODF. */ + CLOCK_SetDiv(kCLOCK_TraceDiv, 3); + /* Set Trace clock source. */ + CLOCK_SetMux(kCLOCK_TraceMux, 0); + /* Disable SAI1 clock gate. */ + CLOCK_DisableClock(kCLOCK_Sai1); + /* Set SAI1_CLK_PRED. */ + CLOCK_SetDiv(kCLOCK_Sai1PreDiv, 3); + /* Set SAI1_CLK_PODF. */ + CLOCK_SetDiv(kCLOCK_Sai1Div, 1); + /* Set Sai1 clock source. */ + CLOCK_SetMux(kCLOCK_Sai1Mux, 0); + /* Disable SAI3 clock gate. */ + CLOCK_DisableClock(kCLOCK_Sai3); + /* Set SAI3_CLK_PRED. */ + CLOCK_SetDiv(kCLOCK_Sai3PreDiv, 3); + /* Set SAI3_CLK_PODF. */ + CLOCK_SetDiv(kCLOCK_Sai3Div, 1); + /* Set Sai3 clock source. */ + CLOCK_SetMux(kCLOCK_Sai3Mux, 0); + /* Disable Lpi2c clock gate. */ + CLOCK_DisableClock(kCLOCK_Lpi2c1); + CLOCK_DisableClock(kCLOCK_Lpi2c2); + /* Set LPI2C_CLK_PODF. */ + CLOCK_SetDiv(kCLOCK_Lpi2cDiv, 0); + /* Set Lpi2c clock source. */ + CLOCK_SetMux(kCLOCK_Lpi2cMux, 0); + /* Disable UART clock gate. */ + CLOCK_DisableClock(kCLOCK_Lpuart1); + CLOCK_DisableClock(kCLOCK_Lpuart2); + CLOCK_DisableClock(kCLOCK_Lpuart3); + CLOCK_DisableClock(kCLOCK_Lpuart4); + /* Set UART_CLK_PODF. */ + CLOCK_SetDiv(kCLOCK_UartDiv, 0); + /* Set Uart clock source. */ + CLOCK_SetMux(kCLOCK_UartMux, 0); + /* Disable SPDIF clock gate. */ + CLOCK_DisableClock(kCLOCK_Spdif); + /* Set SPDIF0_CLK_PRED. */ + CLOCK_SetDiv(kCLOCK_Spdif0PreDiv, 1); + /* Set SPDIF0_CLK_PODF. */ + CLOCK_SetDiv(kCLOCK_Spdif0Div, 7); + /* Set Spdif clock source. */ + CLOCK_SetMux(kCLOCK_SpdifMux, 3); + /* Disable Flexio1 clock gate. */ + CLOCK_DisableClock(kCLOCK_Flexio1); + /* Set FLEXIO1_CLK_PRED. */ + CLOCK_SetDiv(kCLOCK_Flexio1PreDiv, 1); + /* Set FLEXIO1_CLK_PODF. */ + CLOCK_SetDiv(kCLOCK_Flexio1Div, 7); + /* Set Flexio1 clock source. */ + CLOCK_SetMux(kCLOCK_Flexio1Mux, 3); + /* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd. + * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left unchanged. + * Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as well.*/ +#if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)) + /* Init Usb1 PLL. */ + CLOCK_InitUsb1Pll(&usb1PllConfig_BOARD_BootClockRUN); + /* Init Usb1 pfd0. */ + CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 22); + /* Init Usb1 pfd1. */ + CLOCK_InitUsb1Pfd(kCLOCK_Pfd1, 16); + /* Init Usb1 pfd2. */ + CLOCK_InitUsb1Pfd(kCLOCK_Pfd2, 17); + /* Init Usb1 pfd3. */ + CLOCK_InitUsb1Pfd(kCLOCK_Pfd3, 18); +#endif + /* Set periph clock source to use the USB1 PLL output (PLL3_SW_CLK) temporarily. */ + /* Set Pll3 SW clock source to use the USB1 PLL output. */ + CLOCK_SetMux(kCLOCK_Pll3SwMux, 0); + /* Set safe value of the AHB_PODF. */ + CLOCK_SetDiv(kCLOCK_AhbDiv, 1); + /* Set periph clock2 clock source to use the PLL3_SW_CLK. */ + CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 0); + /* Set peripheral clock source (glitchless mux) to select the temporary core clock. */ + CLOCK_SetMux(kCLOCK_PeriphMux, 1); + /* Set per clock source. */ + CLOCK_SetMux(kCLOCK_PerclkMux, 0); + /* Init System PLL. */ + CLOCK_InitSysPll(&sysPllConfig_BOARD_BootClockRUN); + /* Init System pfd0. */ + CLOCK_InitSysPfd(kCLOCK_Pfd0, 27); + /* Init System pfd1. */ + CLOCK_InitSysPfd(kCLOCK_Pfd1, 16); + /* Init System pfd2. */ + CLOCK_InitSysPfd(kCLOCK_Pfd2, 18); + /* Init System pfd3. */ + CLOCK_InitSysPfd(kCLOCK_Pfd3, 18); + /* DeInit Audio PLL. */ + CLOCK_DeinitAudioPll(); + /* Bypass Audio PLL. */ + CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllAudio, 1); + /* Set divider for Audio PLL. */ + CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK; + CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK; + /* Enable Audio PLL output. */ + CCM_ANALOG->PLL_AUDIO |= CCM_ANALOG_PLL_AUDIO_ENABLE_MASK; + /* Set preperiph clock source. */ + CLOCK_SetMux(kCLOCK_PrePeriphMux, 3); + /* Set periph clock source. */ + CLOCK_SetMux(kCLOCK_PeriphMux, 0); + /* Set periph clock2 clock source. */ + CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 0); + /* Set AHB_PODF. */ + CLOCK_SetDiv(kCLOCK_AhbDiv, 0); + /* Set clock out1 divider. */ + CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_DIV_MASK)) | CCM_CCOSR_CLKO1_DIV(0); + /* Set clock out1 source. */ + CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_SEL_MASK)) | CCM_CCOSR_CLKO1_SEL(1); + /* Set clock out2 divider. */ + CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_DIV_MASK)) | CCM_CCOSR_CLKO2_DIV(0); + /* Set clock out2 source. */ + CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_SEL_MASK)) | CCM_CCOSR_CLKO2_SEL(18); + /* Set clock out1 drives clock out1. */ + CCM->CCOSR &= ~CCM_CCOSR_CLK_OUT_SEL_MASK; + /* Disable clock out1. */ + CCM->CCOSR &= ~CCM_CCOSR_CLKO1_EN_MASK; + /* Disable clock out2. */ + CCM->CCOSR &= ~CCM_CCOSR_CLKO2_EN_MASK; + /* Set SAI1 MCLK1 clock source. */ + IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk1Sel, 0); + /* Set SAI1 MCLK2 clock source. */ + IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk2Sel, 0); + /* Set SAI1 MCLK3 clock source. */ + IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk3Sel, 0); + /* Set SAI3 MCLK3 clock source. */ + IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI3MClk3Sel, 0); + /* Set MQS configuration. */ + IOMUXC_MQSConfig(IOMUXC_GPR,kIOMUXC_MqsPwmOverSampleRate32, 0); + /* Set GPT1 High frequency reference clock source. */ + IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT1_MASK; + /* Set GPT2 High frequency reference clock source. */ + IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT2_MASK; + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; +} diff --git a/hw/bsp/imxrt/boards/metro_m7_1011_sd/board/clock_config.h b/hw/bsp/imxrt/boards/metro_m7_1011_sd/board/clock_config.h new file mode 100644 index 000000000..119fd94bd --- /dev/null +++ b/hw/bsp/imxrt/boards/metro_m7_1011_sd/board/clock_config.h @@ -0,0 +1,97 @@ +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */ + +#define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32k frequency in Hz */ +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockRUN configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 500000000U /*!< Core clock frequency: 500000000Hz */ + +/* Clock outputs (values are in Hz): */ +#define BOARD_BOOTCLOCKRUN_ADC_ALT_CLK 40000000UL +#define BOARD_BOOTCLOCKRUN_CKIL_SYNC_CLK_ROOT 32768UL +#define BOARD_BOOTCLOCKRUN_CLKO1_CLK 0UL +#define BOARD_BOOTCLOCKRUN_CLKO2_CLK 0UL +#define BOARD_BOOTCLOCKRUN_CLK_1M 1000000UL +#define BOARD_BOOTCLOCKRUN_CLK_24M 24000000UL +#define BOARD_BOOTCLOCKRUN_CORE_CLK_ROOT 500000000UL +#define BOARD_BOOTCLOCKRUN_ENET_500M_REF_CLK 500000000UL +#define BOARD_BOOTCLOCKRUN_FLEXIO1_CLK_ROOT 30000000UL +#define BOARD_BOOTCLOCKRUN_FLEXSPI_CLK_ROOT 132000000UL +#define BOARD_BOOTCLOCKRUN_GPT1_IPG_CLK_HIGHFREQ 62500000UL +#define BOARD_BOOTCLOCKRUN_GPT2_IPG_CLK_HIGHFREQ 62500000UL +#define BOARD_BOOTCLOCKRUN_IPG_CLK_ROOT 125000000UL +#define BOARD_BOOTCLOCKRUN_LPI2C_CLK_ROOT 60000000UL +#define BOARD_BOOTCLOCKRUN_LPSPI_CLK_ROOT 105600000UL +#define BOARD_BOOTCLOCKRUN_MQS_MCLK 63529411UL +#define BOARD_BOOTCLOCKRUN_PERCLK_CLK_ROOT 62500000UL +#define BOARD_BOOTCLOCKRUN_SAI1_CLK_ROOT 63529411UL +#define BOARD_BOOTCLOCKRUN_SAI1_MCLK1 63529411UL +#define BOARD_BOOTCLOCKRUN_SAI1_MCLK2 63529411UL +#define BOARD_BOOTCLOCKRUN_SAI1_MCLK3 30000000UL +#define BOARD_BOOTCLOCKRUN_SAI3_CLK_ROOT 63529411UL +#define BOARD_BOOTCLOCKRUN_SAI3_MCLK1 63529411UL +#define BOARD_BOOTCLOCKRUN_SAI3_MCLK2 0UL +#define BOARD_BOOTCLOCKRUN_SAI3_MCLK3 30000000UL +#define BOARD_BOOTCLOCKRUN_SPDIF0_CLK_ROOT 30000000UL +#define BOARD_BOOTCLOCKRUN_SPDIF0_EXTCLK_OUT 0UL +#define BOARD_BOOTCLOCKRUN_TRACE_CLK_ROOT 132000000UL +#define BOARD_BOOTCLOCKRUN_UART_CLK_ROOT 80000000UL +#define BOARD_BOOTCLOCKRUN_USBPHY_CLK 480000000UL + +/*! @brief Usb1 PLL set for BOARD_BootClockRUN configuration. + */ +extern const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN; +/*! @brief Sys PLL for BOARD_BootClockRUN configuration. + */ +extern const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN; +/*! @brief Enet PLL set for BOARD_BootClockRUN configuration. + */ +extern const clock_enet_pll_config_t enetPllConfig_BOARD_BootClockRUN; + +/******************************************************************************* + * API for BOARD_BootClockRUN configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ diff --git a/hw/bsp/imxrt/boards/metro_m7_1011_sd/board/pin_mux.c b/hw/bsp/imxrt/boards/metro_m7_1011_sd/board/pin_mux.c new file mode 100644 index 000000000..aa38e02dc --- /dev/null +++ b/hw/bsp/imxrt/boards/metro_m7_1011_sd/board/pin_mux.c @@ -0,0 +1,108 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Pins v13.1 +processor: MIMXRT1011xxxxx +package_id: MIMXRT1011DAE5A +mcu_data: ksdk2_0 +processor_version: 13.0.2 +board: MIMXRT1010-EVK +external_user_signals: {} +pin_labels: +- {pin_num: '1', pin_signal: GPIO_11, label: GPIO_11, identifier: GPIO_11} +- {pin_num: '70', pin_signal: GPIO_SD_05} +- {pin_num: '10', pin_signal: GPIO_03, label: 'SAI1_RXD0/U10[16]', identifier: LED;USER_LED} +- {pin_num: '4', pin_signal: GPIO_08, label: 'SAI1_MCLK/U10[11]', identifier: USER_BUTTON} +- {pin_num: '79', pin_signal: GPIO_13, label: 'USB_OTG1_ID/J9[4]/Q9[2]', identifier: TRACE1} +power_domains: {NVCC_GPIO: '3.3'} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +#include "fsl_common.h" +#include "fsl_iomuxc.h" +#include "fsl_gpio.h" +#include "pin_mux.h" + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitBootPins + * Description : Calls initialization functions. + * + * END ****************************************************************************************************************/ +void BOARD_InitBootPins(void) { + BOARD_InitPins(); +} + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitPins: +- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '3', peripheral: LPUART1, signal: RXD, pin_signal: GPIO_09} + - {pin_num: '2', peripheral: LPUART1, signal: TXD, pin_signal: GPIO_10} + - {pin_num: '10', peripheral: GPIO1, signal: 'gpiomux_io, 03', pin_signal: GPIO_03, identifier: USER_LED, direction: OUTPUT} + - {pin_num: '79', peripheral: ARM, signal: 'TRACE, 1', pin_signal: GPIO_13, speed: MHZ_200} + - {pin_num: '80', peripheral: ARM, signal: 'TRACE, 2', pin_signal: GPIO_12, speed: MHZ_200} + - {pin_num: '58', peripheral: ARM, signal: arm_trace_clk, pin_signal: GPIO_AD_02, speed: MHZ_200} + - {pin_num: '1', peripheral: ARM, signal: 'TRACE, 3', pin_signal: GPIO_11, speed: MHZ_200} + - {pin_num: '60', peripheral: ARM, signal: 'TRACE, 0', pin_signal: GPIO_AD_00, speed: MHZ_200} + - {pin_num: '4', peripheral: GPIO1, signal: 'gpiomux_io, 08', pin_signal: GPIO_08, direction: INPUT, pull_keeper_select: Pull, pull_up_down_config: Pull_Up_100K_Ohm} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + /* GPIO configuration of USER_LED on GPIO_03 (pin 10) */ + gpio_pin_config_t USER_LED_config = { + .direction = kGPIO_DigitalOutput, + .outputLogic = 0U, + .interruptMode = kGPIO_NoIntmode + }; + /* Initialize GPIO functionality on GPIO_03 (pin 10) */ + GPIO_PinInit(GPIO1, 3U, &USER_LED_config); + + /* GPIO configuration of USER_BUTTON on GPIO_08 (pin 4) */ + gpio_pin_config_t USER_BUTTON_config = { + .direction = kGPIO_DigitalInput, + .outputLogic = 0U, + .interruptMode = kGPIO_NoIntmode + }; + /* Initialize GPIO functionality on GPIO_08 (pin 4) */ + GPIO_PinInit(GPIO1, 8U, &USER_BUTTON_config); + + IOMUXC_SetPinMux(IOMUXC_GPIO_03_GPIOMUX_IO03, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_08_GPIOMUX_IO08, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_09_LPUART1_RXD, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_10_LPUART1_TXD, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_11_ARM_TRACE3, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_12_ARM_TRACE2, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_13_ARM_TRACE1, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_00_ARM_TRACE0, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_02_ARM_TRACE_CLK, 0U); + IOMUXC_GPR->GPR26 = ((IOMUXC_GPR->GPR26 & + (~(BOARD_INITPINS_IOMUXC_GPR_GPR26_GPIO_SEL_MASK))) + | IOMUXC_GPR_GPR26_GPIO_SEL(0x00U) + ); + IOMUXC_SetPinConfig(IOMUXC_GPIO_08_GPIOMUX_IO08, 0xB0A0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_11_ARM_TRACE3, 0x10E0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_12_ARM_TRACE2, 0x10E0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_13_ARM_TRACE1, 0x10E0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_00_ARM_TRACE0, 0x10E0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_02_ARM_TRACE_CLK, 0x10E0U); +} + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/imxrt/boards/metro_m7_1011_sd/board/pin_mux.h b/hw/bsp/imxrt/boards/metro_m7_1011_sd/board/pin_mux.h new file mode 100644 index 000000000..42c256745 --- /dev/null +++ b/hw/bsp/imxrt/boards/metro_m7_1011_sd/board/pin_mux.h @@ -0,0 +1,110 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _PIN_MUX_H_ +#define _PIN_MUX_H_ + +/*********************************************************************************************************************** + * Definitions + **********************************************************************************************************************/ + +/*! @brief Direction type */ +typedef enum _pin_mux_direction +{ + kPIN_MUX_DirectionInput = 0U, /* Input direction */ + kPIN_MUX_DirectionOutput = 1U, /* Output direction */ + kPIN_MUX_DirectionInputOrOutput = 2U /* Input or output direction */ +} pin_mux_direction_t; + +/*! + * @addtogroup pin_mux + * @{ + */ + +/*********************************************************************************************************************** + * API + **********************************************************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Calls initialization functions. + * + */ +void BOARD_InitBootPins(void); + +#define BOARD_INITPINS_IOMUXC_GPR_GPR26_GPIO_SEL_MASK 0x08U /*!< Select GPIO1 or GPIO2: affected bits mask */ + +/* GPIO_09 (number 3), LPUART1_RXD/J56[2] */ +/* Routed pin properties */ +#define BOARD_INITPINS_UART1_RXD_PERIPHERAL LPUART1 /*!< Peripheral name */ +#define BOARD_INITPINS_UART1_RXD_SIGNAL RXD /*!< Signal name */ + +/* GPIO_10 (number 2), LPUART1_TXD/J56[4] */ +/* Routed pin properties */ +#define BOARD_INITPINS_UART1_TXD_PERIPHERAL LPUART1 /*!< Peripheral name */ +#define BOARD_INITPINS_UART1_TXD_SIGNAL TXD /*!< Signal name */ + +/* GPIO_03 (number 10), SAI1_RXD0/U10[16] */ +/* Routed pin properties */ +#define BOARD_INITPINS_USER_LED_PERIPHERAL GPIO1 /*!< Peripheral name */ +#define BOARD_INITPINS_USER_LED_SIGNAL gpiomux_io /*!< Signal name */ +#define BOARD_INITPINS_USER_LED_CHANNEL 3U /*!< Signal channel */ + +/* GPIO_13 (number 79), USB_OTG1_ID/J9[4]/Q9[2] */ +/* Routed pin properties */ +#define BOARD_INITPINS_TRACE1_PERIPHERAL ARM /*!< Peripheral name */ +#define BOARD_INITPINS_TRACE1_SIGNAL TRACE /*!< Signal name */ +#define BOARD_INITPINS_TRACE1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_12 (number 80), USB_OTG1_OC/U7[A2] */ +/* Routed pin properties */ +#define BOARD_INITPINS_USB_OTG1_OC_PERIPHERAL ARM /*!< Peripheral name */ +#define BOARD_INITPINS_USB_OTG1_OC_SIGNAL TRACE /*!< Signal name */ +#define BOARD_INITPINS_USB_OTG1_OC_CHANNEL 2U /*!< Signal channel */ + +/* GPIO_AD_02 (number 58), ADC12_2/J26[12]/J56[16] */ +/* Routed pin properties */ +#define BOARD_INITPINS_ADC12_2_PERIPHERAL ARM /*!< Peripheral name */ +#define BOARD_INITPINS_ADC12_2_SIGNAL arm_trace_clk /*!< Signal name */ + +/* GPIO_11 (number 1), GPIO_11 */ +/* Routed pin properties */ +#define BOARD_INITPINS_GPIO_11_PERIPHERAL ARM /*!< Peripheral name */ +#define BOARD_INITPINS_GPIO_11_SIGNAL TRACE /*!< Signal name */ +#define BOARD_INITPINS_GPIO_11_CHANNEL 3U /*!< Signal channel */ + +/* GPIO_AD_00 (number 60), USB_OTG1_PWR */ +/* Routed pin properties */ +#define BOARD_INITPINS_USB_OTG1_PWR_PERIPHERAL ARM /*!< Peripheral name */ +#define BOARD_INITPINS_USB_OTG1_PWR_SIGNAL TRACE /*!< Signal name */ +#define BOARD_INITPINS_USB_OTG1_PWR_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_08 (number 4), SAI1_MCLK/U10[11] */ +/* Routed pin properties */ +#define BOARD_INITPINS_USER_BUTTON_PERIPHERAL GPIO1 /*!< Peripheral name */ +#define BOARD_INITPINS_USER_BUTTON_SIGNAL gpiomux_io /*!< Signal name */ +#define BOARD_INITPINS_USER_BUTTON_CHANNEL 8U /*!< Signal channel */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitPins(void); + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif /* _PIN_MUX_H_ */ + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/imxrt/boards/metro_m7_1011_sd/evkmimxrt1010_flexspi_nor_config.c b/hw/bsp/imxrt/boards/metro_m7_1011_sd/evkmimxrt1010_flexspi_nor_config.c new file mode 100644 index 000000000..752a65629 --- /dev/null +++ b/hw/bsp/imxrt/boards/metro_m7_1011_sd/evkmimxrt1010_flexspi_nor_config.c @@ -0,0 +1,48 @@ +/* + * Copyright 2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "evkmimxrt1010_flexspi_nor_config.h" + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.xip_board" +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ +#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) +__attribute__((section(".boot_hdr.conf"))) +#elif defined(__ICCARM__) +#pragma location = ".boot_hdr.conf" +#endif + +const flexspi_nor_config_t qspiflash_config = { + .memConfig = + { + .tag = FLEXSPI_CFG_BLK_TAG, + .version = FLEXSPI_CFG_BLK_VERSION, + .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .csHoldTime = 3u, + .csSetupTime = 3u, + .sflashPadType = kSerialFlash_4Pads, + .serialClkFreq = kFlexSpiSerialClk_100MHz, + .sflashA1Size = 16u * 1024u * 1024u, + .lookupTable = + { + // Read LUTs + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 24), + FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), + }, + }, + .pageSize = 256u, + .sectorSize = 4u * 1024u, + .blockSize = 64u * 1024u, + .isUniformBlockSize = false, +}; +#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/hw/bsp/imxrt/boards/metro_m7_1011_sd/evkmimxrt1010_flexspi_nor_config.h b/hw/bsp/imxrt/boards/metro_m7_1011_sd/evkmimxrt1010_flexspi_nor_config.h new file mode 100644 index 000000000..bb5a64448 --- /dev/null +++ b/hw/bsp/imxrt/boards/metro_m7_1011_sd/evkmimxrt1010_flexspi_nor_config.h @@ -0,0 +1,267 @@ +/* + * Copyright 2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __EVKMIMXRT1011_FLEXSPI_NOR_CONFIG__ +#define __EVKMIMXRT1011_FLEXSPI_NOR_CONFIG__ + +#include +#include +#include "fsl_common.h" + +/*! @name Driver version */ +/*@{*/ +/*! @brief XIP_BOARD driver version 2.0.0. */ +#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/* FLEXSPI memory config block related definitions */ +#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian +#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 +#define FLEXSPI_CFG_BLK_SIZE (512) + +/* FLEXSPI Feature related definitions */ +#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 + +/* Lookup table related definitions */ +#define CMD_INDEX_READ 0 +#define CMD_INDEX_READSTATUS 1 +#define CMD_INDEX_WRITEENABLE 2 +#define CMD_INDEX_WRITE 4 + +#define CMD_LUT_SEQ_IDX_READ 0 +#define CMD_LUT_SEQ_IDX_READSTATUS 1 +#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define CMD_LUT_SEQ_IDX_WRITE 9 + +#define CMD_SDR 0x01 +#define CMD_DDR 0x21 +#define RADDR_SDR 0x02 +#define RADDR_DDR 0x22 +#define CADDR_SDR 0x03 +#define CADDR_DDR 0x23 +#define MODE1_SDR 0x04 +#define MODE1_DDR 0x24 +#define MODE2_SDR 0x05 +#define MODE2_DDR 0x25 +#define MODE4_SDR 0x06 +#define MODE4_DDR 0x26 +#define MODE8_SDR 0x07 +#define MODE8_DDR 0x27 +#define WRITE_SDR 0x08 +#define WRITE_DDR 0x28 +#define READ_SDR 0x09 +#define READ_DDR 0x29 +#define LEARN_SDR 0x0A +#define LEARN_DDR 0x2A +#define DATSZ_SDR 0x0B +#define DATSZ_DDR 0x2B +#define DUMMY_SDR 0x0C +#define DUMMY_DDR 0x2C +#define DUMMY_RWDS_SDR 0x0D +#define DUMMY_RWDS_DDR 0x2D +#define JMP_ON_CS 0x1F +#define STOP 0 + +#define FLEXSPI_1PAD 0 +#define FLEXSPI_2PAD 1 +#define FLEXSPI_4PAD 2 +#define FLEXSPI_8PAD 3 + +#define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \ + (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \ + FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1)) + +//!@brief Definitions for FlexSPI Serial Clock Frequency +typedef enum _FlexSpiSerialClockFreq +{ + kFlexSpiSerialClk_30MHz = 1, + kFlexSpiSerialClk_50MHz = 2, + kFlexSpiSerialClk_60MHz = 3, + kFlexSpiSerialClk_75MHz = 4, + kFlexSpiSerialClk_80MHz = 5, + kFlexSpiSerialClk_100MHz = 6, + kFlexSpiSerialClk_120MHz = 7, + kFlexSpiSerialClk_133MHz = 8, +} flexspi_serial_clk_freq_t; + +//!@brief FlexSPI clock configuration type +enum +{ + kFlexSpiClk_SDR, //!< Clock configure for SDR mode + kFlexSpiClk_DDR, //!< Clock configurat for DDR mode +}; + +//!@brief FlexSPI Read Sample Clock Source definition +typedef enum _FlashReadSampleClkSource +{ + kFlexSPIReadSampleClk_LoopbackInternally = 0, + kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, + kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, + kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, +} flexspi_read_sample_clk_t; + +//!@brief Misc feature bit definitions +enum +{ + kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable + kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable + kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable + kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable + kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable + kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable + kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication. +}; + +//!@brief Flash Type Definition +enum +{ + kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR + kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND + kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH + kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND + kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial RAMs +}; + +//!@brief Flash Pad Definitions +enum +{ + kSerialFlash_1Pad = 1, + kSerialFlash_2Pads = 2, + kSerialFlash_4Pads = 4, + kSerialFlash_8Pads = 8, +}; + +//!@brief FlexSPI LUT Sequence structure +typedef struct _lut_sequence +{ + uint8_t seqNum; //!< Sequence Number, valid number: 1-16 + uint8_t seqId; //!< Sequence Index, valid number: 0-15 + uint16_t reserved; +} flexspi_lut_seq_t; + +//!@brief Flash Configuration Command Type +enum +{ + kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc + kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command + kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode + kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode + kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode + kDeviceConfigCmdType_Reset, //!< Reset device command +}; + +//!@brief FlexSPI Memory Configuration Block +typedef struct _FlexSPIConfig +{ + uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL + uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix + uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use + uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 + uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3 + uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3 + uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For + //! Serial NAND, need to refer to datasheet + uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable + uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, + //! Generic configuration, etc. + uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for + //! DPI/QPI/OPI switch or reset command + flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt + //! sequence number, [31:16] Reserved + uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration + uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable + uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe + flexspi_lut_seq_t + configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq + uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use + uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands + uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use + uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more + //! details + uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details + uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal + uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequency, device specific definitions, See System Boot + //! Chapter for more details + uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot + //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH + uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use + uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1 + uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 + uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1 + uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 + uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value + uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value + uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value + uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value + uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command + uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands + uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns + uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31 + uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - + //! busy flag is 0 when flash device is busy + uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences + flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences + uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use +} flexspi_mem_config_t; + +/* */ +#define NOR_CMD_INDEX_READ CMD_INDEX_READ //!< 0 +#define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS //!< 1 +#define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE //!< 2 +#define NOR_CMD_INDEX_ERASESECTOR 3 //!< 3 +#define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE //!< 4 +#define NOR_CMD_INDEX_CHIPERASE 5 //!< 5 +#define NOR_CMD_INDEX_DUMMY 6 //!< 6 +#define NOR_CMD_INDEX_ERASEBLOCK 7 //!< 7 + +#define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ //!< 0 READ LUT sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS \ + CMD_LUT_SEQ_IDX_READSTATUS //!< 1 Read Status LUT sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \ + 2 //!< 2 Read status DPI/QPI/OPI sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE \ + CMD_LUT_SEQ_IDX_WRITEENABLE //!< 3 Write Enable sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \ + 4 //!< 4 Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 //!< 5 Erase Sector sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 //!< 8 Erase Block sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM \ + CMD_LUT_SEQ_IDX_WRITE //!< 9 Program sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 //!< 11 Chip Erase sequence in lookupTable id stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 //!< 13 Read SFDP sequence in lookupTable id stored in config block +#define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \ + 14 //!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \ + 15 //!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk + +/* + * Serial NOR configuration block + */ +typedef struct _flexspi_nor_config +{ + flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI + uint32_t pageSize; //!< Page size of Serial NOR + uint32_t sectorSize; //!< Sector size of Serial NOR + uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command + uint8_t isUniformBlockSize; //!< Sector/Block size is the same + uint8_t reserved0[2]; //!< Reserved for future use + uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3 + uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command + uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false + uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP command execution + uint32_t blockSize; //!< Block size + uint32_t reserve2[11]; //!< Reserved for future use +} flexspi_nor_config_t; + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __EVKMIMXRT1011_FLEXSPI_NOR_CONFIG__ */ diff --git a/hw/bsp/imxrt/boards/metro_m7_1011_sd/metro_m7_1011_sd.ld b/hw/bsp/imxrt/boards/metro_m7_1011_sd/metro_m7_1011_sd.ld new file mode 100644 index 000000000..960fc6891 --- /dev/null +++ b/hw/bsp/imxrt/boards/metro_m7_1011_sd/metro_m7_1011_sd.ld @@ -0,0 +1,270 @@ +/* +** ################################################################### +** Processors: MIMXRT1011CAE4A +** MIMXRT1011DAE5A +** +** Compiler: GNU C Compiler +** Reference manual: IMXRT1010RM Rev.0, 09/2019 +** Version: rev. 1.0, 2019-08-01 +** Build: b210709 +** +** Abstract: +** Linker file for the GNU C Compiler +** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2021 NXP +** All rights reserved. +** +** SPDX-License-Identifier: BSD-3-Clause +** +** http: www.nxp.com +** mail: support@nxp.com +** +** ################################################################### +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400; +VECTOR_RAM_SIZE = DEFINED(__ram_vector_table__) ? 0x00000400 : 0; + +/* Specify the memory areas */ +MEMORY +{ + m_flash_config (RX) : ORIGIN = 0x60000400, LENGTH = 0x00000C00 + m_ivt (RX) : ORIGIN = 0x60001000, LENGTH = 0x00001000 + + m_interrupts (RX) : ORIGIN = 0x6000C000, LENGTH = 0x00000400 + m_text (RX) : ORIGIN = 0x6000C400, LENGTH = (8*1024*1024 - 0xC400) + m_qacode (RX) : ORIGIN = 0x00000000, LENGTH = 0x00008000 + m_data (RW) : ORIGIN = 0x20000000, LENGTH = 0x00008000 + m_data2 (RW) : ORIGIN = 0x20200000, LENGTH = 0x00010000 +} + +/* Define output sections */ +SECTIONS +{ + __NCACHE_REGION_START = ORIGIN(m_data2); + __NCACHE_REGION_SIZE = 0; + + .flash_config : + { + . = ALIGN(4); + __FLASH_BASE = .; + KEEP(* (.boot_hdr.conf)) /* flash config section */ + . = ALIGN(4); + } > m_flash_config + + ivt_begin = ORIGIN(m_flash_config) + LENGTH(m_flash_config); + + .ivt : AT(ivt_begin) + { + . = ALIGN(4); + KEEP(* (.boot_hdr.ivt)) /* ivt section */ + KEEP(* (.boot_hdr.boot_data)) /* boot section */ + KEEP(* (.boot_hdr.dcd_data)) /* dcd section */ + . = ALIGN(4); + } > m_ivt + + /* The startup code goes first into internal RAM */ + .interrupts : + { + __VECTOR_TABLE = .; + __Vectors = .; + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } > m_interrupts + + /* The program code and other data goes into internal RAM */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + KEEP (*(.init)) + KEEP (*(.fini)) + . = ALIGN(4); + } > m_text + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > m_text + + .ARM : + { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } > m_text + + .ctors : + { + __CTOR_LIST__ = .; + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + from the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + __CTOR_END__ = .; + } > m_text + + .dtors : + { + __DTOR_LIST__ = .; + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + __DTOR_END__ = .; + } > m_text + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } > m_text + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } > m_text + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } > m_text + + __etext = .; /* define a global symbol at end of code */ + __DATA_ROM = .; /* Symbol is used by startup for data initialization */ + + .interrupts_ram : + { + . = ALIGN(4); + __VECTOR_RAM__ = .; + __interrupts_ram_start__ = .; /* Create a global symbol at data start */ + *(.m_interrupts_ram) /* This is a user defined section */ + . += VECTOR_RAM_SIZE; + . = ALIGN(4); + __interrupts_ram_end__ = .; /* Define a global symbol at data end */ + } > m_data + + __VECTOR_RAM = DEFINED(__ram_vector_table__) ? __VECTOR_RAM__ : ORIGIN(m_interrupts); + __RAM_VECTOR_TABLE_SIZE_BYTES = DEFINED(__ram_vector_table__) ? (__interrupts_ram_end__ - __interrupts_ram_start__) : 0x0; + + .data : AT(__DATA_ROM) + { + . = ALIGN(4); + __DATA_RAM = .; + __data_start__ = .; /* create a global symbol at data start */ + *(m_usb_dma_init_data) + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(DataQuickAccess) /* quick access data section */ + KEEP(*(.jcr*)) + . = ALIGN(4); + __data_end__ = .; /* define a global symbol at data end */ + } > m_data + + __ram_function_flash_start = __DATA_ROM + (__data_end__ - __data_start__); /* Symbol is used by startup for TCM data initialization */ + + .ram_function : AT(__ram_function_flash_start) + { + . = ALIGN(32); + __ram_function_start__ = .; + *(CodeQuickAccess) + . = ALIGN(128); + __ram_function_end__ = .; + } > m_qacode + + __NDATA_ROM = __ram_function_flash_start + (__ram_function_end__ - __ram_function_start__); + .ncache.init : AT(__NDATA_ROM) + { + __noncachedata_start__ = .; /* create a global symbol at ncache data start */ + *(NonCacheable.init) + . = ALIGN(4); + __noncachedata_init_end__ = .; /* create a global symbol at initialized ncache data end */ + } > m_data + . = __noncachedata_init_end__; + .ncache : + { + *(NonCacheable) + . = ALIGN(4); + __noncachedata_end__ = .; /* define a global symbol at ncache data end */ + } > m_data + + __DATA_END = __NDATA_ROM + (__noncachedata_init_end__ - __noncachedata_start__); + text_end = ORIGIN(m_text) + LENGTH(m_text); + ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data") + + /* Uninitialized data section */ + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + . = ALIGN(4); + __START_BSS = .; + __bss_start__ = .; + *(m_usb_dma_noninit_data) + *(.bss) + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + __END_BSS = .; + } > m_data + + .heap : + { + . = ALIGN(8); + __end__ = .; + PROVIDE(end = .); + __HeapBase = .; + . += HEAP_SIZE; + __HeapLimit = .; + __heap_limit = .; /* Add for _sbrk */ + } > m_data + + .stack : + { + . = ALIGN(8); + . += STACK_SIZE; + } > m_data + + /* Initializes stack on the end of block */ + __StackTop = ORIGIN(m_data) + LENGTH(m_data); + __StackLimit = __StackTop - STACK_SIZE; + PROVIDE(__stack = __StackTop); + + .ARM.attributes 0 : { *(.ARM.attributes) } + + ASSERT(__StackLimit >= __HeapLimit, "region m_data overflowed with stack and heap") +} diff --git a/hw/bsp/imxrt/boards/metro_m7_1011_sd/metro_m7_1011_sd.mex b/hw/bsp/imxrt/boards/metro_m7_1011_sd/metro_m7_1011_sd.mex new file mode 100644 index 000000000..7aab59a68 --- /dev/null +++ b/hw/bsp/imxrt/boards/metro_m7_1011_sd/metro_m7_1011_sd.mex @@ -0,0 +1,431 @@ + + + + MIMXRT1011xxxxx + MIMXRT1011DAE5A + MIMXRT1010-EVK + A + ksdk2_0 + + + + + + + true + false + false + true + false + + + + + + + + + 13.0.2 + + + + + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. + + true + core0 + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 13.0.2 + + + + + + + + + true + + + + + INPUT + + + + + true + + + + + OUTPUT + + + + + true + + + + + INPUT + + + + + true + + + + + OUTPUT + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + 0.0.0 + + + + + + + 13.0.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.0.0 + + + + diff --git a/hw/bsp/imxrt/boards/metro_m7_1011_sd/ozone/metro_m7_1011_sd.jdebug b/hw/bsp/imxrt/boards/metro_m7_1011_sd/ozone/metro_m7_1011_sd.jdebug new file mode 100644 index 000000000..90f9b77e5 --- /dev/null +++ b/hw/bsp/imxrt/boards/metro_m7_1011_sd/ozone/metro_m7_1011_sd.jdebug @@ -0,0 +1,215 @@ + +/********************************************************************* +* +* OnProjectLoad +* +* Function description +* Project load routine. Required. +* +********************************************************************** +*/ +void OnProjectLoad (void) { + Project.SetTraceSource ("Trace Pins"); + Project.SetTraceTiming (50, 50, 50, 50); + Project.SetDevice ("MIMXRT1011xxx4A"); + Project.SetHostIF ("USB", ""); + Project.SetTargetIF ("SWD"); + Project.SetTIFSpeed ("20 MHz"); + Project.AddSvdFile ("$(InstallDir)/Config/CPU/Cortex-M7F.svd"); + Project.AddSvdFile ("$(InstallDir)/Config/Peripherals/ARMv7M.svd"); + Project.AddSvdFile ("./MIMXRT1011.svd"); + + + // timing delay for trace pins in pico seconds, default is 2 nano seconds + + File.Open ("../../../../../../examples/cmake-build-metro-m7-1011-sd/device/cdc_msc/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) { +} + +/********************************************************************* +* +* 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) { + // + // Trace pin init is done by J-Link script file as J-Link script files are IDE independent + // + //Project.SetJLinkScript("./ST_STM32H743_Traceconfig.pex"); +} + +/********************************************************************* +* +* 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) { + +} + +/********************************************************************* +* +* 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) { +//} diff --git a/hw/bsp/imxrt/boards/mimxrt1010_evk/board.h b/hw/bsp/imxrt/boards/mimxrt1010_evk/board.h index 926f45618..da12075a0 100644 --- a/hw/bsp/imxrt/boards/mimxrt1010_evk/board.h +++ b/hw/bsp/imxrt/boards/mimxrt1010_evk/board.h @@ -24,30 +24,24 @@ * This file is part of the TinyUSB stack. */ +#ifndef BOARD_MIMXRT1010_EVK_H_ +#define BOARD_MIMXRT1010_EVK_H_ -#ifndef BOARD_H_ -#define BOARD_H_ - -#include "fsl_device_registers.h" - -// required since iMX RT10xx SDK include this file for board size +// required since iMXRT MCUX-SDK include this file for board size #define BOARD_FLASH_SIZE (0x1000000U) -// LED -#define LED_PINMUX IOMUXC_GPIO_11_GPIOMUX_IO11 -#define LED_PORT GPIO1 -#define LED_PIN 11 +// LED: IOMUXC_GPIO_11_GPIOMUX_IO11 +#define LED_PORT BOARD_INITPINS_USER_LED_PERIPHERAL +#define LED_PIN BOARD_INITPINS_USER_LED_CHANNEL #define LED_STATE_ON 0 -// SW8 button -#define BUTTON_PINMUX IOMUXC_GPIO_SD_05_GPIO2_IO05 -#define BUTTON_PORT GPIO2 -#define BUTTON_PIN 5 +// SW8 button: IOMUXC_GPIO_SD_05_GPIO2_IO05 +#define BUTTON_PORT BOARD_INITPINS_USER_BUTTON_GPIO +#define BUTTON_PIN BOARD_INITPINS_USER_BUTTON_GPIO_PIN #define BUTTON_STATE_ACTIVE 0 -// UART +// UART: IOMUXC_GPIO_09_LPUART1_RXD, IOMUXC_GPIO_10_LPUART1_TXD #define UART_PORT LPUART1 -#define UART_RX_PINMUX IOMUXC_GPIO_09_LPUART1_RXD -#define UART_TX_PINMUX IOMUXC_GPIO_10_LPUART1_TXD +#define UART_CLK_ROOT BOARD_BOOTCLOCKRUN_UART_CLK_ROOT -#endif /* BOARD_H_ */ +#endif diff --git a/hw/bsp/imxrt/boards/mimxrt1010_evk/board/clock_config.c b/hw/bsp/imxrt/boards/mimxrt1010_evk/board/clock_config.c index 6cd18c8c2..1b28b668a 100644 --- a/hw/bsp/imxrt/boards/mimxrt1010_evk/board/clock_config.c +++ b/hw/bsp/imxrt/boards/mimxrt1010_evk/board/clock_config.c @@ -24,19 +24,8 @@ board: MIMXRT1010-EVK * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ #include "clock_config.h" - -// Suppress warning caused by mcu driver -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" -#endif - #include "fsl_iomuxc.h" -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif - /******************************************************************************* * Definitions ******************************************************************************/ diff --git a/hw/bsp/imxrt/boards/mimxrt1010_evk/board/pin_mux.c b/hw/bsp/imxrt/boards/mimxrt1010_evk/board/pin_mux.c new file mode 100644 index 000000000..b960191d1 --- /dev/null +++ b/hw/bsp/imxrt/boards/mimxrt1010_evk/board/pin_mux.c @@ -0,0 +1,89 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Pins v13.1 +processor: MIMXRT1011xxxxx +package_id: MIMXRT1011DAE5A +mcu_data: ksdk2_0 +processor_version: 13.0.2 +board: MIMXRT1010-EVK +external_user_signals: {} +pin_labels: +- {pin_num: '1', pin_signal: GPIO_11, label: GPIO_11, identifier: LED;USERLED;USER_LED} +power_domains: {NVCC_GPIO: '3.3'} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +#include "fsl_common.h" +#include "fsl_iomuxc.h" +#include "fsl_gpio.h" +#include "pin_mux.h" + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitBootPins + * Description : Calls initialization functions. + * + * END ****************************************************************************************************************/ +void BOARD_InitBootPins(void) { + BOARD_InitPins(); +} + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitPins: +- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '70', peripheral: GPIO2, signal: 'gpio_io, 05', pin_signal: GPIO_SD_05, direction: INPUT, pull_keeper_select: Pull, pull_up_down_config: Pull_Up_47K_Ohm} + - {pin_num: '1', peripheral: GPIO1, signal: 'gpiomux_io, 11', pin_signal: GPIO_11, identifier: USER_LED, direction: OUTPUT} + - {pin_num: '3', peripheral: LPUART1, signal: RXD, pin_signal: GPIO_09} + - {pin_num: '2', peripheral: LPUART1, signal: TXD, pin_signal: GPIO_10} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + /* GPIO configuration of USER_LED on GPIO_11 (pin 1) */ + gpio_pin_config_t USER_LED_config = { + .direction = kGPIO_DigitalOutput, + .outputLogic = 0U, + .interruptMode = kGPIO_NoIntmode + }; + /* Initialize GPIO functionality on GPIO_11 (pin 1) */ + GPIO_PinInit(GPIO1, 11U, &USER_LED_config); + + /* GPIO configuration of USER_BUTTON on GPIO_SD_05 (pin 70) */ + gpio_pin_config_t USER_BUTTON_config = { + .direction = kGPIO_DigitalInput, + .outputLogic = 0U, + .interruptMode = kGPIO_NoIntmode + }; + /* Initialize GPIO functionality on GPIO_SD_05 (pin 70) */ + GPIO_PinInit(GPIO2, 5U, &USER_BUTTON_config); + + IOMUXC_SetPinMux(IOMUXC_GPIO_09_LPUART1_RXD, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_10_LPUART1_TXD, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_11_GPIOMUX_IO11, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_05_GPIO2_IO05, 0U); + IOMUXC_GPR->GPR26 = ((IOMUXC_GPR->GPR26 & + (~(BOARD_INITPINS_IOMUXC_GPR_GPR26_GPIO_SEL_MASK))) + | IOMUXC_GPR_GPR26_GPIO_SEL(0x00U) + ); + IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_05_GPIO2_IO05, 0x70A0U); +} + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/imxrt/boards/mimxrt1010_evk/board/pin_mux.h b/hw/bsp/imxrt/boards/mimxrt1010_evk/board/pin_mux.h new file mode 100644 index 000000000..0c980150a --- /dev/null +++ b/hw/bsp/imxrt/boards/mimxrt1010_evk/board/pin_mux.h @@ -0,0 +1,89 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _PIN_MUX_H_ +#define _PIN_MUX_H_ + +/*********************************************************************************************************************** + * Definitions + **********************************************************************************************************************/ + +/*! @brief Direction type */ +typedef enum _pin_mux_direction +{ + kPIN_MUX_DirectionInput = 0U, /* Input direction */ + kPIN_MUX_DirectionOutput = 1U, /* Output direction */ + kPIN_MUX_DirectionInputOrOutput = 2U /* Input or output direction */ +} pin_mux_direction_t; + +/*! + * @addtogroup pin_mux + * @{ + */ + +/*********************************************************************************************************************** + * API + **********************************************************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Calls initialization functions. + * + */ +void BOARD_InitBootPins(void); + +#define BOARD_INITPINS_IOMUXC_GPR_GPR26_GPIO_SEL_MASK 0x0820U /*!< Select GPIO1 or GPIO2: affected bits mask */ + +/* GPIO_SD_05 (number 70), USER_BUTTON */ +/* Routed pin properties */ +#define BOARD_INITPINS_USER_BUTTON_PERIPHERAL GPIO2 /*!< Peripheral name */ +#define BOARD_INITPINS_USER_BUTTON_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITPINS_USER_BUTTON_CHANNEL 5U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_USER_BUTTON_GPIO GPIO2 /*!< GPIO peripheral base pointer */ +#define BOARD_INITPINS_USER_BUTTON_GPIO_PIN 5U /*!< GPIO pin number */ +#define BOARD_INITPINS_USER_BUTTON_GPIO_PIN_MASK (1U << 5U) /*!< GPIO pin mask */ +#define BOARD_INITPINS_USER_BUTTON_PORT GPIO2 /*!< PORT peripheral base pointer */ +#define BOARD_INITPINS_USER_BUTTON_PIN 5U /*!< PORT pin number */ +#define BOARD_INITPINS_USER_BUTTON_PIN_MASK (1U << 5U) /*!< PORT pin mask */ + +/* GPIO_11 (number 1), GPIO_11 */ +/* Routed pin properties */ +#define BOARD_INITPINS_USER_LED_PERIPHERAL GPIO1 /*!< Peripheral name */ +#define BOARD_INITPINS_USER_LED_SIGNAL gpiomux_io /*!< Signal name */ +#define BOARD_INITPINS_USER_LED_CHANNEL 11U /*!< Signal channel */ + +/* GPIO_09 (number 3), LPUART1_RXD/J56[2] */ +/* Routed pin properties */ +#define BOARD_INITPINS_UART1_RXD_PERIPHERAL LPUART1 /*!< Peripheral name */ +#define BOARD_INITPINS_UART1_RXD_SIGNAL RXD /*!< Signal name */ + +/* GPIO_10 (number 2), LPUART1_TXD/J56[4] */ +/* Routed pin properties */ +#define BOARD_INITPINS_UART1_TXD_PERIPHERAL LPUART1 /*!< Peripheral name */ +#define BOARD_INITPINS_UART1_TXD_SIGNAL TXD /*!< Signal name */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitPins(void); + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif /* _PIN_MUX_H_ */ + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/imxrt/boards/mimxrt1010_evk/mimxrt1010_evk.mex b/hw/bsp/imxrt/boards/mimxrt1010_evk/mimxrt1010_evk.mex index 606ec2cfc..701f3e9c3 100644 --- a/hw/bsp/imxrt/boards/mimxrt1010_evk/mimxrt1010_evk.mex +++ b/hw/bsp/imxrt/boards/mimxrt1010_evk/mimxrt1010_evk.mex @@ -26,6 +26,9 @@ 13.0.2 + + + @@ -42,17 +45,12 @@ true - + true - - - true - - - + true @@ -67,147 +65,7 @@ true - - - - - - - - - - - - - - - - Configures pin routing and optionally pin electrical features. - - true - core0 - true - - - - - true - - - - - true - - - - - true - - - - - - - - - - Configures pin routing and optionally pin electrical features. - - false - core0 - true - - - - - true - - - - - true - - - - - true - - - - - - - - - - - - - - Configures pin routing and optionally pin electrical features. - - false - core0 - true - - - - - true - - - - - true - - - - - true - - - - - - - - - - - - - - - - - - - - - - Configures pin routing and optionally pin electrical features. - - false - core0 - true - - - - - true - - - - - true - - - - - true - - - + true @@ -217,68 +75,18 @@ - - - - - - - - + - - - - Configures pin routing and optionally pin electrical features. - - false - core0 - true - - - - - true - - - - - true - - - - - true - - - - - + - - - - - - - - - - - - - - - - - - - - + + + + @@ -425,43 +233,8 @@ - - - - - true - - - - - 2.5.1 - - - - - true - - - - - 2.0.1 - - - - - true - - - - - 2.0.3 - - - - - - - + + 13.0.2 @@ -469,43 +242,7 @@ - - - - 0 - - - - - true - - - - - true - - - - - true - - - - - true - - - - - true - - - - - 0 - - - + @@ -555,7 +292,7 @@ - + @@ -582,7 +319,7 @@ - + @@ -594,7 +331,7 @@ - + @@ -614,44 +351,12 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -665,19 +370,19 @@ - + - + - + - + - + diff --git a/hw/bsp/imxrt/boards/mimxrt1015_evk/board.h b/hw/bsp/imxrt/boards/mimxrt1015_evk/board.h index 10d9fad07..6ac78453f 100644 --- a/hw/bsp/imxrt/boards/mimxrt1015_evk/board.h +++ b/hw/bsp/imxrt/boards/mimxrt1015_evk/board.h @@ -24,28 +24,28 @@ * This file is part of the TinyUSB stack. */ +#ifndef BOARD_MIMXRT1015_EVK_H_ +#define BOARD_MIMXRT1015_EVK_H_ -#ifndef BOARD_H_ -#define BOARD_H_ - -// required since iMX RT10xx SDK include this file for board size +// required since iMXRT MCUX-SDK include this file for board size #define BOARD_FLASH_SIZE (0x1000000U) // LED #define LED_PINMUX IOMUXC_GPIO_SD_B1_01_GPIO3_IO21 -#define LED_PORT GPIO3 -#define LED_PIN 21 +#define LED_PORT BOARD_INITPINS_USER_LED_PERIPHERAL +#define LED_PIN BOARD_INITPINS_USER_LED_CHANNEL #define LED_STATE_ON 0 // SW8 button #define BUTTON_PINMUX IOMUXC_GPIO_EMC_09_GPIO2_IO09 -#define BUTTON_PORT GPIO2 -#define BUTTON_PIN 9 +#define BUTTON_PORT BOARD_INITPINS_USER_BUTTON_GPIO +#define BUTTON_PIN BOARD_INITPINS_USER_BUTTON_GPIO_PIN #define BUTTON_STATE_ACTIVE 0 // UART #define UART_PORT LPUART1 +#define UART_CLK_ROOT BOARD_BOOTCLOCKRUN_UART_CLK_ROOT #define UART_RX_PINMUX IOMUXC_GPIO_AD_B0_07_LPUART1_RX #define UART_TX_PINMUX IOMUXC_GPIO_AD_B0_06_LPUART1_TX -#endif /* BOARD_H_ */ +#endif diff --git a/hw/bsp/imxrt/boards/mimxrt1015_evk/board/pin_mux.c b/hw/bsp/imxrt/boards/mimxrt1015_evk/board/pin_mux.c new file mode 100644 index 000000000..97224a332 --- /dev/null +++ b/hw/bsp/imxrt/boards/mimxrt1015_evk/board/pin_mux.c @@ -0,0 +1,118 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Pins v13.1 +processor: MIMXRT1015xxxxx +package_id: MIMXRT1015DAF5A +mcu_data: ksdk2_0 +processor_version: 13.0.2 +board: MIMXRT1015-EVK +external_user_signals: {} +pin_labels: +- {pin_num: '21', pin_signal: GPIO_SD_B1_01, label: GPIO SD_B1_01, identifier: USER_LED} +power_domains: {NVCC_GPIO: '3.3'} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +#include "fsl_common.h" +#include "fsl_iomuxc.h" +#include "fsl_gpio.h" +#include "pin_mux.h" + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitBootPins + * Description : Calls initialization functions. + * + * END ****************************************************************************************************************/ +void BOARD_InitBootPins(void) { + BOARD_InitPins(); +} + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitPins: +- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '1', peripheral: GPIO2, signal: 'gpio_io, 09', pin_signal: GPIO_EMC_09, direction: INPUT, pull_keeper_select: Pull, pull_up_down_config: Pull_Up_47K_Ohm} + - {pin_num: '68', peripheral: LPUART1, signal: RX, pin_signal: GPIO_AD_B0_07, pull_up_down_config: Pull_Down_100K_Ohm} + - {pin_num: '72', peripheral: LPUART1, signal: TX, pin_signal: GPIO_AD_B0_06} + - {pin_num: '21', peripheral: GPIO3, signal: 'gpio_io, 21', pin_signal: GPIO_SD_B1_01, direction: OUTPUT} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + /* GPIO configuration of USER_BUTTON on GPIO_EMC_09 (pin 1) */ + gpio_pin_config_t USER_BUTTON_config = { + .direction = kGPIO_DigitalInput, + .outputLogic = 0U, + .interruptMode = kGPIO_NoIntmode + }; + /* Initialize GPIO functionality on GPIO_EMC_09 (pin 1) */ + GPIO_PinInit(GPIO2, 9U, &USER_BUTTON_config); + + /* GPIO configuration of USER_LED on GPIO_SD_B1_01 (pin 21) */ + gpio_pin_config_t USER_LED_config = { + .direction = kGPIO_DigitalOutput, + .outputLogic = 0U, + .interruptMode = kGPIO_NoIntmode + }; + /* Initialize GPIO functionality on GPIO_SD_B1_01 (pin 21) */ + GPIO_PinInit(GPIO3, 21U, &USER_LED_config); + + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_06_LPUART1_TX, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_07_LPUART1_RX, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_09_GPIO2_IO09, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_01_GPIO3_IO21, 0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_07_LPUART1_RX, 0x10B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_EMC_09_GPIO2_IO09, 0x70B0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitQSPIPins: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '12', peripheral: FLEXSPI, signal: FLEXSPI_A_SCLK, pin_signal: GPIO_SD_B1_07} + - {pin_num: '11', peripheral: FLEXSPI, signal: FLEXSPI_A_DATA0, pin_signal: GPIO_SD_B1_08} + - {pin_num: '9', peripheral: FLEXSPI, signal: FLEXSPI_A_DATA1, pin_signal: GPIO_SD_B1_10} + - {pin_num: '10', peripheral: FLEXSPI, signal: FLEXSPI_A_DATA2, pin_signal: GPIO_SD_B1_09} + - {pin_num: '13', peripheral: FLEXSPI, signal: FLEXSPI_A_DATA3, pin_signal: GPIO_SD_B1_06} + - {pin_num: '8', peripheral: FLEXSPI, signal: FLEXSPI_A_SS0_B, pin_signal: GPIO_SD_B1_11} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitQSPIPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitQSPIPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_06_FLEXSPI_A_DATA03, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_07_FLEXSPI_A_SCLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_08_FLEXSPI_A_DATA00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_09_FLEXSPI_A_DATA02, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_10_FLEXSPI_A_DATA01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_11_FLEXSPI_A_SS0_B, 0U); +} + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/imxrt/boards/mimxrt1015_evk/board/pin_mux.h b/hw/bsp/imxrt/boards/mimxrt1015_evk/board/pin_mux.h new file mode 100644 index 000000000..c9cbe3b72 --- /dev/null +++ b/hw/bsp/imxrt/boards/mimxrt1015_evk/board/pin_mux.h @@ -0,0 +1,133 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _PIN_MUX_H_ +#define _PIN_MUX_H_ + +/*********************************************************************************************************************** + * Definitions + **********************************************************************************************************************/ + +/*! @brief Direction type */ +typedef enum _pin_mux_direction +{ + kPIN_MUX_DirectionInput = 0U, /* Input direction */ + kPIN_MUX_DirectionOutput = 1U, /* Output direction */ + kPIN_MUX_DirectionInputOrOutput = 2U /* Input or output direction */ +} pin_mux_direction_t; + +/*! + * @addtogroup pin_mux + * @{ + */ + +/*********************************************************************************************************************** + * API + **********************************************************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Calls initialization functions. + * + */ +void BOARD_InitBootPins(void); + +/* GPIO_EMC_09 (number 1), USER_BUTTON */ +/* Routed pin properties */ +#define BOARD_INITPINS_USER_BUTTON_PERIPHERAL GPIO2 /*!< Peripheral name */ +#define BOARD_INITPINS_USER_BUTTON_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITPINS_USER_BUTTON_CHANNEL 9U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_USER_BUTTON_GPIO GPIO2 /*!< GPIO peripheral base pointer */ +#define BOARD_INITPINS_USER_BUTTON_GPIO_PIN 9U /*!< GPIO pin number */ +#define BOARD_INITPINS_USER_BUTTON_GPIO_PIN_MASK (1U << 9U) /*!< GPIO pin mask */ +#define BOARD_INITPINS_USER_BUTTON_PORT GPIO2 /*!< PORT peripheral base pointer */ +#define BOARD_INITPINS_USER_BUTTON_PIN 9U /*!< PORT pin number */ +#define BOARD_INITPINS_USER_BUTTON_PIN_MASK (1U << 9U) /*!< PORT pin mask */ + +/* GPIO_AD_B0_07 (number 68), LPUART1_RXD */ +/* Routed pin properties */ +#define BOARD_INITPINS_UART1_RXD_PERIPHERAL LPUART1 /*!< Peripheral name */ +#define BOARD_INITPINS_UART1_RXD_SIGNAL RX /*!< Signal name */ + +/* GPIO_AD_B0_06 (number 72), LPUART1_TXD */ +/* Routed pin properties */ +#define BOARD_INITPINS_UART1_TXD_PERIPHERAL LPUART1 /*!< Peripheral name */ +#define BOARD_INITPINS_UART1_TXD_SIGNAL TX /*!< Signal name */ + +/* GPIO_SD_B1_01 (number 21), GPIO SD_B1_01 */ +/* Routed pin properties */ +#define BOARD_INITPINS_USER_LED_PERIPHERAL GPIO3 /*!< Peripheral name */ +#define BOARD_INITPINS_USER_LED_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITPINS_USER_LED_CHANNEL 21U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_USER_LED_GPIO GPIO3 /*!< GPIO peripheral base pointer */ +#define BOARD_INITPINS_USER_LED_GPIO_PIN 21U /*!< GPIO pin number */ +#define BOARD_INITPINS_USER_LED_GPIO_PIN_MASK (1U << 21U) /*!< GPIO pin mask */ +#define BOARD_INITPINS_USER_LED_PORT GPIO3 /*!< PORT peripheral base pointer */ +#define BOARD_INITPINS_USER_LED_PIN 21U /*!< PORT pin number */ +#define BOARD_INITPINS_USER_LED_PIN_MASK (1U << 21U) /*!< PORT pin mask */ + + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitPins(void); + +/* GPIO_SD_B1_07 (number 12), FlexSPI_CLK_A/U13[6] */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_CLK_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_CLK_SIGNAL FLEXSPI_A_SCLK /*!< Signal name */ + +/* GPIO_SD_B1_08 (number 11), FlexSPI_D0_A/U13[5] */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_D0_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_D0_A_SIGNAL FLEXSPI_A_DATA0 /*!< Signal name */ + +/* GPIO_SD_B1_10 (number 9), FlexSPI_D1_A/U13[2] */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_D1_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_D1_A_SIGNAL FLEXSPI_A_DATA1 /*!< Signal name */ + +/* GPIO_SD_B1_09 (number 10), FlexSPI_D2_A/U13[3] */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_D2_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_D2_A_SIGNAL FLEXSPI_A_DATA2 /*!< Signal name */ + +/* GPIO_SD_B1_06 (number 13), FlexSPI_D3_A/U13[7] */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_D3_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_D3_A_SIGNAL FLEXSPI_A_DATA3 /*!< Signal name */ + +/* GPIO_SD_B1_11 (number 8), FlexSPI_SS0/U13[1] */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_SS0_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_SS0_SIGNAL FLEXSPI_A_SS0_B /*!< Signal name */ + + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitQSPIPins(void); + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif /* _PIN_MUX_H_ */ + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/imxrt/boards/mimxrt1015_evk/mimxrt1015_evk.mex b/hw/bsp/imxrt/boards/mimxrt1015_evk/mimxrt1015_evk.mex index 431a59af7..88265d32e 100644 --- a/hw/bsp/imxrt/boards/mimxrt1015_evk/mimxrt1015_evk.mex +++ b/hw/bsp/imxrt/boards/mimxrt1015_evk/mimxrt1015_evk.mex @@ -26,6 +26,12 @@ 13.0.2 + + + + + + @@ -39,41 +45,51 @@ true + + + true + + + + + true + + true - - - - - Configures pin routing and optionally pin electrical features. - - true - core0 - true - - - - - true - - - + true - + true - + + + + + + + + + + + + + + + + + @@ -109,147 +125,6 @@ - - Configures pin routing and optionally pin electrical features. - - false - core0 - true - - - - - true - - - - - true - - - - - true - - - - - - - - - - - - - - - - - - - - - - - Configures pin routing and optionally pin electrical features. - - false - core0 - true - - - - - true - - - - - true - - - - - true - - - - - true - - - - - - - - - - - - - - - - - - - - - - Configures pin routing and optionally pin electrical features. - - false - core0 - true - - - - - true - - - - - true - - - - - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -399,11 +274,8 @@ - - - - - + + 13.0.2 diff --git a/hw/bsp/imxrt/boards/mimxrt1020_evk/board.h b/hw/bsp/imxrt/boards/mimxrt1020_evk/board.h index 284bb08e7..4f4593524 100644 --- a/hw/bsp/imxrt/boards/mimxrt1020_evk/board.h +++ b/hw/bsp/imxrt/boards/mimxrt1020_evk/board.h @@ -24,28 +24,24 @@ * This file is part of the TinyUSB stack. */ +#ifndef BOARD_MIMXRT1020_EVK_H_ +#define BOARD_MIMXRT1020_EVK_H_ -#ifndef BOARD_H_ -#define BOARD_H_ - -// required since iMX RT10xx SDK include this file for board size +// required since iMXRT MCUX-SDK include this file for board size #define BOARD_FLASH_SIZE (0x800000U) -// LED -#define LED_PINMUX IOMUXC_GPIO_AD_B0_05_GPIO1_IO05 -#define LED_PORT GPIO1 -#define LED_PIN 5 +// LED: IOMUXC_GPIO_AD_B0_05_GPIO1_IO05 +#define LED_PORT BOARD_INITPINS_USER_LED_PERIPHERAL +#define LED_PIN BOARD_INITPINS_USER_LED_CHANNEL #define LED_STATE_ON 0 -// SW8 button -#define BUTTON_PINMUX IOMUXC_SNVS_WAKEUP_GPIO5_IO00 -#define BUTTON_PORT GPIO5 -#define BUTTON_PIN 0 +// SW8 button: IOMUXC_SNVS_WAKEUP_GPIO5_IO00 +#define BUTTON_PORT BOARD_INITPINS_USER_BUTTON_GPIO +#define BUTTON_PIN BOARD_INITPINS_USER_BUTTON_GPIO_PIN #define BUTTON_STATE_ACTIVE 0 -// UART +// UART: IOMUXC_GPIO_AD_B0_07_LPUART1_RX, IOMUXC_GPIO_AD_B0_06_LPUART1_TX #define UART_PORT LPUART1 -#define UART_RX_PINMUX IOMUXC_GPIO_AD_B0_07_LPUART1_RX -#define UART_TX_PINMUX IOMUXC_GPIO_AD_B0_06_LPUART1_TX +#define UART_CLK_ROOT BOARD_BOOTCLOCKRUN_UART_CLK_ROOT -#endif /* BOARD_H_ */ +#endif diff --git a/hw/bsp/imxrt/boards/mimxrt1020_evk/board/pin_mux.c b/hw/bsp/imxrt/boards/mimxrt1020_evk/board/pin_mux.c new file mode 100644 index 000000000..07d910c2c --- /dev/null +++ b/hw/bsp/imxrt/boards/mimxrt1020_evk/board/pin_mux.c @@ -0,0 +1,342 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Pins v13.1 +processor: MIMXRT1021xxxxx +package_id: MIMXRT1021DAG5A +mcu_data: ksdk2_0 +processor_version: 13.0.2 +board: MIMXRT1020-EVK +external_user_signals: {} +pin_labels: +- {pin_num: '52', pin_signal: WAKEUP, label: USER_BUTTON, identifier: USER_BUTTON} +- {pin_num: '106', pin_signal: GPIO_AD_B0_05, label: 'JTAG_nTRST/J16[3]/USER_LED/J17[5]', identifier: USER_LED} +power_domains: {NVCC_GPIO: '3.3'} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +#include "fsl_common.h" +#include "fsl_iomuxc.h" +#include "fsl_gpio.h" +#include "pin_mux.h" + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitBootPins + * Description : Calls initialization functions. + * + * END ****************************************************************************************************************/ +void BOARD_InitBootPins(void) { + BOARD_InitPins(); + BOARD_InitDEBUG_UARTPins(); +} + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitPins: +- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '52', peripheral: GPIO5, signal: 'gpio_io, 00', pin_signal: WAKEUP, direction: INPUT} + - {pin_num: '106', peripheral: GPIO1, signal: 'gpio_io, 05', pin_signal: GPIO_AD_B0_05, direction: OUTPUT, pull_keeper_select: Keeper} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + CLOCK_EnableClock(kCLOCK_IomuxcSnvs); + + /* GPIO configuration of USER_LED on GPIO_AD_B0_05 (pin 106) */ + gpio_pin_config_t USER_LED_config = { + .direction = kGPIO_DigitalOutput, + .outputLogic = 0U, + .interruptMode = kGPIO_NoIntmode + }; + /* Initialize GPIO functionality on GPIO_AD_B0_05 (pin 106) */ + GPIO_PinInit(GPIO1, 5U, &USER_LED_config); + + /* GPIO configuration of USER_BUTTON on WAKEUP (pin 52) */ + gpio_pin_config_t USER_BUTTON_config = { + .direction = kGPIO_DigitalInput, + .outputLogic = 0U, + .interruptMode = kGPIO_NoIntmode + }; + /* Initialize GPIO functionality on WAKEUP (pin 52) */ + GPIO_PinInit(GPIO5, 0U, &USER_BUTTON_config); + + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_05_GPIO1_IO05, 0U); + IOMUXC_SetPinMux(IOMUXC_SNVS_WAKEUP_GPIO5_IO00, 0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_05_GPIO1_IO05, 0x50A0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitDEBUG_UARTPins: +- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '101', peripheral: LPUART1, signal: RX, pin_signal: GPIO_AD_B0_07} + - {pin_num: '105', peripheral: LPUART1, signal: TX, pin_signal: GPIO_AD_B0_06} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitDEBUG_UARTPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitDEBUG_UARTPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_06_LPUART1_TX, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_07_LPUART1_RX, 0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitSDRAMPins: +- options: {coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '142', peripheral: SEMC, signal: 'ADDR, 00', pin_signal: GPIO_EMC_16} + - {pin_num: '141', peripheral: SEMC, signal: 'ADDR, 01', pin_signal: GPIO_EMC_17} + - {pin_num: '140', peripheral: SEMC, signal: 'ADDR, 02', pin_signal: GPIO_EMC_18} + - {pin_num: '139', peripheral: SEMC, signal: 'ADDR, 03', pin_signal: GPIO_EMC_19} + - {pin_num: '138', peripheral: SEMC, signal: 'ADDR, 04', pin_signal: GPIO_EMC_20} + - {pin_num: '136', peripheral: SEMC, signal: 'ADDR, 06', pin_signal: GPIO_EMC_22} + - {pin_num: '137', peripheral: SEMC, signal: 'ADDR, 05', pin_signal: GPIO_EMC_21} + - {pin_num: '133', peripheral: SEMC, signal: 'ADDR, 07', pin_signal: GPIO_EMC_23} + - {pin_num: '132', peripheral: SEMC, signal: 'ADDR, 08', pin_signal: GPIO_EMC_24} + - {pin_num: '131', peripheral: SEMC, signal: 'ADDR, 09', pin_signal: GPIO_EMC_25} + - {pin_num: '143', peripheral: SEMC, signal: 'ADDR, 10', pin_signal: GPIO_EMC_15} + - {pin_num: '130', peripheral: SEMC, signal: 'ADDR, 11', pin_signal: GPIO_EMC_26} + - {pin_num: '129', peripheral: SEMC, signal: 'ADDR, 12', pin_signal: GPIO_EMC_27} + - {pin_num: '2', peripheral: SEMC, signal: 'BA, 0', pin_signal: GPIO_EMC_13} + - {pin_num: '1', peripheral: SEMC, signal: 'BA, 1', pin_signal: GPIO_EMC_14} + - {pin_num: '7', peripheral: SEMC, signal: semc_cas, pin_signal: GPIO_EMC_10} + - {pin_num: '127', peripheral: SEMC, signal: semc_cke, pin_signal: GPIO_EMC_29} + - {pin_num: '126', peripheral: SEMC, signal: semc_clk, pin_signal: GPIO_EMC_30} + - {pin_num: '3', peripheral: SEMC, signal: 'CS, 0', pin_signal: GPIO_EMC_12} + - {pin_num: '8', peripheral: SEMC, signal: semc_we, pin_signal: GPIO_EMC_09} + - {pin_num: '4', peripheral: SEMC, signal: semc_ras, pin_signal: GPIO_EMC_11} + - {pin_num: '128', peripheral: SEMC, signal: semc_dqs, pin_signal: GPIO_EMC_28} + - {pin_num: '125', peripheral: SEMC, signal: 'DM, 1', pin_signal: GPIO_EMC_31} + - {pin_num: '9', peripheral: SEMC, signal: 'DM, 0', pin_signal: GPIO_EMC_08} + - {pin_num: '117', peripheral: SEMC, signal: 'DATA, 15', pin_signal: GPIO_EMC_39} + - {pin_num: '118', peripheral: SEMC, signal: 'DATA, 14', pin_signal: GPIO_EMC_38} + - {pin_num: '119', peripheral: SEMC, signal: 'DATA, 13', pin_signal: GPIO_EMC_37} + - {pin_num: '120', peripheral: SEMC, signal: 'DATA, 12', pin_signal: GPIO_EMC_36} + - {pin_num: '122', peripheral: SEMC, signal: 'DATA, 10', pin_signal: GPIO_EMC_34} + - {pin_num: '121', peripheral: SEMC, signal: 'DATA, 11', pin_signal: GPIO_EMC_35} + - {pin_num: '123', peripheral: SEMC, signal: 'DATA, 09', pin_signal: GPIO_EMC_33} + - {pin_num: '124', peripheral: SEMC, signal: 'DATA, 08', pin_signal: GPIO_EMC_32} + - {pin_num: '10', peripheral: SEMC, signal: 'DATA, 07', pin_signal: GPIO_EMC_07} + - {pin_num: '12', peripheral: SEMC, signal: 'DATA, 06', pin_signal: GPIO_EMC_06} + - {pin_num: '13', peripheral: SEMC, signal: 'DATA, 05', pin_signal: GPIO_EMC_05} + - {pin_num: '14', peripheral: SEMC, signal: 'DATA, 04', pin_signal: GPIO_EMC_04} + - {pin_num: '15', peripheral: SEMC, signal: 'DATA, 03', pin_signal: GPIO_EMC_03} + - {pin_num: '16', peripheral: SEMC, signal: 'DATA, 02', pin_signal: GPIO_EMC_02} + - {pin_num: '17', peripheral: SEMC, signal: 'DATA, 01', pin_signal: GPIO_EMC_01} + - {pin_num: '18', peripheral: SEMC, signal: 'DATA, 00', pin_signal: GPIO_EMC_00} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitSDRAMPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitSDRAMPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_00_SEMC_DATA00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_01_SEMC_DATA01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_02_SEMC_DATA02, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_03_SEMC_DATA03, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_04_SEMC_DATA04, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_05_SEMC_DATA05, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_06_SEMC_DATA06, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_07_SEMC_DATA07, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_08_SEMC_DM00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_09_SEMC_WE, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_10_SEMC_CAS, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_11_SEMC_RAS, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_12_SEMC_CS0, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_13_SEMC_BA0, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_14_SEMC_BA1, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_15_SEMC_ADDR10, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_16_SEMC_ADDR00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_17_SEMC_ADDR01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_18_SEMC_ADDR02, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_19_SEMC_ADDR03, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_20_SEMC_ADDR04, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_21_SEMC_ADDR05, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_22_SEMC_ADDR06, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_23_SEMC_ADDR07, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_24_SEMC_ADDR08, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_25_SEMC_ADDR09, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_26_SEMC_ADDR11, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_27_SEMC_ADDR12, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_28_SEMC_DQS, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_29_SEMC_CKE, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_30_SEMC_CLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_31_SEMC_DM01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_32_SEMC_DATA08, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_33_SEMC_DATA09, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_34_SEMC_DATA10, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_35_SEMC_DATA11, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_36_SEMC_DATA12, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_37_SEMC_DATA13, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_38_SEMC_DATA14, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_39_SEMC_DATA15, 0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitCANPins: +- options: {coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '32', peripheral: CAN1, signal: RX, pin_signal: GPIO_SD_B1_01} + - {pin_num: '33', peripheral: CAN1, signal: TX, pin_signal: GPIO_SD_B1_00} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitCANPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitCANPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_00_FLEXCAN1_TX, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_01_FLEXCAN1_RX, 0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitENETPins: +- options: {coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '97', peripheral: ENET, signal: enet_rx_en, pin_signal: GPIO_AD_B0_11} + - {pin_num: '84', peripheral: GPIO1, signal: 'gpio_io, 22', pin_signal: GPIO_AD_B1_06} + - {pin_num: '107', peripheral: GPIO1, signal: 'gpio_io, 04', pin_signal: GPIO_AD_B0_04} + - {pin_num: '100', peripheral: ENET, signal: enet_tx_clk, pin_signal: GPIO_AD_B0_08} + - {pin_num: '95', peripheral: ENET, signal: enet_tx_en, pin_signal: GPIO_AD_B0_13} + - {pin_num: '93', peripheral: ENET, signal: 'enet_tx_data, 1', pin_signal: GPIO_AD_B0_15} + - {pin_num: '94', peripheral: ENET, signal: 'enet_tx_data, 0', pin_signal: GPIO_AD_B0_14} + - {pin_num: '96', peripheral: ENET, signal: enet_rx_er, pin_signal: GPIO_AD_B0_12} + - {pin_num: '99', peripheral: ENET, signal: 'enet_rx_data, 1', pin_signal: GPIO_AD_B0_09} + - {pin_num: '98', peripheral: ENET, signal: 'enet_rx_data, 0', pin_signal: GPIO_AD_B0_10} + - {pin_num: '116', peripheral: ENET, signal: enet_mdio, pin_signal: GPIO_EMC_40} + - {pin_num: '115', peripheral: ENET, signal: enet_mdc, pin_signal: GPIO_EMC_41} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitENETPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitENETPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_04_GPIO1_IO04, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_08_ENET_TX_CLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_09_ENET_RDATA01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_10_ENET_RDATA00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_11_ENET_RX_EN, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_12_ENET_RX_ER, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_13_ENET_TX_EN, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_14_ENET_TDATA00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_15_ENET_TDATA01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_06_GPIO1_IO22, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_40_ENET_MDIO, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_41_ENET_MDC, 0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitUSDHCPins: +- options: {coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '45', peripheral: USDHC1, signal: usdhc_clk, pin_signal: GPIO_SD_B0_03} + - {pin_num: '46', peripheral: USDHC1, signal: usdhc_cmd, pin_signal: GPIO_SD_B0_02} + - {pin_num: '43', peripheral: USDHC1, signal: 'usdhc_data, 0', pin_signal: GPIO_SD_B0_04} + - {pin_num: '42', peripheral: USDHC1, signal: 'usdhc_data, 1', pin_signal: GPIO_SD_B0_05} + - {pin_num: '48', peripheral: USDHC1, signal: 'usdhc_data, 2', pin_signal: GPIO_SD_B0_00} + - {pin_num: '47', peripheral: USDHC1, signal: 'usdhc_data, 3', pin_signal: GPIO_SD_B0_01} + - {pin_num: '41', peripheral: GPIO3, signal: 'gpio_io, 19', pin_signal: GPIO_SD_B0_06} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitUSDHCPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitUSDHCPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_00_USDHC1_DATA2, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_01_USDHC1_DATA3, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_02_USDHC1_CMD, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_03_USDHC1_CLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_04_USDHC1_DATA0, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_05_USDHC1_DATA1, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_06_GPIO3_IO19, 0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitQSPIPins: +- options: {coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '24', peripheral: FLEXSPI, signal: FLEXSPI_A_SCLK, pin_signal: GPIO_SD_B1_07} + - {pin_num: '23', peripheral: FLEXSPI, signal: FLEXSPI_A_DATA0, pin_signal: GPIO_SD_B1_08} + - {pin_num: '21', peripheral: FLEXSPI, signal: FLEXSPI_A_DATA1, pin_signal: GPIO_SD_B1_10} + - {pin_num: '22', peripheral: FLEXSPI, signal: FLEXSPI_A_DATA2, pin_signal: GPIO_SD_B1_09} + - {pin_num: '25', peripheral: FLEXSPI, signal: FLEXSPI_A_DATA3, pin_signal: GPIO_SD_B1_06} + - {pin_num: '19', peripheral: FLEXSPI, signal: FLEXSPI_A_SS0_B, pin_signal: GPIO_SD_B1_11} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitQSPIPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitQSPIPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_06_FLEXSPI_A_DATA03, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_07_FLEXSPI_A_SCLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_08_FLEXSPI_A_DATA00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_09_FLEXSPI_A_DATA02, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_10_FLEXSPI_A_DATA01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_11_FLEXSPI_A_SS0_B, 0U); +} + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/imxrt/boards/mimxrt1020_evk/board/pin_mux.h b/hw/bsp/imxrt/boards/mimxrt1020_evk/board/pin_mux.h new file mode 100644 index 000000000..4155c56ec --- /dev/null +++ b/hw/bsp/imxrt/boards/mimxrt1020_evk/board/pin_mux.h @@ -0,0 +1,542 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _PIN_MUX_H_ +#define _PIN_MUX_H_ + +/*********************************************************************************************************************** + * Definitions + **********************************************************************************************************************/ + +/*! @brief Direction type */ +typedef enum _pin_mux_direction +{ + kPIN_MUX_DirectionInput = 0U, /* Input direction */ + kPIN_MUX_DirectionOutput = 1U, /* Output direction */ + kPIN_MUX_DirectionInputOrOutput = 2U /* Input or output direction */ +} pin_mux_direction_t; + +/*! + * @addtogroup pin_mux + * @{ + */ + +/*********************************************************************************************************************** + * API + **********************************************************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Calls initialization functions. + * + */ +void BOARD_InitBootPins(void); + +/* WAKEUP (number 52), USER_BUTTON */ +/* Routed pin properties */ +#define BOARD_INITPINS_USER_BUTTON_PERIPHERAL GPIO5 /*!< Peripheral name */ +#define BOARD_INITPINS_USER_BUTTON_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITPINS_USER_BUTTON_CHANNEL 0U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_USER_BUTTON_GPIO GPIO5 /*!< GPIO peripheral base pointer */ +#define BOARD_INITPINS_USER_BUTTON_GPIO_PIN 0U /*!< GPIO pin number */ +#define BOARD_INITPINS_USER_BUTTON_GPIO_PIN_MASK (1U << 0U) /*!< GPIO pin mask */ +#define BOARD_INITPINS_USER_BUTTON_PORT GPIO5 /*!< PORT peripheral base pointer */ +#define BOARD_INITPINS_USER_BUTTON_PIN 0U /*!< PORT pin number */ +#define BOARD_INITPINS_USER_BUTTON_PIN_MASK (1U << 0U) /*!< PORT pin mask */ + +/* GPIO_AD_B0_05 (number 106), JTAG_nTRST/J16[3]/USER_LED/J17[5] */ +/* Routed pin properties */ +#define BOARD_INITPINS_USER_LED_PERIPHERAL GPIO1 /*!< Peripheral name */ +#define BOARD_INITPINS_USER_LED_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITPINS_USER_LED_CHANNEL 5U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_USER_LED_GPIO GPIO1 /*!< GPIO peripheral base pointer */ +#define BOARD_INITPINS_USER_LED_GPIO_PIN 5U /*!< GPIO pin number */ +#define BOARD_INITPINS_USER_LED_GPIO_PIN_MASK (1U << 5U) /*!< GPIO pin mask */ +#define BOARD_INITPINS_USER_LED_PORT GPIO1 /*!< PORT peripheral base pointer */ +#define BOARD_INITPINS_USER_LED_PIN 5U /*!< PORT pin number */ +#define BOARD_INITPINS_USER_LED_PIN_MASK (1U << 5U) /*!< PORT pin mask */ + + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitPins(void); + +/* GPIO_AD_B0_07 (number 101), UART1_RXD/J17[4] */ +/* Routed pin properties */ +#define BOARD_INITDEBUG_UARTPINS_UART1_RXD_PERIPHERAL LPUART1 /*!< Peripheral name */ +#define BOARD_INITDEBUG_UARTPINS_UART1_RXD_SIGNAL RX /*!< Signal name */ + +/* GPIO_AD_B0_06 (number 105), UART1_TXD/J17[6] */ +/* Routed pin properties */ +#define BOARD_INITDEBUG_UARTPINS_UART1_TXD_PERIPHERAL LPUART1 /*!< Peripheral name */ +#define BOARD_INITDEBUG_UARTPINS_UART1_TXD_SIGNAL TX /*!< Signal name */ + + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitDEBUG_UARTPins(void); + +/* GPIO_EMC_16 (number 142), SEMC_A0/U14[23]/BOOT_MODE[0] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A0_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A0_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_EMC_17 (number 141), SEMC_A1/U14[24]/BOOT_MODE[1] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A1_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A1_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_EMC_18 (number 140), SEMC_A2/U14[25]/BT_CFG[0] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A2_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A2_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A2_CHANNEL 2U /*!< Signal channel */ + +/* GPIO_EMC_19 (number 139), SEMC_A3/U14[26]/BT_CFG[1] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A3_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A3_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A3_CHANNEL 3U /*!< Signal channel */ + +/* GPIO_EMC_20 (number 138), SEMC_A4/U14[29]/BT_CFG[2] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A4_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A4_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A4_CHANNEL 4U /*!< Signal channel */ + +/* GPIO_EMC_22 (number 136), SEMC_A6/U14[31]/BT_CFG[4] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A6_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A6_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A6_CHANNEL 6U /*!< Signal channel */ + +/* GPIO_EMC_21 (number 137), SEMC_A5/U14[30]/BT_CFG[3] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A5_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A5_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A5_CHANNEL 5U /*!< Signal channel */ + +/* GPIO_EMC_23 (number 133), SEMC_A7/U14[32]/BT_CFG[5] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A7_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A7_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A7_CHANNEL 7U /*!< Signal channel */ + +/* GPIO_EMC_24 (number 132), SEMC_A8/U14[33]/BT_CFG[6] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A8_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A8_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A8_CHANNEL 8U /*!< Signal channel */ + +/* GPIO_EMC_25 (number 131), SEMC_A9/U14[34]/BT_CFG[7] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A9_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A9_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A9_CHANNEL 9U /*!< Signal channel */ + +/* GPIO_EMC_15 (number 143), SEMC_A10/U14[22] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A10_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A10_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A10_CHANNEL 10U /*!< Signal channel */ + +/* GPIO_EMC_26 (number 130), SEMC_A11/U14[35]/BT_CFG[8] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A11_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A11_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A11_CHANNEL 11U /*!< Signal channel */ + +/* GPIO_EMC_27 (number 129), SEMC_A12/U14[36]/BT_CFG[9] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A12_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A12_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A12_CHANNEL 12U /*!< Signal channel */ + +/* GPIO_EMC_13 (number 2), SEMC_BA0/U14[20] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_BA0_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_BA0_SIGNAL BA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_BA0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_EMC_14 (number 1), SEMC_BA1/U14[21] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_BA1_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_BA1_SIGNAL BA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_BA1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_EMC_10 (number 7), SEMC_CAS/U14[17] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_CAS_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_CAS_SIGNAL semc_cas /*!< Signal name */ + +/* GPIO_EMC_29 (number 127), SEMC_CKE/U14[37] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_CKE_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_CKE_SIGNAL semc_cke /*!< Signal name */ + +/* GPIO_EMC_30 (number 126), SEMC_CLK/U14[38] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_CLK_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_CLK_SIGNAL semc_clk /*!< Signal name */ + +/* GPIO_EMC_12 (number 3), SEMC_CS0/U14[19] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_CS0_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_CS0_SIGNAL CS /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_CS0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_EMC_09 (number 8), SEMC_WE/U14[16] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_WE_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_WE_SIGNAL semc_we /*!< Signal name */ + +/* GPIO_EMC_11 (number 4), SEMC_RAS/U14[18] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_RAS_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_RAS_SIGNAL semc_ras /*!< Signal name */ + +/* GPIO_EMC_28 (number 128), SEMC_DQS */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_DQS_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_DQS_SIGNAL semc_dqs /*!< Signal name */ + +/* GPIO_EMC_31 (number 125), SEMC_DM1/U14[39] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_DM1_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_DM1_SIGNAL DM /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_DM1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_EMC_08 (number 9), SEMC_DM0/U14[15] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_DM0_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_DM0_SIGNAL DM /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_DM0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_EMC_39 (number 117), SEMC_D15/U14[53] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D15_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D15_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D15_CHANNEL 15U /*!< Signal channel */ + +/* GPIO_EMC_38 (number 118), SEMC_D14/U14[51] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D14_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D14_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D14_CHANNEL 14U /*!< Signal channel */ + +/* GPIO_EMC_37 (number 119), SEMC_D13/U14[50] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D13_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D13_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D13_CHANNEL 13U /*!< Signal channel */ + +/* GPIO_EMC_36 (number 120), SEMC_D12/U14[48] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D12_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D12_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D12_CHANNEL 12U /*!< Signal channel */ + +/* GPIO_EMC_34 (number 122), SEMC_D10/U14[45] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D10_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D10_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D10_CHANNEL 10U /*!< Signal channel */ + +/* GPIO_EMC_35 (number 121), SEMC_D11/U14[47] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D11_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D11_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D11_CHANNEL 11U /*!< Signal channel */ + +/* GPIO_EMC_33 (number 123), SEMC_D9/U14[44] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D9_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D9_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D9_CHANNEL 9U /*!< Signal channel */ + +/* GPIO_EMC_32 (number 124), SEMC_D8/U14[42] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D8_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D8_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D8_CHANNEL 8U /*!< Signal channel */ + +/* GPIO_EMC_07 (number 10), SEMC_D7/U14[13] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D7_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D7_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D7_CHANNEL 7U /*!< Signal channel */ + +/* GPIO_EMC_06 (number 12), SEMC_D6/U14[11] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D6_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D6_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D6_CHANNEL 6U /*!< Signal channel */ + +/* GPIO_EMC_05 (number 13), SEMC_D5/U14[10] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D5_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D5_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D5_CHANNEL 5U /*!< Signal channel */ + +/* GPIO_EMC_04 (number 14), SEMC_D4/U14[8] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D4_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D4_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D4_CHANNEL 4U /*!< Signal channel */ + +/* GPIO_EMC_03 (number 15), SEMC_D3/U14[7] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D3_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D3_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D3_CHANNEL 3U /*!< Signal channel */ + +/* GPIO_EMC_02 (number 16), SEMC_D2/U14[5] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D2_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D2_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D2_CHANNEL 2U /*!< Signal channel */ + +/* GPIO_EMC_01 (number 17), SEMC_D1/U14[4] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D1_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D1_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_EMC_00 (number 18), SEMC_D0/U14[2] */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D0_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D0_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D0_CHANNEL 0U /*!< Signal channel */ + + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitSDRAMPins(void); + +/* GPIO_SD_B1_01 (number 32), CAN1_RX/U9[4] */ +/* Routed pin properties */ +#define BOARD_INITCANPINS_CAN1_RX_PERIPHERAL CAN1 /*!< Peripheral name */ +#define BOARD_INITCANPINS_CAN1_RX_SIGNAL RX /*!< Signal name */ + +/* GPIO_SD_B1_00 (number 33), CAN1_TX/U9[1] */ +/* Routed pin properties */ +#define BOARD_INITCANPINS_CAN1_TX_PERIPHERAL CAN1 /*!< Peripheral name */ +#define BOARD_INITCANPINS_CAN1_TX_SIGNAL TX /*!< Signal name */ + + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitCANPins(void); + +/* GPIO_AD_B0_11 (number 97), ENET_CRS_DV/U11[18]/J19[3] */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_CRS_DV_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_CRS_DV_SIGNAL enet_rx_en /*!< Signal name */ + +/* GPIO_AD_B1_06 (number 84), ENET_INT/U11[21]/J17[8] */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_INT_PERIPHERAL GPIO1 /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_INT_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITENETPINS_ENET_INT_CHANNEL 22U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITENETPINS_ENET_INT_GPIO GPIO1 /*!< GPIO peripheral base pointer */ +#define BOARD_INITENETPINS_ENET_INT_GPIO_PIN 22U /*!< GPIO pin number */ +#define BOARD_INITENETPINS_ENET_INT_GPIO_PIN_MASK (1U << 22U) /*!< GPIO pin mask */ +#define BOARD_INITENETPINS_ENET_INT_PORT GPIO1 /*!< PORT peripheral base pointer */ +#define BOARD_INITENETPINS_ENET_INT_PIN 22U /*!< PORT pin number */ +#define BOARD_INITENETPINS_ENET_INT_PIN_MASK (1U << 22U) /*!< PORT pin mask */ + +/* GPIO_AD_B0_04 (number 107), JTAG_TDO/J16[13]/ENET_RST/U11[32] */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_RST_PERIPHERAL GPIO1 /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_RST_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITENETPINS_ENET_RST_CHANNEL 4U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITENETPINS_ENET_RST_GPIO GPIO1 /*!< GPIO peripheral base pointer */ +#define BOARD_INITENETPINS_ENET_RST_GPIO_PIN 4U /*!< GPIO pin number */ +#define BOARD_INITENETPINS_ENET_RST_GPIO_PIN_MASK (1U << 4U) /*!< GPIO pin mask */ +#define BOARD_INITENETPINS_ENET_RST_PORT GPIO1 /*!< PORT peripheral base pointer */ +#define BOARD_INITENETPINS_ENET_RST_PIN 4U /*!< PORT pin number */ +#define BOARD_INITENETPINS_ENET_RST_PIN_MASK (1U << 4U) /*!< PORT pin mask */ + +/* GPIO_AD_B0_08 (number 100), ENET_TX_CLK/U11[9] */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_TX_CLK_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_TX_CLK_SIGNAL enet_tx_clk /*!< Signal name */ + +/* GPIO_AD_B0_13 (number 95), ENET_TXEN/U11[23]/J19[5] */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_TXEN_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_TXEN_SIGNAL enet_tx_en /*!< Signal name */ + +/* GPIO_AD_B0_15 (number 93), ENET_TXD1/U11[25]/J19[2] */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_TXD1_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_TXD1_SIGNAL enet_tx_data /*!< Signal name */ +#define BOARD_INITENETPINS_ENET_TXD1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_AD_B0_14 (number 94), ENET_TXD0/U11[24]/J17[7] */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_TXD0_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_TXD0_SIGNAL enet_tx_data /*!< Signal name */ +#define BOARD_INITENETPINS_ENET_TXD0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_AD_B0_12 (number 96), ENET_RXER/U11[20]/J19[4] */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_RXER_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_RXER_SIGNAL enet_rx_er /*!< Signal name */ + +/* GPIO_AD_B0_09 (number 99), ENET_RXD1/U11[15]/J17[3] */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_RXD1_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_RXD1_SIGNAL enet_rx_data /*!< Signal name */ +#define BOARD_INITENETPINS_ENET_RXD1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_AD_B0_10 (number 98), ENET_RXD0/U11[16]/J19[6] */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_RXD0_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_RXD0_SIGNAL enet_rx_data /*!< Signal name */ +#define BOARD_INITENETPINS_ENET_RXD0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_EMC_40 (number 116), ENET_MDIO/U11[11] */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_MDIO_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_MDIO_SIGNAL enet_mdio /*!< Signal name */ + +/* GPIO_EMC_41 (number 115), ENET_MDC/U11[12] */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_MDC_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_MDC_SIGNAL enet_mdc /*!< Signal name */ + + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitENETPins(void); + +/* GPIO_SD_B0_03 (number 45), SD1_CLK/J15[5] */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_CLK_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_CLK_SIGNAL usdhc_clk /*!< Signal name */ + +/* GPIO_SD_B0_02 (number 46), SD1_CMD/J15[3] */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_CMD_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_CMD_SIGNAL usdhc_cmd /*!< Signal name */ + +/* GPIO_SD_B0_04 (number 43), SD1_D0/J15[7] */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_D0_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_D0_SIGNAL usdhc_data /*!< Signal name */ +#define BOARD_INITUSDHCPINS_SD1_D0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_SD_B0_05 (number 42), SD1_D1/J15[8] */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_D1_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_D1_SIGNAL usdhc_data /*!< Signal name */ +#define BOARD_INITUSDHCPINS_SD1_D1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_SD_B0_00 (number 48), SD1_D2/J15[1] */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_D2_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_D2_SIGNAL usdhc_data /*!< Signal name */ +#define BOARD_INITUSDHCPINS_SD1_D2_CHANNEL 2U /*!< Signal channel */ + +/* GPIO_SD_B0_01 (number 47), SD1_D3/J15[2] */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_D3_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_D3_SIGNAL usdhc_data /*!< Signal name */ +#define BOARD_INITUSDHCPINS_SD1_D3_CHANNEL 3U /*!< Signal channel */ + +/* GPIO_SD_B0_06 (number 41), SD_CD_SW/J15[9] */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD_CD_SW_PERIPHERAL GPIO3 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD_CD_SW_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITUSDHCPINS_SD_CD_SW_CHANNEL 19U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITUSDHCPINS_SD_CD_SW_GPIO GPIO3 /*!< GPIO peripheral base pointer */ +#define BOARD_INITUSDHCPINS_SD_CD_SW_GPIO_PIN 19U /*!< GPIO pin number */ +#define BOARD_INITUSDHCPINS_SD_CD_SW_GPIO_PIN_MASK (1U << 19U) /*!< GPIO pin mask */ +#define BOARD_INITUSDHCPINS_SD_CD_SW_PORT GPIO3 /*!< PORT peripheral base pointer */ +#define BOARD_INITUSDHCPINS_SD_CD_SW_PIN 19U /*!< PORT pin number */ +#define BOARD_INITUSDHCPINS_SD_CD_SW_PIN_MASK (1U << 19U) /*!< PORT pin mask */ + + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitUSDHCPins(void); + +/* GPIO_SD_B1_07 (number 24), FlexSPI_CLK/U13[6] */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_CLK_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_CLK_SIGNAL FLEXSPI_A_SCLK /*!< Signal name */ + +/* GPIO_SD_B1_08 (number 23), FlexSPI_D0_A/U13[5] */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_D0_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_D0_A_SIGNAL FLEXSPI_A_DATA0 /*!< Signal name */ + +/* GPIO_SD_B1_10 (number 21), FlexSPI_D1_A/U13[2] */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_D1_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_D1_A_SIGNAL FLEXSPI_A_DATA1 /*!< Signal name */ + +/* GPIO_SD_B1_09 (number 22), FlexSPI_D2_A/U13[3] */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_D2_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_D2_A_SIGNAL FLEXSPI_A_DATA2 /*!< Signal name */ + +/* GPIO_SD_B1_06 (number 25), FlexSPI_D3_A/U13[7] */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_D3_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_D3_A_SIGNAL FLEXSPI_A_DATA3 /*!< Signal name */ + +/* GPIO_SD_B1_11 (number 19), FlexSPI_SS0/U13[1] */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_SS0_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_SS0_SIGNAL FLEXSPI_A_SS0_B /*!< Signal name */ + + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitQSPIPins(void); + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif /* _PIN_MUX_H_ */ + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/imxrt/boards/mimxrt1020_evk/mimxrt1020_evk.mex b/hw/bsp/imxrt/boards/mimxrt1020_evk/mimxrt1020_evk.mex index 4ddaaed77..4437a420e 100644 --- a/hw/bsp/imxrt/boards/mimxrt1020_evk/mimxrt1020_evk.mex +++ b/hw/bsp/imxrt/boards/mimxrt1020_evk/mimxrt1020_evk.mex @@ -26,6 +26,10 @@ 13.0.2 + + + + @@ -42,13 +46,40 @@ true + + + true + + true + + + true + + + + + true + + - + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. diff --git a/hw/bsp/imxrt/boards/mimxrt1024_evk/board.h b/hw/bsp/imxrt/boards/mimxrt1024_evk/board.h index 9100072e2..27a64b464 100644 --- a/hw/bsp/imxrt/boards/mimxrt1024_evk/board.h +++ b/hw/bsp/imxrt/boards/mimxrt1024_evk/board.h @@ -24,29 +24,25 @@ * This file is part of the TinyUSB stack. */ +#ifndef BOARD_MIMXRT1024_EVK_H_ +#define BOARD_MIMXRT1024_EVK_H_ -#ifndef BOARD_H_ -#define BOARD_H_ - -// required since iMX RT10xx SDK include this file for board size +// required since iMXRT MCUX-SDK include this file for board size // RT1020-EVK #define BOARD_FLASH_SIZE (0x800000U) #define BOARD_FLASH_SIZE (0x400000U) // builtin flash of RT1024 -// LED - DRN updated for RT1024EVK -#define LED_PINMUX IOMUXC_GPIO_AD_B1_08_GPIO1_IO24 -#define LED_PORT GPIO1 -#define LED_PIN 24 +// LED: IOMUXC_GPIO_AD_B1_08_GPIO1_IO24 +#define LED_PORT BOARD_INITPINS_USER_LED_GPIO +#define LED_PIN BOARD_INITPINS_USER_LED_PIN #define LED_STATE_ON 1 -// SW8 button - DRN verified -#define BUTTON_PINMUX IOMUXC_SNVS_WAKEUP_GPIO5_IO00 -#define BUTTON_PORT GPIO5 -#define BUTTON_PIN 0 +// SW8 button: IOMUXC_SNVS_WAKEUP_GPIO5_IO00 +#define BUTTON_PORT BOARD_INITPINS_USER_BUTTON_GPIO +#define BUTTON_PIN BOARD_INITPINS_USER_BUTTON_PIN #define BUTTON_STATE_ACTIVE 0 -// UART - DRN verified +// UART: IOMUXC_GPIO_AD_B0_07_LPUART1_RX, IOMUXC_GPIO_AD_B0_06_LPUART1_TX #define UART_PORT LPUART1 -#define UART_RX_PINMUX IOMUXC_GPIO_AD_B0_07_LPUART1_RX -#define UART_TX_PINMUX IOMUXC_GPIO_AD_B0_06_LPUART1_TX +#define UART_CLK_ROOT BOARD_BOOTCLOCKRUN_UART_CLK_ROOT -#endif /* BOARD_H_ */ +#endif diff --git a/hw/bsp/imxrt/boards/mimxrt1024_evk/board/pin_mux.c b/hw/bsp/imxrt/boards/mimxrt1024_evk/board/pin_mux.c new file mode 100644 index 000000000..29a9d8d3d --- /dev/null +++ b/hw/bsp/imxrt/boards/mimxrt1024_evk/board/pin_mux.c @@ -0,0 +1,490 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Pins v13.1 +processor: MIMXRT1024xxxxx +package_id: MIMXRT1024DAG5A +mcu_data: ksdk2_0 +processor_version: 13.0.2 +board: MIMXRT1024-EVK +pin_labels: +- {pin_num: '52', pin_signal: WAKEUP, label: USER_BUTTON, identifier: USER_BUTTON} +- {pin_num: '82', pin_signal: GPIO_AD_B1_08, label: 'UART_TX/USER_LED/J17[4]', identifier: USER_LED} +power_domains: {NVCC_GPIO: '3.3'} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +#include "fsl_common.h" +#include "fsl_iomuxc.h" +#include "fsl_gpio.h" +#include "pin_mux.h" + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitBootPins + * Description : Calls initialization functions. + * + * END ****************************************************************************************************************/ +void BOARD_InitBootPins(void) { + BOARD_InitPins(); + BOARD_InitDEBUG_UARTPins(); + +/* GPIO_AD_B1_00~GPIO_AD_B1_05 can only be configured as flexspi function. Note that it can't be modified here */ + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_00_FLEXSPI_A_DATA03,1U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_01_FLEXSPI_A_SCLK,1U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_02_FLEXSPI_A_DATA00,1U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_03_FLEXSPI_A_DATA02,1U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_04_FLEXSPI_A_DATA01,1U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_05_FLEXSPI_A_SS0_B,1U); +} + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitPins: +- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '52', peripheral: GPIO5, signal: 'gpio_io, 00', pin_signal: WAKEUP, direction: INPUT} + - {pin_num: '82', peripheral: GPIO1, signal: 'gpio_io, 24', pin_signal: GPIO_AD_B1_08, direction: OUTPUT} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03U */ + CLOCK_EnableClock(kCLOCK_IomuxcSnvs); /* iomuxc_snvs clock (iomuxc_snvs_clk_enable): 0x03U */ + + /* GPIO configuration of USER_LED on GPIO_AD_B1_08 (pin 82) */ + gpio_pin_config_t USER_LED_config = { + .direction = kGPIO_DigitalOutput, + .outputLogic = 0U, + .interruptMode = kGPIO_NoIntmode + }; + /* Initialize GPIO functionality on GPIO_AD_B1_08 (pin 82) */ + GPIO_PinInit(GPIO1, 24U, &USER_LED_config); + + /* GPIO configuration of USER_BUTTON on WAKEUP (pin 52) */ + gpio_pin_config_t USER_BUTTON_config = { + .direction = kGPIO_DigitalInput, + .outputLogic = 0U, + .interruptMode = kGPIO_NoIntmode + }; + /* Initialize GPIO functionality on WAKEUP (pin 52) */ + GPIO_PinInit(GPIO5, 0U, &USER_BUTTON_config); + + IOMUXC_SetPinMux( + IOMUXC_GPIO_AD_B1_08_GPIO1_IO24, /* GPIO_AD_B1_08 is configured as GPIO1_IO24 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_SNVS_WAKEUP_GPIO5_IO00, /* WAKEUP is configured as GPIO5_IO00 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitDEBUG_UARTPins: +- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '101', peripheral: LPUART1, signal: RX, pin_signal: GPIO_AD_B0_07} + - {pin_num: '105', peripheral: LPUART1, signal: TX, pin_signal: GPIO_AD_B0_06} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitDEBUG_UARTPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitDEBUG_UARTPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03U */ + + IOMUXC_SetPinMux( + IOMUXC_GPIO_AD_B0_06_LPUART1_TX, /* GPIO_AD_B0_06 is configured as LPUART1_TX */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_AD_B0_07_LPUART1_RX, /* GPIO_AD_B0_07 is configured as LPUART1_RX */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitSDRAMPins: +- options: {coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '142', peripheral: SEMC, signal: 'ADDR, 00', pin_signal: GPIO_EMC_16} + - {pin_num: '141', peripheral: SEMC, signal: 'ADDR, 01', pin_signal: GPIO_EMC_17} + - {pin_num: '140', peripheral: SEMC, signal: 'ADDR, 02', pin_signal: GPIO_EMC_18} + - {pin_num: '139', peripheral: SEMC, signal: 'ADDR, 03', pin_signal: GPIO_EMC_19} + - {pin_num: '138', peripheral: SEMC, signal: 'ADDR, 04', pin_signal: GPIO_EMC_20} + - {pin_num: '136', peripheral: SEMC, signal: 'ADDR, 06', pin_signal: GPIO_EMC_22} + - {pin_num: '137', peripheral: SEMC, signal: 'ADDR, 05', pin_signal: GPIO_EMC_21} + - {pin_num: '133', peripheral: SEMC, signal: 'ADDR, 07', pin_signal: GPIO_EMC_23} + - {pin_num: '132', peripheral: SEMC, signal: 'ADDR, 08', pin_signal: GPIO_EMC_24} + - {pin_num: '131', peripheral: SEMC, signal: 'ADDR, 09', pin_signal: GPIO_EMC_25} + - {pin_num: '143', peripheral: SEMC, signal: 'ADDR, 10', pin_signal: GPIO_EMC_15} + - {pin_num: '130', peripheral: SEMC, signal: 'ADDR, 11', pin_signal: GPIO_EMC_26} + - {pin_num: '129', peripheral: SEMC, signal: 'ADDR, 12', pin_signal: GPIO_EMC_27} + - {pin_num: '2', peripheral: SEMC, signal: 'BA, 0', pin_signal: GPIO_EMC_13} + - {pin_num: '1', peripheral: SEMC, signal: 'BA, 1', pin_signal: GPIO_EMC_14} + - {pin_num: '7', peripheral: SEMC, signal: semc_cas, pin_signal: GPIO_EMC_10} + - {pin_num: '127', peripheral: SEMC, signal: semc_cke, pin_signal: GPIO_EMC_29} + - {pin_num: '126', peripheral: SEMC, signal: semc_clk, pin_signal: GPIO_EMC_30} + - {pin_num: '3', peripheral: SEMC, signal: 'CS, 0', pin_signal: GPIO_EMC_12} + - {pin_num: '8', peripheral: SEMC, signal: semc_we, pin_signal: GPIO_EMC_09} + - {pin_num: '4', peripheral: SEMC, signal: semc_ras, pin_signal: GPIO_EMC_11} + - {pin_num: '128', peripheral: SEMC, signal: semc_dqs, pin_signal: GPIO_EMC_28} + - {pin_num: '125', peripheral: SEMC, signal: 'DM, 1', pin_signal: GPIO_EMC_31} + - {pin_num: '9', peripheral: SEMC, signal: 'DM, 0', pin_signal: GPIO_EMC_08} + - {pin_num: '117', peripheral: SEMC, signal: 'DATA, 15', pin_signal: GPIO_EMC_39} + - {pin_num: '118', peripheral: SEMC, signal: 'DATA, 14', pin_signal: GPIO_EMC_38} + - {pin_num: '119', peripheral: SEMC, signal: 'DATA, 13', pin_signal: GPIO_EMC_37} + - {pin_num: '120', peripheral: SEMC, signal: 'DATA, 12', pin_signal: GPIO_EMC_36} + - {pin_num: '122', peripheral: SEMC, signal: 'DATA, 10', pin_signal: GPIO_EMC_34} + - {pin_num: '121', peripheral: SEMC, signal: 'DATA, 11', pin_signal: GPIO_EMC_35} + - {pin_num: '123', peripheral: SEMC, signal: 'DATA, 09', pin_signal: GPIO_EMC_33} + - {pin_num: '124', peripheral: SEMC, signal: 'DATA, 08', pin_signal: GPIO_EMC_32} + - {pin_num: '10', peripheral: SEMC, signal: 'DATA, 07', pin_signal: GPIO_EMC_07} + - {pin_num: '12', peripheral: SEMC, signal: 'DATA, 06', pin_signal: GPIO_EMC_06} + - {pin_num: '13', peripheral: SEMC, signal: 'DATA, 05', pin_signal: GPIO_EMC_05} + - {pin_num: '14', peripheral: SEMC, signal: 'DATA, 04', pin_signal: GPIO_EMC_04} + - {pin_num: '15', peripheral: SEMC, signal: 'DATA, 03', pin_signal: GPIO_EMC_03} + - {pin_num: '16', peripheral: SEMC, signal: 'DATA, 02', pin_signal: GPIO_EMC_02} + - {pin_num: '17', peripheral: SEMC, signal: 'DATA, 01', pin_signal: GPIO_EMC_01} + - {pin_num: '18', peripheral: SEMC, signal: 'DATA, 00', pin_signal: GPIO_EMC_00} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitSDRAMPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitSDRAMPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03U */ + + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_00_SEMC_DATA00, /* GPIO_EMC_00 is configured as SEMC_DATA00 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_01_SEMC_DATA01, /* GPIO_EMC_01 is configured as SEMC_DATA01 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_02_SEMC_DATA02, /* GPIO_EMC_02 is configured as SEMC_DATA02 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_03_SEMC_DATA03, /* GPIO_EMC_03 is configured as SEMC_DATA03 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_04_SEMC_DATA04, /* GPIO_EMC_04 is configured as SEMC_DATA04 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_05_SEMC_DATA05, /* GPIO_EMC_05 is configured as SEMC_DATA05 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_06_SEMC_DATA06, /* GPIO_EMC_06 is configured as SEMC_DATA06 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_07_SEMC_DATA07, /* GPIO_EMC_07 is configured as SEMC_DATA07 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_08_SEMC_DM00, /* GPIO_EMC_08 is configured as SEMC_DM00 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_09_SEMC_WE, /* GPIO_EMC_09 is configured as SEMC_WE */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_10_SEMC_CAS, /* GPIO_EMC_10 is configured as SEMC_CAS */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_11_SEMC_RAS, /* GPIO_EMC_11 is configured as SEMC_RAS */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_12_SEMC_CS0, /* GPIO_EMC_12 is configured as SEMC_CS0 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_13_SEMC_BA0, /* GPIO_EMC_13 is configured as SEMC_BA0 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_14_SEMC_BA1, /* GPIO_EMC_14 is configured as SEMC_BA1 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_15_SEMC_ADDR10, /* GPIO_EMC_15 is configured as SEMC_ADDR10 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_16_SEMC_ADDR00, /* GPIO_EMC_16 is configured as SEMC_ADDR00 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_17_SEMC_ADDR01, /* GPIO_EMC_17 is configured as SEMC_ADDR01 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_18_SEMC_ADDR02, /* GPIO_EMC_18 is configured as SEMC_ADDR02 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_19_SEMC_ADDR03, /* GPIO_EMC_19 is configured as SEMC_ADDR03 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_20_SEMC_ADDR04, /* GPIO_EMC_20 is configured as SEMC_ADDR04 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_21_SEMC_ADDR05, /* GPIO_EMC_21 is configured as SEMC_ADDR05 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_22_SEMC_ADDR06, /* GPIO_EMC_22 is configured as SEMC_ADDR06 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_23_SEMC_ADDR07, /* GPIO_EMC_23 is configured as SEMC_ADDR07 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_24_SEMC_ADDR08, /* GPIO_EMC_24 is configured as SEMC_ADDR08 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_25_SEMC_ADDR09, /* GPIO_EMC_25 is configured as SEMC_ADDR09 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_26_SEMC_ADDR11, /* GPIO_EMC_26 is configured as SEMC_ADDR11 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_27_SEMC_ADDR12, /* GPIO_EMC_27 is configured as SEMC_ADDR12 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_28_SEMC_DQS, /* GPIO_EMC_28 is configured as SEMC_DQS */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_29_SEMC_CKE, /* GPIO_EMC_29 is configured as SEMC_CKE */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_30_SEMC_CLK, /* GPIO_EMC_30 is configured as SEMC_CLK */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_31_SEMC_DM01, /* GPIO_EMC_31 is configured as SEMC_DM01 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_32_SEMC_DATA08, /* GPIO_EMC_32 is configured as SEMC_DATA08 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_33_SEMC_DATA09, /* GPIO_EMC_33 is configured as SEMC_DATA09 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_34_SEMC_DATA10, /* GPIO_EMC_34 is configured as SEMC_DATA10 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_35_SEMC_DATA11, /* GPIO_EMC_35 is configured as SEMC_DATA11 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_36_SEMC_DATA12, /* GPIO_EMC_36 is configured as SEMC_DATA12 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_37_SEMC_DATA13, /* GPIO_EMC_37 is configured as SEMC_DATA13 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_38_SEMC_DATA14, /* GPIO_EMC_38 is configured as SEMC_DATA14 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_39_SEMC_DATA15, /* GPIO_EMC_39 is configured as SEMC_DATA15 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitCANPins: +- options: {coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '32', peripheral: CAN1, signal: RX, pin_signal: GPIO_SD_B1_01} + - {pin_num: '33', peripheral: CAN1, signal: TX, pin_signal: GPIO_SD_B1_00} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitCANPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitCANPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03U */ + + IOMUXC_SetPinMux( + IOMUXC_GPIO_SD_B1_00_FLEXCAN1_TX, /* GPIO_SD_B1_00 is configured as FLEXCAN1_TX */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_SD_B1_01_FLEXCAN1_RX, /* GPIO_SD_B1_01 is configured as FLEXCAN1_RX */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitENETPins: +- options: {coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '97', peripheral: ENET, signal: enet_rx_en, pin_signal: GPIO_AD_B0_11} + - {pin_num: '84', peripheral: GPIO1, signal: 'gpio_io, 22', pin_signal: GPIO_AD_B1_06} + - {pin_num: '107', peripheral: GPIO1, signal: 'gpio_io, 04', pin_signal: GPIO_AD_B0_04} + - {pin_num: '100', peripheral: ENET, signal: enet_tx_clk, pin_signal: GPIO_AD_B0_08} + - {pin_num: '95', peripheral: ENET, signal: enet_tx_en, pin_signal: GPIO_AD_B0_13} + - {pin_num: '93', peripheral: ENET, signal: 'enet_tx_data, 1', pin_signal: GPIO_AD_B0_15} + - {pin_num: '94', peripheral: ENET, signal: 'enet_tx_data, 0', pin_signal: GPIO_AD_B0_14} + - {pin_num: '96', peripheral: ENET, signal: enet_rx_er, pin_signal: GPIO_AD_B0_12} + - {pin_num: '99', peripheral: ENET, signal: 'enet_rx_data, 1', pin_signal: GPIO_AD_B0_09} + - {pin_num: '98', peripheral: ENET, signal: 'enet_rx_data, 0', pin_signal: GPIO_AD_B0_10} + - {pin_num: '116', peripheral: ENET, signal: enet_mdio, pin_signal: GPIO_EMC_40} + - {pin_num: '115', peripheral: ENET, signal: enet_mdc, pin_signal: GPIO_EMC_41} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitENETPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitENETPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03U */ + + IOMUXC_SetPinMux( + IOMUXC_GPIO_AD_B0_04_GPIO1_IO04, /* GPIO_AD_B0_04 is configured as GPIO1_IO04 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_AD_B0_08_ENET_TX_CLK, /* GPIO_AD_B0_08 is configured as ENET_TX_CLK */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_AD_B0_09_ENET_RDATA01, /* GPIO_AD_B0_09 is configured as ENET_RDATA01 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_AD_B0_10_ENET_RDATA00, /* GPIO_AD_B0_10 is configured as ENET_RDATA00 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_AD_B0_11_ENET_RX_EN, /* GPIO_AD_B0_11 is configured as ENET_RX_EN */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_AD_B0_12_ENET_RX_ER, /* GPIO_AD_B0_12 is configured as ENET_RX_ER */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_AD_B0_13_ENET_TX_EN, /* GPIO_AD_B0_13 is configured as ENET_TX_EN */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_AD_B0_14_ENET_TDATA00, /* GPIO_AD_B0_14 is configured as ENET_TDATA00 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_AD_B0_15_ENET_TDATA01, /* GPIO_AD_B0_15 is configured as ENET_TDATA01 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_AD_B1_06_GPIO1_IO22, /* GPIO_AD_B1_06 is configured as GPIO1_IO22 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_40_ENET_MDIO, /* GPIO_EMC_40 is configured as ENET_MDIO */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_41_ENET_MDC, /* GPIO_EMC_41 is configured as ENET_MDC */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitUSDHCPins: +- options: {coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '45', peripheral: USDHC1, signal: usdhc_clk, pin_signal: GPIO_SD_B0_03} + - {pin_num: '46', peripheral: USDHC1, signal: usdhc_cmd, pin_signal: GPIO_SD_B0_02} + - {pin_num: '43', peripheral: USDHC1, signal: 'usdhc_data, 0', pin_signal: GPIO_SD_B0_04} + - {pin_num: '42', peripheral: USDHC1, signal: 'usdhc_data, 1', pin_signal: GPIO_SD_B0_05} + - {pin_num: '48', peripheral: USDHC1, signal: 'usdhc_data, 2', pin_signal: GPIO_SD_B0_00} + - {pin_num: '47', peripheral: USDHC1, signal: 'usdhc_data, 3', pin_signal: GPIO_SD_B0_01} + - {pin_num: '41', peripheral: GPIO3, signal: 'gpio_io, 19', pin_signal: GPIO_SD_B0_06} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitUSDHCPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitUSDHCPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03U */ + + IOMUXC_SetPinMux( + IOMUXC_GPIO_SD_B0_00_USDHC1_DATA2, /* GPIO_SD_B0_00 is configured as USDHC1_DATA2 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_SD_B0_01_USDHC1_DATA3, /* GPIO_SD_B0_01 is configured as USDHC1_DATA3 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_SD_B0_02_USDHC1_CMD, /* GPIO_SD_B0_02 is configured as USDHC1_CMD */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_SD_B0_03_USDHC1_CLK, /* GPIO_SD_B0_03 is configured as USDHC1_CLK */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_SD_B0_04_USDHC1_DATA0, /* GPIO_SD_B0_04 is configured as USDHC1_DATA0 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_SD_B0_05_USDHC1_DATA1, /* GPIO_SD_B0_05 is configured as USDHC1_DATA1 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_SD_B0_06_GPIO3_IO19, /* GPIO_SD_B0_06 is configured as GPIO3_IO19 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitQSPIPins: +- options: {coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '24', peripheral: FLEXSPI, signal: FLEXSPI_A_SCLK, pin_signal: GPIO_SD_B1_07} + - {pin_num: '23', peripheral: FLEXSPI, signal: FLEXSPI_A_DATA0, pin_signal: GPIO_SD_B1_08} + - {pin_num: '21', peripheral: FLEXSPI, signal: FLEXSPI_A_DATA1, pin_signal: GPIO_SD_B1_10} + - {pin_num: '22', peripheral: FLEXSPI, signal: FLEXSPI_A_DATA2, pin_signal: GPIO_SD_B1_09} + - {pin_num: '25', peripheral: FLEXSPI, signal: FLEXSPI_A_DATA3, pin_signal: GPIO_SD_B1_06} + - {pin_num: '19', peripheral: FLEXSPI, signal: FLEXSPI_A_SS0_B, pin_signal: GPIO_SD_B1_11} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitQSPIPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitQSPIPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03U */ + + IOMUXC_SetPinMux( + IOMUXC_GPIO_SD_B1_06_FLEXSPI_A_DATA03, /* GPIO_SD_B1_06 is configured as FLEXSPI_A_DATA03 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_SD_B1_07_FLEXSPI_A_SCLK, /* GPIO_SD_B1_07 is configured as FLEXSPI_A_SCLK */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_SD_B1_08_FLEXSPI_A_DATA00, /* GPIO_SD_B1_08 is configured as FLEXSPI_A_DATA00 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_SD_B1_09_FLEXSPI_A_DATA02, /* GPIO_SD_B1_09 is configured as FLEXSPI_A_DATA02 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_SD_B1_10_FLEXSPI_A_DATA01, /* GPIO_SD_B1_10 is configured as FLEXSPI_A_DATA01 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_SD_B1_11_FLEXSPI_A_SS0_B, /* GPIO_SD_B1_11 is configured as FLEXSPI_A_SS0_B */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ +} + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/imxrt/boards/mimxrt1024_evk/board/pin_mux.h b/hw/bsp/imxrt/boards/mimxrt1024_evk/board/pin_mux.h new file mode 100644 index 000000000..73ca62533 --- /dev/null +++ b/hw/bsp/imxrt/boards/mimxrt1024_evk/board/pin_mux.h @@ -0,0 +1,439 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _PIN_MUX_H_ +#define _PIN_MUX_H_ + +/*********************************************************************************************************************** + * Definitions + **********************************************************************************************************************/ + +/* Define the flexspi macro. Note that it can't be modified here */ +#define IOMUXC_GPIO_AD_B1_00_FLEXSPI_A_DATA03 0x401F80FCU, 0x1U, 0x401F8374U, 0x1U, 0x401F8270U +#define IOMUXC_GPIO_AD_B1_01_FLEXSPI_A_SCLK 0x401F8100U, 0x1U, 0x401F8378U, 0x1U, 0x401F8274U +#define IOMUXC_GPIO_AD_B1_02_FLEXSPI_A_DATA00 0x401F8104U, 0x1U, 0x401F8368U, 0x1U, 0x401F8278U +#define IOMUXC_GPIO_AD_B1_03_FLEXSPI_A_DATA02 0x401F8108U, 0x1U, 0x401F8370U, 0x1U, 0x401F827CU +#define IOMUXC_GPIO_AD_B1_04_FLEXSPI_A_DATA01 0x401F810CU, 0x1U, 0x401F836CU, 0x1U, 0x401F8280U +#define IOMUXC_GPIO_AD_B1_05_FLEXSPI_A_SS0_B 0x401F8110U, 0x1U, 0, 0, 0x401F8284U + +/*! @brief Direction type */ +typedef enum _pin_mux_direction +{ + kPIN_MUX_DirectionInput = 0U, /* Input direction */ + kPIN_MUX_DirectionOutput = 1U, /* Output direction */ + kPIN_MUX_DirectionInputOrOutput = 2U /* Input or output direction */ +} pin_mux_direction_t; + +/*! + * @addtogroup pin_mux + * @{ + */ + +/*********************************************************************************************************************** + * API + **********************************************************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Calls initialization functions. + * + */ +void BOARD_InitBootPins(void); + +/* WAKEUP (number 52), USER_BUTTON */ +#define BOARD_INITPINS_USER_BUTTON_GPIO GPIO5 /*!< GPIO device name: GPIO5 */ +#define BOARD_INITPINS_USER_BUTTON_PORT GPIO5 /*!< PORT device name: GPIO5 */ +#define BOARD_INITPINS_USER_BUTTON_PIN 0U /*!< GPIO5 pin index: 0 */ + +/* GPIO_AD_B1_08 (number 82), UART_TX/USER_LED/J17[4] */ +#define BOARD_INITPINS_USER_LED_GPIO GPIO1 /*!< GPIO device name: GPIO1 */ +#define BOARD_INITPINS_USER_LED_PORT GPIO1 /*!< PORT device name: GPIO1 */ +#define BOARD_INITPINS_USER_LED_PIN 24U /*!< GPIO1 pin index: 24 */ + + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitPins(void); + +/* GPIO_AD_B0_07 (number 101), UART1_RXD/J17[8] */ +#define BOARD_INITDEBUG_UARTPINS_UART1_RXD_PERIPHERAL LPUART1 /*!< Device name: LPUART1 */ +#define BOARD_INITDEBUG_UARTPINS_UART1_RXD_SIGNAL RX /*!< LPUART1 signal: RX */ + +/* GPIO_AD_B0_06 (number 105), UART1_TXD/J17[12] */ +#define BOARD_INITDEBUG_UARTPINS_UART1_TXD_PERIPHERAL LPUART1 /*!< Device name: LPUART1 */ +#define BOARD_INITDEBUG_UARTPINS_UART1_TXD_SIGNAL TX /*!< LPUART1 signal: TX */ + + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitDEBUG_UARTPins(void); + +/* GPIO_EMC_16 (number 142), SEMC_A0/U14[23]/BOOT_MODE[0] */ +#define BOARD_INITSDRAMPINS_SEMC_A0_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_A0_SIGNAL ADDR /*!< SEMC signal: ADDR */ +#define BOARD_INITSDRAMPINS_SEMC_A0_CHANNEL 0U /*!< SEMC ADDR channel: 00 */ + +/* GPIO_EMC_17 (number 141), SEMC_A1/U14[24]/BOOT_MODE[1] */ +#define BOARD_INITSDRAMPINS_SEMC_A1_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_A1_SIGNAL ADDR /*!< SEMC signal: ADDR */ +#define BOARD_INITSDRAMPINS_SEMC_A1_CHANNEL 1U /*!< SEMC ADDR channel: 01 */ + +/* GPIO_EMC_18 (number 140), SEMC_A2/U14[25]/BT_CFG[0] */ +#define BOARD_INITSDRAMPINS_SEMC_A2_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_A2_SIGNAL ADDR /*!< SEMC signal: ADDR */ +#define BOARD_INITSDRAMPINS_SEMC_A2_CHANNEL 2U /*!< SEMC ADDR channel: 02 */ + +/* GPIO_EMC_19 (number 139), SEMC_A3/U14[26]/BT_CFG[1] */ +#define BOARD_INITSDRAMPINS_SEMC_A3_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_A3_SIGNAL ADDR /*!< SEMC signal: ADDR */ +#define BOARD_INITSDRAMPINS_SEMC_A3_CHANNEL 3U /*!< SEMC ADDR channel: 03 */ + +/* GPIO_EMC_20 (number 138), SEMC_A4/U14[29]/BT_CFG[2] */ +#define BOARD_INITSDRAMPINS_SEMC_A4_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_A4_SIGNAL ADDR /*!< SEMC signal: ADDR */ +#define BOARD_INITSDRAMPINS_SEMC_A4_CHANNEL 4U /*!< SEMC ADDR channel: 04 */ + +/* GPIO_EMC_22 (number 136), SEMC_A6/U14[31]/BT_CFG[4] */ +#define BOARD_INITSDRAMPINS_SEMC_A6_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_A6_SIGNAL ADDR /*!< SEMC signal: ADDR */ +#define BOARD_INITSDRAMPINS_SEMC_A6_CHANNEL 6U /*!< SEMC ADDR channel: 06 */ + +/* GPIO_EMC_21 (number 137), SEMC_A5/U14[30]/BT_CFG[3] */ +#define BOARD_INITSDRAMPINS_SEMC_A5_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_A5_SIGNAL ADDR /*!< SEMC signal: ADDR */ +#define BOARD_INITSDRAMPINS_SEMC_A5_CHANNEL 5U /*!< SEMC ADDR channel: 05 */ + +/* GPIO_EMC_23 (number 133), SEMC_A7/U14[32]/BT_CFG[5] */ +#define BOARD_INITSDRAMPINS_SEMC_A7_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_A7_SIGNAL ADDR /*!< SEMC signal: ADDR */ +#define BOARD_INITSDRAMPINS_SEMC_A7_CHANNEL 7U /*!< SEMC ADDR channel: 07 */ + +/* GPIO_EMC_24 (number 132), SEMC_A8/U14[33]/BT_CFG[6] */ +#define BOARD_INITSDRAMPINS_SEMC_A8_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_A8_SIGNAL ADDR /*!< SEMC signal: ADDR */ +#define BOARD_INITSDRAMPINS_SEMC_A8_CHANNEL 8U /*!< SEMC ADDR channel: 08 */ + +/* GPIO_EMC_25 (number 131), SEMC_A9/U14[34]/BT_CFG[7] */ +#define BOARD_INITSDRAMPINS_SEMC_A9_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_A9_SIGNAL ADDR /*!< SEMC signal: ADDR */ +#define BOARD_INITSDRAMPINS_SEMC_A9_CHANNEL 9U /*!< SEMC ADDR channel: 09 */ + +/* GPIO_EMC_15 (number 143), SEMC_A10/U14[22] */ +#define BOARD_INITSDRAMPINS_SEMC_A10_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_A10_SIGNAL ADDR /*!< SEMC signal: ADDR */ +#define BOARD_INITSDRAMPINS_SEMC_A10_CHANNEL 10U /*!< SEMC ADDR channel: 10 */ + +/* GPIO_EMC_26 (number 130), SEMC_A11/U14[35]/BT_CFG[8] */ +#define BOARD_INITSDRAMPINS_SEMC_A11_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_A11_SIGNAL ADDR /*!< SEMC signal: ADDR */ +#define BOARD_INITSDRAMPINS_SEMC_A11_CHANNEL 11U /*!< SEMC ADDR channel: 11 */ + +/* GPIO_EMC_27 (number 129), SEMC_A12/U14[36]/BT_CFG[9] */ +#define BOARD_INITSDRAMPINS_SEMC_A12_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_A12_SIGNAL ADDR /*!< SEMC signal: ADDR */ +#define BOARD_INITSDRAMPINS_SEMC_A12_CHANNEL 12U /*!< SEMC ADDR channel: 12 */ + +/* GPIO_EMC_13 (number 2), SEMC_BA0/U14[20] */ +#define BOARD_INITSDRAMPINS_SEMC_BA0_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_BA0_SIGNAL BA /*!< SEMC signal: BA */ +#define BOARD_INITSDRAMPINS_SEMC_BA0_CHANNEL 0U /*!< SEMC BA channel: 0 */ + +/* GPIO_EMC_14 (number 1), SEMC_BA1/U14[21] */ +#define BOARD_INITSDRAMPINS_SEMC_BA1_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_BA1_SIGNAL BA /*!< SEMC signal: BA */ +#define BOARD_INITSDRAMPINS_SEMC_BA1_CHANNEL 1U /*!< SEMC BA channel: 1 */ + +/* GPIO_EMC_10 (number 7), SEMC_CAS/U14[17] */ +#define BOARD_INITSDRAMPINS_SEMC_CAS_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_CAS_SIGNAL semc_cas /*!< SEMC signal: semc_cas */ + +/* GPIO_EMC_29 (number 127), SEMC_CKE/U14[37] */ +#define BOARD_INITSDRAMPINS_SEMC_CKE_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_CKE_SIGNAL semc_cke /*!< SEMC signal: semc_cke */ + +/* GPIO_EMC_30 (number 126), SEMC_CLK/U14[38] */ +#define BOARD_INITSDRAMPINS_SEMC_CLK_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_CLK_SIGNAL semc_clk /*!< SEMC signal: semc_clk */ + +/* GPIO_EMC_12 (number 3), SEMC_CS0/U14[19] */ +#define BOARD_INITSDRAMPINS_SEMC_CS0_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_CS0_SIGNAL CS /*!< SEMC signal: CS */ +#define BOARD_INITSDRAMPINS_SEMC_CS0_CHANNEL 0U /*!< SEMC CS channel: 0 */ + +/* GPIO_EMC_09 (number 8), SEMC_WE/U14[16] */ +#define BOARD_INITSDRAMPINS_SEMC_WE_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_WE_SIGNAL semc_we /*!< SEMC signal: semc_we */ + +/* GPIO_EMC_11 (number 4), SEMC_RAS/U14[18] */ +#define BOARD_INITSDRAMPINS_SEMC_RAS_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_RAS_SIGNAL semc_ras /*!< SEMC signal: semc_ras */ + +/* GPIO_EMC_28 (number 128), SAI3_MCLK */ +#define BOARD_INITSDRAMPINS_SEMC_DQS_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_DQS_SIGNAL semc_dqs /*!< SEMC signal: semc_dqs */ + +/* GPIO_EMC_31 (number 125), SEMC_DM1/U14[39] */ +#define BOARD_INITSDRAMPINS_SEMC_DM1_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_DM1_SIGNAL DM /*!< SEMC signal: DM */ +#define BOARD_INITSDRAMPINS_SEMC_DM1_CHANNEL 1U /*!< SEMC DM channel: 1 */ + +/* GPIO_EMC_08 (number 9), SEMC_DM0/U14[15] */ +#define BOARD_INITSDRAMPINS_SEMC_DM0_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_DM0_SIGNAL DM /*!< SEMC signal: DM */ +#define BOARD_INITSDRAMPINS_SEMC_DM0_CHANNEL 0U /*!< SEMC DM channel: 0 */ + +/* GPIO_EMC_39 (number 117), SEMC_D15/U14[53] */ +#define BOARD_INITSDRAMPINS_SEMC_D15_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_D15_SIGNAL DATA /*!< SEMC signal: DATA */ +#define BOARD_INITSDRAMPINS_SEMC_D15_CHANNEL 15U /*!< SEMC DATA channel: 15 */ + +/* GPIO_EMC_38 (number 118), SEMC_D14/U14[51] */ +#define BOARD_INITSDRAMPINS_SEMC_D14_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_D14_SIGNAL DATA /*!< SEMC signal: DATA */ +#define BOARD_INITSDRAMPINS_SEMC_D14_CHANNEL 14U /*!< SEMC DATA channel: 14 */ + +/* GPIO_EMC_37 (number 119), SEMC_D13/U14[50] */ +#define BOARD_INITSDRAMPINS_SEMC_D13_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_D13_SIGNAL DATA /*!< SEMC signal: DATA */ +#define BOARD_INITSDRAMPINS_SEMC_D13_CHANNEL 13U /*!< SEMC DATA channel: 13 */ + +/* GPIO_EMC_36 (number 120), SEMC_D12/U14[48] */ +#define BOARD_INITSDRAMPINS_SEMC_D12_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_D12_SIGNAL DATA /*!< SEMC signal: DATA */ +#define BOARD_INITSDRAMPINS_SEMC_D12_CHANNEL 12U /*!< SEMC DATA channel: 12 */ + +/* GPIO_EMC_34 (number 122), SEMC_D10/U14[45] */ +#define BOARD_INITSDRAMPINS_SEMC_D10_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_D10_SIGNAL DATA /*!< SEMC signal: DATA */ +#define BOARD_INITSDRAMPINS_SEMC_D10_CHANNEL 10U /*!< SEMC DATA channel: 10 */ + +/* GPIO_EMC_35 (number 121), SEMC_D11/U14[47] */ +#define BOARD_INITSDRAMPINS_SEMC_D11_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_D11_SIGNAL DATA /*!< SEMC signal: DATA */ +#define BOARD_INITSDRAMPINS_SEMC_D11_CHANNEL 11U /*!< SEMC DATA channel: 11 */ + +/* GPIO_EMC_33 (number 123), SEMC_D9/U14[44] */ +#define BOARD_INITSDRAMPINS_SEMC_D9_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_D9_SIGNAL DATA /*!< SEMC signal: DATA */ +#define BOARD_INITSDRAMPINS_SEMC_D9_CHANNEL 9U /*!< SEMC DATA channel: 09 */ + +/* GPIO_EMC_32 (number 124), SEMC_D8/U14[42] */ +#define BOARD_INITSDRAMPINS_SEMC_D8_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_D8_SIGNAL DATA /*!< SEMC signal: DATA */ +#define BOARD_INITSDRAMPINS_SEMC_D8_CHANNEL 8U /*!< SEMC DATA channel: 08 */ + +/* GPIO_EMC_07 (number 10), SEMC_D7/U14[13] */ +#define BOARD_INITSDRAMPINS_SEMC_D7_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_D7_SIGNAL DATA /*!< SEMC signal: DATA */ +#define BOARD_INITSDRAMPINS_SEMC_D7_CHANNEL 7U /*!< SEMC DATA channel: 07 */ + +/* GPIO_EMC_06 (number 12), SEMC_D6/U14[11] */ +#define BOARD_INITSDRAMPINS_SEMC_D6_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_D6_SIGNAL DATA /*!< SEMC signal: DATA */ +#define BOARD_INITSDRAMPINS_SEMC_D6_CHANNEL 6U /*!< SEMC DATA channel: 06 */ + +/* GPIO_EMC_05 (number 13), SEMC_D5/U14[10] */ +#define BOARD_INITSDRAMPINS_SEMC_D5_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_D5_SIGNAL DATA /*!< SEMC signal: DATA */ +#define BOARD_INITSDRAMPINS_SEMC_D5_CHANNEL 5U /*!< SEMC DATA channel: 05 */ + +/* GPIO_EMC_04 (number 14), SEMC_D4/U14[8] */ +#define BOARD_INITSDRAMPINS_SEMC_D4_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_D4_SIGNAL DATA /*!< SEMC signal: DATA */ +#define BOARD_INITSDRAMPINS_SEMC_D4_CHANNEL 4U /*!< SEMC DATA channel: 04 */ + +/* GPIO_EMC_03 (number 15), SEMC_D3/U14[7] */ +#define BOARD_INITSDRAMPINS_SEMC_D3_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_D3_SIGNAL DATA /*!< SEMC signal: DATA */ +#define BOARD_INITSDRAMPINS_SEMC_D3_CHANNEL 3U /*!< SEMC DATA channel: 03 */ + +/* GPIO_EMC_02 (number 16), SEMC_D2/U14[5] */ +#define BOARD_INITSDRAMPINS_SEMC_D2_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_D2_SIGNAL DATA /*!< SEMC signal: DATA */ +#define BOARD_INITSDRAMPINS_SEMC_D2_CHANNEL 2U /*!< SEMC DATA channel: 02 */ + +/* GPIO_EMC_01 (number 17), SEMC_D1/U14[4] */ +#define BOARD_INITSDRAMPINS_SEMC_D1_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_D1_SIGNAL DATA /*!< SEMC signal: DATA */ +#define BOARD_INITSDRAMPINS_SEMC_D1_CHANNEL 1U /*!< SEMC DATA channel: 01 */ + +/* GPIO_EMC_00 (number 18), SEMC_D0/U14[2] */ +#define BOARD_INITSDRAMPINS_SEMC_D0_PERIPHERAL SEMC /*!< Device name: SEMC */ +#define BOARD_INITSDRAMPINS_SEMC_D0_SIGNAL DATA /*!< SEMC signal: DATA */ +#define BOARD_INITSDRAMPINS_SEMC_D0_CHANNEL 0U /*!< SEMC DATA channel: 00 */ + + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitSDRAMPins(void); + +/* GPIO_SD_B1_01 (number 32), CAN1_RX/U9[4] */ +#define BOARD_INITCANPINS_CAN1_RX_PERIPHERAL CAN1 /*!< Device name: CAN1 */ +#define BOARD_INITCANPINS_CAN1_RX_SIGNAL RX /*!< CAN1 signal: RX */ + +/* GPIO_SD_B1_00 (number 33), CAN1_TX/U9[1] */ +#define BOARD_INITCANPINS_CAN1_TX_PERIPHERAL CAN1 /*!< Device name: CAN1 */ +#define BOARD_INITCANPINS_CAN1_TX_SIGNAL TX /*!< CAN1 signal: TX */ + + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitCANPins(void); + +/* GPIO_AD_B0_11 (number 97), ENET_CRS_DV/U11[18]/J19[6] */ +#define BOARD_INITENETPINS_ENET_CRS_DV_PERIPHERAL ENET /*!< Device name: ENET */ +#define BOARD_INITENETPINS_ENET_CRS_DV_SIGNAL enet_rx_en /*!< ENET signal: enet_rx_en */ + +/* GPIO_AD_B1_06 (number 84), ENET_INT/U11[21]/J17[16] */ +#define BOARD_INITENETPINS_ENET_INT_GPIO GPIO1 /*!< GPIO device name: GPIO1 */ +#define BOARD_INITENETPINS_ENET_INT_PORT GPIO1 /*!< PORT device name: GPIO1 */ +#define BOARD_INITENETPINS_ENET_INT_PIN 22U /*!< GPIO1 pin index: 22 */ + +/* GPIO_AD_B0_04 (number 107), JTAG_TDO/ENET_RST/U11[32] */ +#define BOARD_INITENETPINS_ENET_RST_GPIO GPIO1 /*!< GPIO device name: GPIO1 */ +#define BOARD_INITENETPINS_ENET_RST_PORT GPIO1 /*!< PORT device name: GPIO1 */ +#define BOARD_INITENETPINS_ENET_RST_PIN 4U /*!< GPIO1 pin index: 4 */ + +/* GPIO_AD_B0_08 (number 100), ENET_TX_REF_CLK/U11[9] */ +#define BOARD_INITENETPINS_ENET_TX_CLK_PERIPHERAL ENET /*!< Device name: ENET */ +#define BOARD_INITENETPINS_ENET_TX_CLK_SIGNAL enet_tx_clk /*!< ENET signal: enet_tx_clk */ + +/* GPIO_AD_B0_13 (number 95), ENET_TXEN/U11[23]/J19[10] */ +#define BOARD_INITENETPINS_ENET_TXEN_PERIPHERAL ENET /*!< Device name: ENET */ +#define BOARD_INITENETPINS_ENET_TXEN_SIGNAL enet_tx_en /*!< ENET signal: enet_tx_en */ + +/* GPIO_AD_B0_15 (number 93), ENET_TXD1/U11[25]/J19[4] */ +#define BOARD_INITENETPINS_ENET_TXD1_PERIPHERAL ENET /*!< Device name: ENET */ +#define BOARD_INITENETPINS_ENET_TXD1_SIGNAL enet_tx_data /*!< ENET signal: enet_tx_data */ +#define BOARD_INITENETPINS_ENET_TXD1_CHANNEL 1U /*!< ENET enet_tx_data channel: 1 */ + +/* GPIO_AD_B0_14 (number 94), ENET_TXD0/U11[24]/J17[14] */ +#define BOARD_INITENETPINS_ENET_TXD0_PERIPHERAL ENET /*!< Device name: ENET */ +#define BOARD_INITENETPINS_ENET_TXD0_SIGNAL enet_tx_data /*!< ENET signal: enet_tx_data */ +#define BOARD_INITENETPINS_ENET_TXD0_CHANNEL 0U /*!< ENET enet_tx_data channel: 0 */ + +/* GPIO_AD_B0_12 (number 96), ENET_RXER/U11[20]/J19[8] */ +#define BOARD_INITENETPINS_ENET_RXER_PERIPHERAL ENET /*!< Device name: ENET */ +#define BOARD_INITENETPINS_ENET_RXER_SIGNAL enet_rx_er /*!< ENET signal: enet_rx_er */ + +/* GPIO_AD_B0_09 (number 99), ENET_RXD1/U11[15]/J17[6] */ +#define BOARD_INITENETPINS_ENET_RXD1_PERIPHERAL ENET /*!< Device name: ENET */ +#define BOARD_INITENETPINS_ENET_RXD1_SIGNAL enet_rx_data /*!< ENET signal: enet_rx_data */ +#define BOARD_INITENETPINS_ENET_RXD1_CHANNEL 1U /*!< ENET enet_rx_data channel: 1 */ + +/* GPIO_AD_B0_10 (number 98), ENET_RXD0/U11[16]/J19[12] */ +#define BOARD_INITENETPINS_ENET_RXD0_PERIPHERAL ENET /*!< Device name: ENET */ +#define BOARD_INITENETPINS_ENET_RXD0_SIGNAL enet_rx_data /*!< ENET signal: enet_rx_data */ +#define BOARD_INITENETPINS_ENET_RXD0_CHANNEL 0U /*!< ENET enet_rx_data channel: 0 */ + +/* GPIO_EMC_40 (number 116), ENET_MDIO/U11[11] */ +#define BOARD_INITENETPINS_ENET_MDIO_PERIPHERAL ENET /*!< Device name: ENET */ +#define BOARD_INITENETPINS_ENET_MDIO_SIGNAL enet_mdio /*!< ENET signal: enet_mdio */ + +/* GPIO_EMC_41 (number 115), ENET_MDC/U11[12] */ +#define BOARD_INITENETPINS_ENET_MDC_PERIPHERAL ENET /*!< Device name: ENET */ +#define BOARD_INITENETPINS_ENET_MDC_SIGNAL enet_mdc /*!< ENET signal: enet_mdc */ + + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitENETPins(void); + +/* GPIO_SD_B0_03 (number 45), SD1_CLK/J15[5] */ +#define BOARD_INITUSDHCPINS_SD1_CLK_PERIPHERAL USDHC1 /*!< Device name: USDHC1 */ +#define BOARD_INITUSDHCPINS_SD1_CLK_SIGNAL usdhc_clk /*!< USDHC1 signal: usdhc_clk */ + +/* GPIO_SD_B0_02 (number 46), SD1_CMD/J15[3] */ +#define BOARD_INITUSDHCPINS_SD1_CMD_PERIPHERAL USDHC1 /*!< Device name: USDHC1 */ +#define BOARD_INITUSDHCPINS_SD1_CMD_SIGNAL usdhc_cmd /*!< USDHC1 signal: usdhc_cmd */ + +/* GPIO_SD_B0_04 (number 43), SD1_D0/J15[7] */ +#define BOARD_INITUSDHCPINS_SD1_D0_PERIPHERAL USDHC1 /*!< Device name: USDHC1 */ +#define BOARD_INITUSDHCPINS_SD1_D0_SIGNAL usdhc_data /*!< USDHC1 signal: usdhc_data */ +#define BOARD_INITUSDHCPINS_SD1_D0_CHANNEL 0U /*!< USDHC1 usdhc_data channel: 0 */ + +/* GPIO_SD_B0_05 (number 42), SD1_D1/J15[8] */ +#define BOARD_INITUSDHCPINS_SD1_D1_PERIPHERAL USDHC1 /*!< Device name: USDHC1 */ +#define BOARD_INITUSDHCPINS_SD1_D1_SIGNAL usdhc_data /*!< USDHC1 signal: usdhc_data */ +#define BOARD_INITUSDHCPINS_SD1_D1_CHANNEL 1U /*!< USDHC1 usdhc_data channel: 1 */ + +/* GPIO_SD_B0_00 (number 48), SD1_D2/J15[1] */ +#define BOARD_INITUSDHCPINS_SD1_D2_PERIPHERAL USDHC1 /*!< Device name: USDHC1 */ +#define BOARD_INITUSDHCPINS_SD1_D2_SIGNAL usdhc_data /*!< USDHC1 signal: usdhc_data */ +#define BOARD_INITUSDHCPINS_SD1_D2_CHANNEL 2U /*!< USDHC1 usdhc_data channel: 2 */ + +/* GPIO_SD_B0_01 (number 47), SD1_D3/J15[2] */ +#define BOARD_INITUSDHCPINS_SD1_D3_PERIPHERAL USDHC1 /*!< Device name: USDHC1 */ +#define BOARD_INITUSDHCPINS_SD1_D3_SIGNAL usdhc_data /*!< USDHC1 signal: usdhc_data */ +#define BOARD_INITUSDHCPINS_SD1_D3_CHANNEL 3U /*!< USDHC1 usdhc_data channel: 3 */ + +/* GPIO_SD_B0_06 (number 41), SD_CD_SW/J15[9] */ +#define BOARD_INITUSDHCPINS_SD_CD_SW_GPIO GPIO3 /*!< GPIO device name: GPIO3 */ +#define BOARD_INITUSDHCPINS_SD_CD_SW_PORT GPIO3 /*!< PORT device name: GPIO3 */ +#define BOARD_INITUSDHCPINS_SD_CD_SW_PIN 19U /*!< GPIO3 pin index: 19 */ + + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitUSDHCPins(void); + +/* GPIO_SD_B1_07 (number 24), SAI3_TX_SYNC */ +#define BOARD_INITQSPIPINS_FlexSPI_CLK_PERIPHERAL FLEXSPI /*!< Device name: FLEXSPI */ +#define BOARD_INITQSPIPINS_FlexSPI_CLK_SIGNAL FLEXSPI_A_SCLK /*!< FLEXSPI signal: FLEXSPI_A_SCLK */ + +/* GPIO_SD_B1_08 (number 23), SAI3_TXD */ +#define BOARD_INITQSPIPINS_FlexSPI_D0_A_PERIPHERAL FLEXSPI /*!< Device name: FLEXSPI */ +#define BOARD_INITQSPIPINS_FlexSPI_D0_A_SIGNAL FLEXSPI_A_DATA0 /*!< FLEXSPI signal: FLEXSPI_A_DATA0 */ + +/* GPIO_SD_B1_10 (number 21), SD_PWREN */ +#define BOARD_INITQSPIPINS_FlexSPI_D1_A_PERIPHERAL FLEXSPI /*!< Device name: FLEXSPI */ +#define BOARD_INITQSPIPINS_FlexSPI_D1_A_SIGNAL FLEXSPI_A_DATA1 /*!< FLEXSPI signal: FLEXSPI_A_DATA1 */ + +/* GPIO_SD_B1_09 (number 22), AUD_INT */ +#define BOARD_INITQSPIPINS_FlexSPI_D2_A_PERIPHERAL FLEXSPI /*!< Device name: FLEXSPI */ +#define BOARD_INITQSPIPINS_FlexSPI_D2_A_SIGNAL FLEXSPI_A_DATA2 /*!< FLEXSPI signal: FLEXSPI_A_DATA2 */ + +/* GPIO_SD_B1_06 (number 25), SAI3_TX_BCLK */ +#define BOARD_INITQSPIPINS_FlexSPI_D3_A_PERIPHERAL FLEXSPI /*!< Device name: FLEXSPI */ +#define BOARD_INITQSPIPINS_FlexSPI_D3_A_SIGNAL FLEXSPI_A_DATA3 /*!< FLEXSPI signal: FLEXSPI_A_DATA3 */ + +/* GPIO_SD_B1_11 (number 19), SAI3_RXD */ +#define BOARD_INITQSPIPINS_FlexSPI_SS0_PERIPHERAL FLEXSPI /*!< Device name: FLEXSPI */ +#define BOARD_INITQSPIPINS_FlexSPI_SS0_SIGNAL FLEXSPI_A_SS0_B /*!< FLEXSPI signal: FLEXSPI_A_SS0_B */ + + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitQSPIPins(void); + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif /* _PIN_MUX_H_ */ + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/imxrt/boards/mimxrt1024_evk/mimxrt1024_evk.mex b/hw/bsp/imxrt/boards/mimxrt1024_evk/mimxrt1024_evk.mex index 2aa55a604..7c44950ec 100644 --- a/hw/bsp/imxrt/boards/mimxrt1024_evk/mimxrt1024_evk.mex +++ b/hw/bsp/imxrt/boards/mimxrt1024_evk/mimxrt1024_evk.mex @@ -26,6 +26,10 @@ 13.0.2 + + + + @@ -39,13 +43,39 @@ true + + + true + + true + + + true + + + + + true + + - + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. @@ -423,11 +453,8 @@ - - - - - + + 13.0.2 c_array @@ -440,11 +467,8 @@ - - - - - + + 13.0.2 diff --git a/hw/bsp/imxrt/boards/mimxrt1050_evkb/board.h b/hw/bsp/imxrt/boards/mimxrt1050_evkb/board.h index beb69bf2b..97d1e446c 100644 --- a/hw/bsp/imxrt/boards/mimxrt1050_evkb/board.h +++ b/hw/bsp/imxrt/boards/mimxrt1050_evkb/board.h @@ -24,28 +24,24 @@ * This file is part of the TinyUSB stack. */ +#ifndef BOARD_MIMXRT1050_EVKB_H_ +#define BOARD_MIMXRT1050_EVKB_H_ -#ifndef BOARD_H_ -#define BOARD_H_ - -// required since iMX RT10xx SDK include this file for board size +// required since iMXRT MCUX-SDK include this file for board size #define BOARD_FLASH_SIZE (0x4000000U) -// LED -#define LED_PINMUX IOMUXC_GPIO_AD_B0_09_GPIO1_IO09 -#define LED_PORT GPIO1 -#define LED_PIN 9 +// LED: IOMUXC_GPIO_AD_B0_09_GPIO1_IO09 +#define LED_PORT BOARD_INITPINS_USER_LED_PERIPHERAL +#define LED_PIN BOARD_INITPINS_USER_LED_CHANNEL #define LED_STATE_ON 0 -// SW8 button -#define BUTTON_PINMUX IOMUXC_SNVS_WAKEUP_GPIO5_IO00 -#define BUTTON_PORT GPIO5 -#define BUTTON_PIN 0 +// SW8 button: IOMUXC_SNVS_WAKEUP_GPIO5_IO00 +#define BUTTON_PORT BOARD_INITPINS_USER_BUTTON_PERIPHERAL +#define BUTTON_PIN BOARD_INITPINS_USER_BUTTON_CHANNEL #define BUTTON_STATE_ACTIVE 0 -// UART +// UART: IOMUXC_GPIO_AD_B0_13_LPUART1_RXD, IOMUXC_GPIO_AD_B0_12_LPUART1_TXD #define UART_PORT LPUART1 -#define UART_RX_PINMUX IOMUXC_GPIO_AD_B0_13_LPUART1_RXD -#define UART_TX_PINMUX IOMUXC_GPIO_AD_B0_12_LPUART1_TXD +#define UART_CLK_ROOT BOARD_BOOTCLOCKRUN_UART_CLK_ROOT -#endif /* BOARD_H_ */ +#endif diff --git a/hw/bsp/imxrt/boards/mimxrt1050_evkb/board/pin_mux.c b/hw/bsp/imxrt/boards/mimxrt1050_evkb/board/pin_mux.c new file mode 100644 index 000000000..aebfa5f46 --- /dev/null +++ b/hw/bsp/imxrt/boards/mimxrt1050_evkb/board/pin_mux.c @@ -0,0 +1,618 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Pins v13.1 +processor: MIMXRT1052xxxxB +package_id: MIMXRT1052DVL6B +mcu_data: ksdk2_0 +processor_version: 13.0.2 +board: IMXRT1050-EVKB +pin_labels: +- {pin_num: F14, pin_signal: GPIO_AD_B0_09, label: 'JTAG_TDI/J21[5]/ENET_RST/J22[5]', identifier: USER_LED} +- {pin_num: L6, pin_signal: WAKEUP, label: SD_PWREN, identifier: USER_BUTTON} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +#include "fsl_common.h" +#include "fsl_iomuxc.h" +#include "fsl_gpio.h" +#include "pin_mux.h" + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitBootPins + * Description : Calls initialization functions. + * + * END ****************************************************************************************************************/ +void BOARD_InitBootPins(void) { + BOARD_InitPins(); + BOARD_InitDEBUG_UARTPins(); +} + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitPins: +- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: F14, peripheral: GPIO1, signal: 'gpio_io, 09', pin_signal: GPIO_AD_B0_09, direction: OUTPUT, pull_keeper_select: Keeper} + - {pin_num: L6, peripheral: GPIO5, signal: 'gpio_io, 00', pin_signal: WAKEUP, direction: INPUT, pull_up_down_config: Pull_Up_100K_Ohm} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + CLOCK_EnableClock(kCLOCK_IomuxcSnvs); + + /* GPIO configuration of USER_LED on GPIO_AD_B0_09 (pin F14) */ + gpio_pin_config_t USER_LED_config = { + .direction = kGPIO_DigitalOutput, + .outputLogic = 0U, + .interruptMode = kGPIO_NoIntmode + }; + /* Initialize GPIO functionality on GPIO_AD_B0_09 (pin F14) */ + GPIO_PinInit(GPIO1, 9U, &USER_LED_config); + + /* GPIO configuration of USER_BUTTON on WAKEUP (pin L6) */ + gpio_pin_config_t USER_BUTTON_config = { + .direction = kGPIO_DigitalInput, + .outputLogic = 0U, + .interruptMode = kGPIO_NoIntmode + }; + /* Initialize GPIO functionality on WAKEUP (pin L6) */ + GPIO_PinInit(GPIO5, 0U, &USER_BUTTON_config); + + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, 0U); + IOMUXC_SetPinMux(IOMUXC_SNVS_WAKEUP_GPIO5_IO00, 0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, 0x50A0U); + IOMUXC_SetPinConfig(IOMUXC_SNVS_WAKEUP_GPIO5_IO00, 0x01B0A0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitDEBUG_UARTPins: +- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: K14, peripheral: LPUART1, signal: TX, pin_signal: GPIO_AD_B0_12, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Down_100K_Ohm, + pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} + - {pin_num: L14, peripheral: LPUART1, signal: RX, pin_signal: GPIO_AD_B0_13, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Down_100K_Ohm, + pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitDEBUG_UARTPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitDEBUG_UARTPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_12_LPUART1_TXD, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, 0U); +#endif +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_13_LPUART1_RXD, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, 0U); +#endif +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_12_LPUART1_TXD, 0x10B0U); +#else + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, 0x10B0U); +#endif +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_13_LPUART1_RXD, 0x10B0U); +#else + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, 0x10B0U); +#endif +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitSDRAMPins: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: C2, peripheral: SEMC, signal: 'ADDR, 00', pin_signal: GPIO_EMC_09} + - {pin_num: G1, peripheral: SEMC, signal: 'ADDR, 01', pin_signal: GPIO_EMC_10} + - {pin_num: G3, peripheral: SEMC, signal: 'ADDR, 02', pin_signal: GPIO_EMC_11} + - {pin_num: H1, peripheral: SEMC, signal: 'ADDR, 03', pin_signal: GPIO_EMC_12} + - {pin_num: A6, peripheral: SEMC, signal: 'ADDR, 04', pin_signal: GPIO_EMC_13} + - {pin_num: B6, peripheral: SEMC, signal: 'ADDR, 05', pin_signal: GPIO_EMC_14} + - {pin_num: B1, peripheral: SEMC, signal: 'ADDR, 06', pin_signal: GPIO_EMC_15} + - {pin_num: A5, peripheral: SEMC, signal: 'ADDR, 07', pin_signal: GPIO_EMC_16} + - {pin_num: A4, peripheral: SEMC, signal: 'ADDR, 08', pin_signal: GPIO_EMC_17} + - {pin_num: B2, peripheral: SEMC, signal: 'ADDR, 09', pin_signal: GPIO_EMC_18} + - {pin_num: G2, peripheral: SEMC, signal: 'ADDR, 10', pin_signal: GPIO_EMC_23} + - {pin_num: B4, peripheral: SEMC, signal: 'ADDR, 11', pin_signal: GPIO_EMC_19} + - {pin_num: A3, peripheral: SEMC, signal: 'ADDR, 12', pin_signal: GPIO_EMC_20} + - {pin_num: C1, peripheral: SEMC, signal: 'BA, 0', pin_signal: GPIO_EMC_21} + - {pin_num: F1, peripheral: SEMC, signal: 'BA, 1', pin_signal: GPIO_EMC_22} + - {pin_num: D3, peripheral: SEMC, signal: semc_cas, pin_signal: GPIO_EMC_24} + - {pin_num: A2, peripheral: SEMC, signal: semc_cke, pin_signal: GPIO_EMC_27} + - {pin_num: B3, peripheral: SEMC, signal: semc_clk, pin_signal: GPIO_EMC_26} + - {pin_num: E3, peripheral: SEMC, signal: 'DATA, 00', pin_signal: GPIO_EMC_00} + - {pin_num: F3, peripheral: SEMC, signal: 'DATA, 01', pin_signal: GPIO_EMC_01} + - {pin_num: F4, peripheral: SEMC, signal: 'DATA, 02', pin_signal: GPIO_EMC_02} + - {pin_num: G4, peripheral: SEMC, signal: 'DATA, 03', pin_signal: GPIO_EMC_03} + - {pin_num: F2, peripheral: SEMC, signal: 'DATA, 04', pin_signal: GPIO_EMC_04} + - {pin_num: G5, peripheral: SEMC, signal: 'DATA, 05', pin_signal: GPIO_EMC_05} + - {pin_num: H5, peripheral: SEMC, signal: 'DATA, 06', pin_signal: GPIO_EMC_06} + - {pin_num: H4, peripheral: SEMC, signal: 'DATA, 07', pin_signal: GPIO_EMC_07} + - {pin_num: C6, peripheral: SEMC, signal: 'DATA, 08', pin_signal: GPIO_EMC_30} + - {pin_num: C5, peripheral: SEMC, signal: 'DATA, 09', pin_signal: GPIO_EMC_31} + - {pin_num: D5, peripheral: SEMC, signal: 'DATA, 10', pin_signal: GPIO_EMC_32} + - {pin_num: C4, peripheral: SEMC, signal: 'DATA, 11', pin_signal: GPIO_EMC_33} + - {pin_num: D4, peripheral: SEMC, signal: 'DATA, 12', pin_signal: GPIO_EMC_34} + - {pin_num: E5, peripheral: SEMC, signal: 'DATA, 13', pin_signal: GPIO_EMC_35} + - {pin_num: C3, peripheral: SEMC, signal: 'DATA, 14', pin_signal: GPIO_EMC_36} + - {pin_num: E4, peripheral: SEMC, signal: 'DATA, 15', pin_signal: GPIO_EMC_37} + - {pin_num: H3, peripheral: SEMC, signal: 'DM, 0', pin_signal: GPIO_EMC_08} + - {pin_num: D6, peripheral: SEMC, signal: 'DM, 1', pin_signal: GPIO_EMC_38} + - {pin_num: D2, peripheral: SEMC, signal: semc_ras, pin_signal: GPIO_EMC_25} + - {pin_num: D1, peripheral: SEMC, signal: semc_we, pin_signal: GPIO_EMC_28} + - {pin_num: C7, peripheral: SEMC, signal: 'CSX, 0', pin_signal: GPIO_EMC_41} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitSDRAMPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitSDRAMPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_00_SEMC_DA00, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_00_SEMC_DATA00, 0U); +#endif +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_01_SEMC_DA01, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_01_SEMC_DATA01, 0U); +#endif +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_02_SEMC_DA02, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_02_SEMC_DATA02, 0U); +#endif +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_03_SEMC_DA03, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_03_SEMC_DATA03, 0U); +#endif +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_04_SEMC_DA04, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_04_SEMC_DATA04, 0U); +#endif +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_05_SEMC_DA05, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_05_SEMC_DATA05, 0U); +#endif +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_06_SEMC_DA06, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_06_SEMC_DATA06, 0U); +#endif +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_07_SEMC_DA07, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_07_SEMC_DATA07, 0U); +#endif + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_08_SEMC_DM00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_09_SEMC_ADDR00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_10_SEMC_ADDR01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_11_SEMC_ADDR02, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_12_SEMC_ADDR03, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_13_SEMC_ADDR04, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_14_SEMC_ADDR05, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_15_SEMC_ADDR06, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_16_SEMC_ADDR07, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_17_SEMC_ADDR08, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_18_SEMC_ADDR09, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_19_SEMC_ADDR11, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_20_SEMC_ADDR12, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_21_SEMC_BA0, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_22_SEMC_BA1, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_23_SEMC_ADDR10, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_24_SEMC_CAS, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_25_SEMC_RAS, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_26_SEMC_CLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_27_SEMC_CKE, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_28_SEMC_WE, 0U); +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_30_SEMC_DA08, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_30_SEMC_DATA08, 0U); +#endif +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_31_SEMC_DA09, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_31_SEMC_DATA09, 0U); +#endif +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_32_SEMC_DA10, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_32_SEMC_DATA10, 0U); +#endif +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_33_SEMC_DA11, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_33_SEMC_DATA11, 0U); +#endif +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_34_SEMC_DA12, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_34_SEMC_DATA12, 0U); +#endif +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_35_SEMC_DA13, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_35_SEMC_DATA13, 0U); +#endif +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_36_SEMC_DA14, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_36_SEMC_DATA14, 0U); +#endif +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_37_SEMC_DA15, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_37_SEMC_DATA15, 0U); +#endif + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_38_SEMC_DM01, 0U); +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_41_SEMC_CSX0, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_41_SEMC_CSX00, 0U); +#endif +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitCSIPins: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: H13, peripheral: CSI, signal: 'csi_data, 09', pin_signal: GPIO_AD_B1_08} + - {pin_num: M13, peripheral: CSI, signal: 'csi_data, 08', pin_signal: GPIO_AD_B1_09} + - {pin_num: L13, peripheral: CSI, signal: 'csi_data, 07', pin_signal: GPIO_AD_B1_10} + - {pin_num: J13, peripheral: CSI, signal: 'csi_data, 06', pin_signal: GPIO_AD_B1_11} + - {pin_num: H12, peripheral: CSI, signal: 'csi_data, 05', pin_signal: GPIO_AD_B1_12} + - {pin_num: H11, peripheral: CSI, signal: 'csi_data, 04', pin_signal: GPIO_AD_B1_13} + - {pin_num: J14, peripheral: CSI, signal: 'csi_data, 02', pin_signal: GPIO_AD_B1_15} + - {pin_num: G12, peripheral: CSI, signal: 'csi_data, 03', pin_signal: GPIO_AD_B1_14} + - {pin_num: L12, peripheral: CSI, signal: csi_pixclk, pin_signal: GPIO_AD_B1_04} + - {pin_num: K12, peripheral: CSI, signal: csi_mclk, pin_signal: GPIO_AD_B1_05} + - {pin_num: J12, peripheral: CSI, signal: csi_vsync, pin_signal: GPIO_AD_B1_06} + - {pin_num: K10, peripheral: CSI, signal: csi_hsync, pin_signal: GPIO_AD_B1_07} + - {pin_num: J11, peripheral: LPI2C1, signal: SCL, pin_signal: GPIO_AD_B1_00, identifier: CSI_I2C_SCL, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Up_22K_Ohm, + pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Enable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} + - {pin_num: K11, peripheral: LPI2C1, signal: SDA, pin_signal: GPIO_AD_B1_01, identifier: CSI_I2C_SDA, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Up_22K_Ohm, + pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Enable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} + - {pin_num: F11, peripheral: GPIO1, signal: 'gpio_io, 04', pin_signal: GPIO_AD_B0_04} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitCSIPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitCSIPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_04_GPIO1_IO04, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_04_CSI_PIXCLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_05_CSI_MCLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_06_CSI_VSYNC, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_07_CSI_HSYNC, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_08_CSI_DATA09, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_09_CSI_DATA08, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_10_CSI_DATA07, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_11_CSI_DATA06, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_12_CSI_DATA05, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_13_CSI_DATA04, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_14_CSI_DATA03, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_15_CSI_DATA02, 0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL, 0xD8B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA, 0xD8B0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitLCDPins: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: C8, peripheral: LCDIF, signal: 'lcdif_data, 00', pin_signal: GPIO_B0_04, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: B8, peripheral: LCDIF, signal: 'lcdif_data, 01', pin_signal: GPIO_B0_05, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: A8, peripheral: LCDIF, signal: 'lcdif_data, 02', pin_signal: GPIO_B0_06, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: D7, peripheral: LCDIF, signal: lcdif_clk, pin_signal: GPIO_B0_00, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: A9, peripheral: LCDIF, signal: 'lcdif_data, 03', pin_signal: GPIO_B0_07, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: B9, peripheral: LCDIF, signal: 'lcdif_data, 04', pin_signal: GPIO_B0_08, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: C9, peripheral: LCDIF, signal: 'lcdif_data, 05', pin_signal: GPIO_B0_09, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: D9, peripheral: LCDIF, signal: 'lcdif_data, 06', pin_signal: GPIO_B0_10, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: A10, peripheral: LCDIF, signal: 'lcdif_data, 07', pin_signal: GPIO_B0_11, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: C10, peripheral: LCDIF, signal: 'lcdif_data, 08', pin_signal: GPIO_B0_12, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: D10, peripheral: LCDIF, signal: 'lcdif_data, 09', pin_signal: GPIO_B0_13, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: E10, peripheral: LCDIF, signal: 'lcdif_data, 10', pin_signal: GPIO_B0_14, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: E11, peripheral: LCDIF, signal: 'lcdif_data, 11', pin_signal: GPIO_B0_15, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: A11, peripheral: LCDIF, signal: 'lcdif_data, 12', pin_signal: GPIO_B1_00, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: B11, peripheral: LCDIF, signal: 'lcdif_data, 13', pin_signal: GPIO_B1_01, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: C11, peripheral: LCDIF, signal: 'lcdif_data, 14', pin_signal: GPIO_B1_02, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: D11, peripheral: LCDIF, signal: 'lcdif_data, 15', pin_signal: GPIO_B1_03, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: E7, peripheral: LCDIF, signal: lcdif_enable, pin_signal: GPIO_B0_01, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: E8, peripheral: LCDIF, signal: lcdif_hsync, pin_signal: GPIO_B0_02, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: D8, peripheral: LCDIF, signal: lcdif_vsync, pin_signal: GPIO_B0_03, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: B14, peripheral: GPIO2, signal: 'gpio_io, 31', pin_signal: GPIO_B1_15, slew_rate: Slow} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitLCDPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitLCDPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_00_LCD_CLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_01_LCD_ENABLE, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_02_LCD_HSYNC, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_03_LCD_VSYNC, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_04_LCD_DATA00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_05_LCD_DATA01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_06_LCD_DATA02, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_07_LCD_DATA03, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_08_LCD_DATA04, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_09_LCD_DATA05, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_10_LCD_DATA06, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_11_LCD_DATA07, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_12_LCD_DATA08, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_13_LCD_DATA09, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_14_LCD_DATA10, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_15_LCD_DATA11, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_00_LCD_DATA12, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_01_LCD_DATA13, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_02_LCD_DATA14, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_03_LCD_DATA15, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_15_GPIO2_IO31, 0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_00_LCD_CLK, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_01_LCD_ENABLE, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_02_LCD_HSYNC, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_03_LCD_VSYNC, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_04_LCD_DATA00, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_05_LCD_DATA01, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_06_LCD_DATA02, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_07_LCD_DATA03, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_08_LCD_DATA04, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_09_LCD_DATA05, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_10_LCD_DATA06, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_11_LCD_DATA07, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_12_LCD_DATA08, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_13_LCD_DATA09, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_14_LCD_DATA10, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_15_LCD_DATA11, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_00_LCD_DATA12, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_01_LCD_DATA13, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_02_LCD_DATA14, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_03_LCD_DATA15, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_15_GPIO2_IO31, 0x10B0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitCANPins: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: H14, peripheral: CAN2, signal: TX, pin_signal: GPIO_AD_B0_14} + - {pin_num: L10, peripheral: CAN2, signal: RX, pin_signal: GPIO_AD_B0_15} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitCANPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitCANPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_14_FLEXCAN2_TX, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_15_FLEXCAN2_RX, 0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitENETPins: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: A7, peripheral: ENET, signal: enet_mdc, pin_signal: GPIO_EMC_40} + - {pin_num: C7, peripheral: ENET, signal: enet_mdio, pin_signal: GPIO_EMC_41} + - {pin_num: B13, peripheral: ENET, signal: enet_ref_clk, pin_signal: GPIO_B1_10} + - {pin_num: E12, peripheral: ENET, signal: 'enet_rx_data, 0', pin_signal: GPIO_B1_04} + - {pin_num: D12, peripheral: ENET, signal: 'enet_rx_data, 1', pin_signal: GPIO_B1_05} + - {pin_num: C12, peripheral: ENET, signal: enet_rx_en, pin_signal: GPIO_B1_06} + - {pin_num: C13, peripheral: ENET, signal: enet_rx_er, pin_signal: GPIO_B1_11} + - {pin_num: B12, peripheral: ENET, signal: 'enet_tx_data, 0', pin_signal: GPIO_B1_07} + - {pin_num: A12, peripheral: ENET, signal: 'enet_tx_data, 1', pin_signal: GPIO_B1_08} + - {pin_num: A13, peripheral: ENET, signal: enet_tx_en, pin_signal: GPIO_B1_09} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitENETPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitENETPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_04_ENET_RX_DATA00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_05_ENET_RX_DATA01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_06_ENET_RX_EN, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_07_ENET_TX_DATA00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_08_ENET_TX_DATA01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_09_ENET_TX_EN, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_10_ENET_REF_CLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_11_ENET_RX_ER, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_40_ENET_MDC, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_41_ENET_MDIO, 0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitUSDHCPins: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: J2, peripheral: USDHC1, signal: 'usdhc_data, 3', pin_signal: GPIO_SD_B0_05} + - {pin_num: H2, peripheral: USDHC1, signal: 'usdhc_data, 2', pin_signal: GPIO_SD_B0_04} + - {pin_num: K1, peripheral: USDHC1, signal: 'usdhc_data, 1', pin_signal: GPIO_SD_B0_03} + - {pin_num: J1, peripheral: USDHC1, signal: 'usdhc_data, 0', pin_signal: GPIO_SD_B0_02} + - {pin_num: J4, peripheral: USDHC1, signal: usdhc_cmd, pin_signal: GPIO_SD_B0_00} + - {pin_num: J3, peripheral: USDHC1, signal: usdhc_clk, pin_signal: GPIO_SD_B0_01} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitUSDHCPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitUSDHCPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_00_USDHC1_CMD, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_01_USDHC1_CLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_02_USDHC1_DATA0, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_03_USDHC1_DATA1, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_04_USDHC1_DATA2, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_05_USDHC1_DATA3, 0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitHyperFlashPins: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: L4, peripheral: FLEXSPI, signal: FLEXSPI_A_SCLK, pin_signal: GPIO_SD_B1_07} + - {pin_num: P4, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA2, pin_signal: GPIO_SD_B1_10} + - {pin_num: P3, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA0, pin_signal: GPIO_SD_B1_08} + - {pin_num: N4, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA1, pin_signal: GPIO_SD_B1_09} + - {pin_num: L5, peripheral: FLEXSPI, signal: FLEXSPI_B_DATA3, pin_signal: GPIO_SD_B1_00} + - {pin_num: M5, peripheral: FLEXSPI, signal: FLEXSPI_B_DATA2, pin_signal: GPIO_SD_B1_01} + - {pin_num: M3, peripheral: FLEXSPI, signal: FLEXSPI_B_DATA1, pin_signal: GPIO_SD_B1_02} + - {pin_num: M4, peripheral: FLEXSPI, signal: FLEXSPI_B_DATA0, pin_signal: GPIO_SD_B1_03} + - {pin_num: P2, peripheral: FLEXSPI, signal: FLEXSPI_B_SCLK, pin_signal: GPIO_SD_B1_04} + - {pin_num: L3, peripheral: FLEXSPI, signal: FLEXSPI_A_SS0_B, pin_signal: GPIO_SD_B1_06} + - {pin_num: P5, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA3, pin_signal: GPIO_SD_B1_11} + - {pin_num: N3, peripheral: FLEXSPI, signal: FLEXSPI_A_DQS, pin_signal: GPIO_SD_B1_05} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitHyperFlashPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitHyperFlashPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_00_FLEXSPI_B_DATA3, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_00_FLEXSPIB_DATA03, 0U); +#endif +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_01_FLEXSPI_B_DATA2, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_01_FLEXSPIB_DATA02, 0U); +#endif +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_02_FLEXSPI_B_DATA1, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_02_FLEXSPIB_DATA01, 0U); +#endif +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_03_FLEXSPI_B_DATA0, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_03_FLEXSPIB_DATA00, 0U); +#endif +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_04_FLEXSPI_B_SCLK, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_04_FLEXSPIB_SCLK, 0U); +#endif +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_05_FLEXSPI_A_DQS, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_05_FLEXSPIA_DQS, 0U); +#endif +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_06_FLEXSPI_A_SS0_B, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_06_FLEXSPIA_SS0_B, 0U); +#endif +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_07_FLEXSPI_A_SCLK, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_07_FLEXSPIA_SCLK, 0U); +#endif +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_08_FLEXSPI_A_DATA00, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_08_FLEXSPIA_DATA00, 0U); +#endif +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_09_FLEXSPI_A_DATA1, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_09_FLEXSPIA_DATA01, 0U); +#endif +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_10_FLEXSPI_A_DATA2, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_10_FLEXSPIA_DATA02, 0U); +#endif +#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3) + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_11_FLEXSPI_A_DATA3, 0U); +#else + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_11_FLEXSPIA_DATA03, 0U); +#endif +} + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/imxrt/boards/mimxrt1050_evkb/board/pin_mux.h b/hw/bsp/imxrt/boards/mimxrt1050_evkb/board/pin_mux.h new file mode 100644 index 000000000..3d3a7a93c --- /dev/null +++ b/hw/bsp/imxrt/boards/mimxrt1050_evkb/board/pin_mux.h @@ -0,0 +1,761 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _PIN_MUX_H_ +#define _PIN_MUX_H_ + +/*********************************************************************************************************************** + * Definitions + **********************************************************************************************************************/ + +/*! @brief Direction type */ +typedef enum _pin_mux_direction +{ + kPIN_MUX_DirectionInput = 0U, /* Input direction */ + kPIN_MUX_DirectionOutput = 1U, /* Output direction */ + kPIN_MUX_DirectionInputOrOutput = 2U /* Input or output direction */ +} pin_mux_direction_t; + +/*! + * @addtogroup pin_mux + * @{ + */ + +/*********************************************************************************************************************** + * API + **********************************************************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Calls initialization functions. + * + */ +void BOARD_InitBootPins(void); + +/* GPIO_AD_B0_09 (coord F14), JTAG_TDI/J21[5]/ENET_RST/J22[5] */ +/* Routed pin properties */ +#define BOARD_INITPINS_USER_LED_PERIPHERAL GPIO1 /*!< Peripheral name */ +#define BOARD_INITPINS_USER_LED_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITPINS_USER_LED_CHANNEL 9U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_USER_LED_GPIO GPIO1 /*!< GPIO peripheral base pointer */ +#define BOARD_INITPINS_USER_LED_GPIO_PIN 9U /*!< GPIO pin number */ +#define BOARD_INITPINS_USER_LED_GPIO_PIN_MASK (1U << 9U) /*!< GPIO pin mask */ +#define BOARD_INITPINS_USER_LED_PORT GPIO1 /*!< PORT peripheral base pointer */ +#define BOARD_INITPINS_USER_LED_PIN 9U /*!< PORT pin number */ +#define BOARD_INITPINS_USER_LED_PIN_MASK (1U << 9U) /*!< PORT pin mask */ + +/* WAKEUP (coord L6), SD_PWREN */ +/* Routed pin properties */ +#define BOARD_INITPINS_USER_BUTTON_PERIPHERAL GPIO5 /*!< Peripheral name */ +#define BOARD_INITPINS_USER_BUTTON_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITPINS_USER_BUTTON_CHANNEL 0U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_USER_BUTTON_GPIO GPIO5 /*!< GPIO peripheral base pointer */ +#define BOARD_INITPINS_USER_BUTTON_GPIO_PIN 0U /*!< GPIO pin number */ +#define BOARD_INITPINS_USER_BUTTON_GPIO_PIN_MASK (1U << 0U) /*!< GPIO pin mask */ +#define BOARD_INITPINS_USER_BUTTON_PORT GPIO5 /*!< PORT peripheral base pointer */ +#define BOARD_INITPINS_USER_BUTTON_PIN 0U /*!< PORT pin number */ +#define BOARD_INITPINS_USER_BUTTON_PIN_MASK (1U << 0U) /*!< PORT pin mask */ + + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitPins(void); + +/* GPIO_AD_B0_12 (coord K14), UART1_TXD */ +/* Routed pin properties */ +#define BOARD_INITDEBUG_UARTPINS_UART1_TXD_PERIPHERAL LPUART1 /*!< Peripheral name */ +#define BOARD_INITDEBUG_UARTPINS_UART1_TXD_SIGNAL TX /*!< Signal name */ + +/* GPIO_AD_B0_13 (coord L14), UART1_RXD */ +/* Routed pin properties */ +#define BOARD_INITDEBUG_UARTPINS_UART1_RXD_PERIPHERAL LPUART1 /*!< Peripheral name */ +#define BOARD_INITDEBUG_UARTPINS_UART1_RXD_SIGNAL RX /*!< Signal name */ + + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitDEBUG_UARTPins(void); + +/* GPIO_EMC_09 (coord C2), SEMC_A0 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A0_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A0_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_EMC_10 (coord G1), SEMC_A1 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A1_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A1_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_EMC_11 (coord G3), SEMC_A2 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A2_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A2_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A2_CHANNEL 2U /*!< Signal channel */ + +/* GPIO_EMC_12 (coord H1), SEMC_A3 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A3_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A3_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A3_CHANNEL 3U /*!< Signal channel */ + +/* GPIO_EMC_13 (coord A6), SEMC_A4 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A4_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A4_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A4_CHANNEL 4U /*!< Signal channel */ + +/* GPIO_EMC_14 (coord B6), SEMC_A5 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A5_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A5_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A5_CHANNEL 5U /*!< Signal channel */ + +/* GPIO_EMC_15 (coord B1), SEMC_A6 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A6_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A6_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A6_CHANNEL 6U /*!< Signal channel */ + +/* GPIO_EMC_16 (coord A5), SEMC_A7 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A7_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A7_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A7_CHANNEL 7U /*!< Signal channel */ + +/* GPIO_EMC_17 (coord A4), SEMC_A8 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A8_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A8_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A8_CHANNEL 8U /*!< Signal channel */ + +/* GPIO_EMC_18 (coord B2), SEMC_A9 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A9_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A9_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A9_CHANNEL 9U /*!< Signal channel */ + +/* GPIO_EMC_23 (coord G2), SEMC_A10 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A10_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A10_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A10_CHANNEL 10U /*!< Signal channel */ + +/* GPIO_EMC_19 (coord B4), SEMC_A11 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A11_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A11_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A11_CHANNEL 11U /*!< Signal channel */ + +/* GPIO_EMC_20 (coord A3), SEMC_A12 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A12_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A12_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A12_CHANNEL 12U /*!< Signal channel */ + +/* GPIO_EMC_21 (coord C1), SEMC_BA0 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_BA0_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_BA0_SIGNAL BA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_BA0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_EMC_22 (coord F1), SEMC_BA1 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_BA1_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_BA1_SIGNAL BA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_BA1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_EMC_24 (coord D3), SEMC_CAS */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_CAS_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_CAS_SIGNAL semc_cas /*!< Signal name */ + +/* GPIO_EMC_27 (coord A2), SEMC_CKE */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_CKE_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_CKE_SIGNAL semc_cke /*!< Signal name */ + +/* GPIO_EMC_26 (coord B3), SEMC_CLK */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_CLK_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_CLK_SIGNAL semc_clk /*!< Signal name */ + +/* GPIO_EMC_00 (coord E3), SEMC_D0 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D0_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D0_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_EMC_01 (coord F3), SEMC_D1 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D1_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D1_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_EMC_02 (coord F4), SEMC_D2 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D2_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D2_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D2_CHANNEL 2U /*!< Signal channel */ + +/* GPIO_EMC_03 (coord G4), SEMC_D3 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D3_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D3_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D3_CHANNEL 3U /*!< Signal channel */ + +/* GPIO_EMC_04 (coord F2), SEMC_D4 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D4_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D4_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D4_CHANNEL 4U /*!< Signal channel */ + +/* GPIO_EMC_05 (coord G5), SEMC_D5 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D5_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D5_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D5_CHANNEL 5U /*!< Signal channel */ + +/* GPIO_EMC_06 (coord H5), SEMC_D6 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D6_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D6_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D6_CHANNEL 6U /*!< Signal channel */ + +/* GPIO_EMC_07 (coord H4), SEMC_D7 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D7_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D7_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D7_CHANNEL 7U /*!< Signal channel */ + +/* GPIO_EMC_30 (coord C6), SEMC_D8 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D8_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D8_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D8_CHANNEL 8U /*!< Signal channel */ + +/* GPIO_EMC_31 (coord C5), SEMC_D9 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D9_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D9_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D9_CHANNEL 9U /*!< Signal channel */ + +/* GPIO_EMC_32 (coord D5), SEMC_D10 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D10_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D10_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D10_CHANNEL 10U /*!< Signal channel */ + +/* GPIO_EMC_33 (coord C4), SEMC_D11 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D11_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D11_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D11_CHANNEL 11U /*!< Signal channel */ + +/* GPIO_EMC_34 (coord D4), SEMC_D12 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D12_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D12_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D12_CHANNEL 12U /*!< Signal channel */ + +/* GPIO_EMC_35 (coord E5), SEMC_D13 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D13_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D13_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D13_CHANNEL 13U /*!< Signal channel */ + +/* GPIO_EMC_36 (coord C3), SEMC_D14 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D14_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D14_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D14_CHANNEL 14U /*!< Signal channel */ + +/* GPIO_EMC_37 (coord E4), SEMC_D15 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D15_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D15_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D15_CHANNEL 15U /*!< Signal channel */ + +/* GPIO_EMC_08 (coord H3), SEMC_DM0 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_DM0_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_DM0_SIGNAL DM /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_DM0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_EMC_38 (coord D6), SEMC_DM1 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_DM1_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_DM1_SIGNAL DM /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_DM1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_EMC_25 (coord D2), SEMC_RAS */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_RAS_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_RAS_SIGNAL semc_ras /*!< Signal name */ + +/* GPIO_EMC_28 (coord D1), SEMC_WE */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_WE_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_WE_SIGNAL semc_we /*!< Signal name */ + +/* GPIO_EMC_41 (coord C7), ENET_MDIO */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_ENET_MDIO_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_ENET_MDIO_SIGNAL CSX /*!< Signal name */ +#define BOARD_INITSDRAMPINS_ENET_MDIO_CHANNEL 0U /*!< Signal channel */ + + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitSDRAMPins(void); + +/* GPIO_AD_B1_08 (coord H13), AUD_INT/CSI_D9//J35[13]/J22[4] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_D9_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_D9_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSIPINS_CSI_D9_CHANNEL 9U /*!< Signal channel */ + +/* GPIO_AD_B1_09 (coord M13), SAI1_MCLK/CSI_D8/J35[11] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_D8_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_D8_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSIPINS_CSI_D8_CHANNEL 8U /*!< Signal channel */ + +/* GPIO_AD_B1_10 (coord L13), SAI1_RX_SYNC/CSI_D7/J35[9]/J23[1] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_D7_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_D7_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSIPINS_CSI_D7_CHANNEL 7U /*!< Signal channel */ + +/* GPIO_AD_B1_11 (coord J13), SAI1_RX_BCLK/CSI_D6/J35[7]/J23[2] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_D6_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_D6_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSIPINS_CSI_D6_CHANNEL 6U /*!< Signal channel */ + +/* GPIO_AD_B1_12 (coord H12), SAI1_RXD/CSI_D5/J35[5]/U13[16] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_D5_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_D5_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSIPINS_CSI_D5_CHANNEL 5U /*!< Signal channel */ + +/* GPIO_AD_B1_13 (coord H11), SAI1_TXD/CSI_D4/J35[3]/U13[14] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_D4_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_D4_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSIPINS_CSI_D4_CHANNEL 4U /*!< Signal channel */ + +/* GPIO_AD_B1_15 (coord J14), SAI1_TX_SYNC/CSI_D2/J35[6]/U13[13] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_D2_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_D2_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSIPINS_CSI_D2_CHANNEL 2U /*!< Signal channel */ + +/* GPIO_AD_B1_14 (coord G12), SAI1_TX_BCLK/CSI_D3/J35[4]/U13[12] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_D3_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_D3_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSIPINS_CSI_D3_CHANNEL 3U /*!< Signal channel */ + +/* GPIO_AD_B1_04 (coord L12), CSI_PIXCLK/J35[8]/J23[3] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_PIXCLK_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_PIXCLK_SIGNAL csi_pixclk /*!< Signal name */ + +/* GPIO_AD_B1_05 (coord K12), CSI_MCLK/J35[12]/J23[4] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_MCLK_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_MCLK_SIGNAL csi_mclk /*!< Signal name */ + +/* GPIO_AD_B1_06 (coord J12), CSI_VSYNC/J35[18]/J22[2]/UART_TX */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_VSYNC_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_VSYNC_SIGNAL csi_vsync /*!< Signal name */ + +/* GPIO_AD_B1_07 (coord K10), CSI_HSYNC/J35[16]/J22[1]/UART_RX */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_HSYNC_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_HSYNC_SIGNAL csi_hsync /*!< Signal name */ + +/* GPIO_AD_B1_00 (coord J11), I2C1_SCL/CSI_I2C_SCL/J35[20]/J23[6]/U13[17]/U32[4] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_I2C_SCL_PERIPHERAL LPI2C1 /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_I2C_SCL_SIGNAL SCL /*!< Signal name */ + +/* GPIO_AD_B1_01 (coord K11), I2C1_SDA/CSI_I2C_SDA/J35[22]/J23[5]/U13[18]/U32[6] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_I2C_SDA_PERIPHERAL LPI2C1 /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_I2C_SDA_SIGNAL SDA /*!< Signal name */ + +/* GPIO_AD_B0_04 (coord F11), CSI_PWDN/J35[17]/BOOT_MODE[0] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_PWDN_PERIPHERAL GPIO1 /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_PWDN_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITCSIPINS_CSI_PWDN_CHANNEL 4U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITCSIPINS_CSI_PWDN_GPIO GPIO1 /*!< GPIO peripheral base pointer */ +#define BOARD_INITCSIPINS_CSI_PWDN_GPIO_PIN 4U /*!< GPIO pin number */ +#define BOARD_INITCSIPINS_CSI_PWDN_GPIO_PIN_MASK (1U << 4U) /*!< GPIO pin mask */ +#define BOARD_INITCSIPINS_CSI_PWDN_PORT GPIO1 /*!< PORT peripheral base pointer */ +#define BOARD_INITCSIPINS_CSI_PWDN_PIN 4U /*!< PORT pin number */ +#define BOARD_INITCSIPINS_CSI_PWDN_PIN_MASK (1U << 4U) /*!< PORT pin mask */ + + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitCSIPins(void); + +/* GPIO_B0_04 (coord C8), LCDIF_D0/BT_CFG[0] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D0_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D0_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_B0_05 (coord B8), LCDIF_D1/BT_CFG[1] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D1_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D1_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_B0_06 (coord A8), LCDIF_D2/BT_CFG[2] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D2_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D2_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D2_CHANNEL 2U /*!< Signal channel */ + +/* GPIO_B0_00 (coord D7), LCDIF_CLK */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_CLK_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_CLK_SIGNAL lcdif_clk /*!< Signal name */ + +/* GPIO_B0_07 (coord A9), LCDIF_D3/BT_CFG[3] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D3_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D3_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D3_CHANNEL 3U /*!< Signal channel */ + +/* GPIO_B0_08 (coord B9), LCDIF_D4/BT_CFG[4] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D4_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D4_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D4_CHANNEL 4U /*!< Signal channel */ + +/* GPIO_B0_09 (coord C9), LCDIF_D5/BT_CFG[5] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D5_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D5_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D5_CHANNEL 5U /*!< Signal channel */ + +/* GPIO_B0_10 (coord D9), LCDIF_D6/BT_CFG[6] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D6_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D6_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D6_CHANNEL 6U /*!< Signal channel */ + +/* GPIO_B0_11 (coord A10), LCDIF_D7/BT_CFG[7] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D7_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D7_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D7_CHANNEL 7U /*!< Signal channel */ + +/* GPIO_B0_12 (coord C10), LCDIF_D8/BT_CFG[8] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D8_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D8_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D8_CHANNEL 8U /*!< Signal channel */ + +/* GPIO_B0_13 (coord D10), LCDIF_D9/BT_CFG[9] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D9_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D9_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D9_CHANNEL 9U /*!< Signal channel */ + +/* GPIO_B0_14 (coord E10), LCDIF_D10/BT_CFG[10] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D10_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D10_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D10_CHANNEL 10U /*!< Signal channel */ + +/* GPIO_B0_15 (coord E11), LCDIF_D11/BT_CFG[11] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D11_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D11_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D11_CHANNEL 11U /*!< Signal channel */ + +/* GPIO_B1_00 (coord A11), LCDIF_D12 */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D12_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D12_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D12_CHANNEL 12U /*!< Signal channel */ + +/* GPIO_B1_01 (coord B11), LCDIF_D13 */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D13_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D13_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D13_CHANNEL 13U /*!< Signal channel */ + +/* GPIO_B1_02 (coord C11), LCDIF_D14 */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D14_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D14_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D14_CHANNEL 14U /*!< Signal channel */ + +/* GPIO_B1_03 (coord D11), LCDIF_D15 */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D15_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D15_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D15_CHANNEL 15U /*!< Signal channel */ + +/* GPIO_B0_01 (coord E7), LCDIF_ENABLE */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_ENABLE_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_ENABLE_SIGNAL lcdif_enable /*!< Signal name */ + +/* GPIO_B0_02 (coord E8), LCDIF_HSYNC */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_HSYNC_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_HSYNC_SIGNAL lcdif_hsync /*!< Signal name */ + +/* GPIO_B0_03 (coord D8), LCDIF_VSYNC */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_VSYNC_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_VSYNC_SIGNAL lcdif_vsync /*!< Signal name */ + +/* GPIO_B1_15 (coord B14), USB_HOST_PWR/BACKLIGHT_CTL */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_BACKLIGHT_CTL_PERIPHERAL GPIO2 /*!< Peripheral name */ +#define BOARD_INITLCDPINS_BACKLIGHT_CTL_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITLCDPINS_BACKLIGHT_CTL_CHANNEL 31U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITLCDPINS_BACKLIGHT_CTL_GPIO GPIO2 /*!< GPIO peripheral base pointer */ +#define BOARD_INITLCDPINS_BACKLIGHT_CTL_GPIO_PIN 31U /*!< GPIO pin number */ +#define BOARD_INITLCDPINS_BACKLIGHT_CTL_GPIO_PIN_MASK (1U << 31U) /*!< GPIO pin mask */ +#define BOARD_INITLCDPINS_BACKLIGHT_CTL_PORT GPIO2 /*!< PORT peripheral base pointer */ +#define BOARD_INITLCDPINS_BACKLIGHT_CTL_PIN 31U /*!< PORT pin number */ +#define BOARD_INITLCDPINS_BACKLIGHT_CTL_PIN_MASK (1U << 31U) /*!< PORT pin mask */ + + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitLCDPins(void); + +/* GPIO_AD_B0_14 (coord H14), CAN2_TX/U12[1] */ +/* Routed pin properties */ +#define BOARD_INITCANPINS_CAN2_TX_PERIPHERAL CAN2 /*!< Peripheral name */ +#define BOARD_INITCANPINS_CAN2_TX_SIGNAL TX /*!< Signal name */ + +/* GPIO_AD_B0_15 (coord L10), CAN2_RX/U12[4] */ +/* Routed pin properties */ +#define BOARD_INITCANPINS_CAN2_RX_PERIPHERAL CAN2 /*!< Peripheral name */ +#define BOARD_INITCANPINS_CAN2_RX_SIGNAL RX /*!< Signal name */ + + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitCANPins(void); + +/* GPIO_EMC_40 (coord A7), ENET_MDC */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_MDC_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_MDC_SIGNAL enet_mdc /*!< Signal name */ + +/* GPIO_EMC_41 (coord C7), ENET_MDIO */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_MDIO_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_MDIO_SIGNAL enet_mdio /*!< Signal name */ + +/* GPIO_B1_10 (coord B13), ENET_TX_CLK */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_TX_CLK_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_TX_CLK_SIGNAL enet_ref_clk /*!< Signal name */ + +/* GPIO_B1_04 (coord E12), ENET_RXD0 */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_RXD0_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_RXD0_SIGNAL enet_rx_data /*!< Signal name */ +#define BOARD_INITENETPINS_ENET_RXD0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_B1_05 (coord D12), ENET_RXD1 */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_RXD1_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_RXD1_SIGNAL enet_rx_data /*!< Signal name */ +#define BOARD_INITENETPINS_ENET_RXD1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_B1_06 (coord C12), ENET_CRS_DV */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_CRS_DV_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_CRS_DV_SIGNAL enet_rx_en /*!< Signal name */ + +/* GPIO_B1_11 (coord C13), ENET_RXER */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_RXER_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_RXER_SIGNAL enet_rx_er /*!< Signal name */ + +/* GPIO_B1_07 (coord B12), ENET_TXD0 */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_TXD0_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_TXD0_SIGNAL enet_tx_data /*!< Signal name */ +#define BOARD_INITENETPINS_ENET_TXD0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_B1_08 (coord A12), ENET_TXD1 */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_TXD1_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_TXD1_SIGNAL enet_tx_data /*!< Signal name */ +#define BOARD_INITENETPINS_ENET_TXD1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_B1_09 (coord A13), ENET_TXEN */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_TXEN_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_TXEN_SIGNAL enet_tx_en /*!< Signal name */ + + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitENETPins(void); + +/* GPIO_SD_B0_05 (coord J2), SD1_D3 */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_D3_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_D3_SIGNAL usdhc_data /*!< Signal name */ +#define BOARD_INITUSDHCPINS_SD1_D3_CHANNEL 3U /*!< Signal channel */ + +/* GPIO_SD_B0_04 (coord H2), SD1_D2 */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_D2_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_D2_SIGNAL usdhc_data /*!< Signal name */ +#define BOARD_INITUSDHCPINS_SD1_D2_CHANNEL 2U /*!< Signal channel */ + +/* GPIO_SD_B0_03 (coord K1), SD1_D1/J24[5]/SPI_MISO */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_D1_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_D1_SIGNAL usdhc_data /*!< Signal name */ +#define BOARD_INITUSDHCPINS_SD1_D1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_SD_B0_02 (coord J1), SD1_D0/J24[4]/SPI_MOSI/PWM */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_D0_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_D0_SIGNAL usdhc_data /*!< Signal name */ +#define BOARD_INITUSDHCPINS_SD1_D0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_SD_B0_00 (coord J4), SD1_CMD/J24[6] */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_CMD_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_CMD_SIGNAL usdhc_cmd /*!< Signal name */ + +/* GPIO_SD_B0_01 (coord J3), SD1_CLK/J24[3] */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_CLK_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_CLK_SIGNAL usdhc_clk /*!< Signal name */ + + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitUSDHCPins(void); + +/* GPIO_SD_B1_07 (coord L4), FlexSPI_CLK */ +/* Routed pin properties */ +#define BOARD_INITHYPERFLASHPINS_FlexSPI_CLK_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITHYPERFLASHPINS_FlexSPI_CLK_SIGNAL FLEXSPI_A_SCLK /*!< Signal name */ + +/* GPIO_SD_B1_10 (coord P4), FlexSPI_D2_A */ +/* Routed pin properties */ +#define BOARD_INITHYPERFLASHPINS_FlexSPI_D2_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITHYPERFLASHPINS_FlexSPI_D2_A_SIGNAL FLEXSPI_A_DATA2 /*!< Signal name */ + +/* GPIO_SD_B1_08 (coord P3), FlexSPI_D0_A */ +/* Routed pin properties */ +#define BOARD_INITHYPERFLASHPINS_FlexSPI_D0_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITHYPERFLASHPINS_FlexSPI_D0_A_SIGNAL FLEXSPI_A_DATA0 /*!< Signal name */ + +/* GPIO_SD_B1_09 (coord N4), FlexSPI_D1_A */ +/* Routed pin properties */ +#define BOARD_INITHYPERFLASHPINS_FlexSPI_D1_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITHYPERFLASHPINS_FlexSPI_D1_A_SIGNAL FLEXSPI_A_DATA1 /*!< Signal name */ + +/* GPIO_SD_B1_00 (coord L5), FlexSPI_D3_B */ +/* Routed pin properties */ +#define BOARD_INITHYPERFLASHPINS_FlexSPI_D3_B_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITHYPERFLASHPINS_FlexSPI_D3_B_SIGNAL FLEXSPI_B_DATA3 /*!< Signal name */ + +/* GPIO_SD_B1_01 (coord M5), FlexSPI_D2_B */ +/* Routed pin properties */ +#define BOARD_INITHYPERFLASHPINS_FlexSPI_D2_B_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITHYPERFLASHPINS_FlexSPI_D2_B_SIGNAL FLEXSPI_B_DATA2 /*!< Signal name */ + +/* GPIO_SD_B1_02 (coord M3), FlexSPI_D1_B */ +/* Routed pin properties */ +#define BOARD_INITHYPERFLASHPINS_FlexSPI_D1_B_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITHYPERFLASHPINS_FlexSPI_D1_B_SIGNAL FLEXSPI_B_DATA1 /*!< Signal name */ + +/* GPIO_SD_B1_03 (coord M4), FlexSPI_D0_B */ +/* Routed pin properties */ +#define BOARD_INITHYPERFLASHPINS_FlexSPI_D0_B_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITHYPERFLASHPINS_FlexSPI_D0_B_SIGNAL FLEXSPI_B_DATA0 /*!< Signal name */ + +/* GPIO_SD_B1_04 (coord P2), FlexSPI_CLK_B */ +/* Routed pin properties */ +#define BOARD_INITHYPERFLASHPINS_FlexSPI_CLK_B_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITHYPERFLASHPINS_FlexSPI_CLK_B_SIGNAL FLEXSPI_B_SCLK /*!< Signal name */ + +/* GPIO_SD_B1_06 (coord L3), FlexSPI_SS0 */ +/* Routed pin properties */ +#define BOARD_INITHYPERFLASHPINS_FlexSPI_SS0_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITHYPERFLASHPINS_FlexSPI_SS0_SIGNAL FLEXSPI_A_SS0_B /*!< Signal name */ + +/* GPIO_SD_B1_11 (coord P5), FlexSPI_D3_A */ +/* Routed pin properties */ +#define BOARD_INITHYPERFLASHPINS_FlexSPI_D3_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITHYPERFLASHPINS_FlexSPI_D3_A_SIGNAL FLEXSPI_A_DATA3 /*!< Signal name */ + +/* GPIO_SD_B1_05 (coord N3), FlexSPI_DQS */ +/* Routed pin properties */ +#define BOARD_INITHYPERFLASHPINS_FlexSPI_DQS_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITHYPERFLASHPINS_FlexSPI_DQS_SIGNAL FLEXSPI_A_DQS /*!< Signal name */ + + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitHyperFlashPins(void); + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif /* _PIN_MUX_H_ */ + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/imxrt/boards/mimxrt1050_evkb/mimxrt1050_evkb.mex b/hw/bsp/imxrt/boards/mimxrt1050_evkb/mimxrt1050_evkb.mex index c0a5b5660..6bdfd46a1 100644 --- a/hw/bsp/imxrt/boards/mimxrt1050_evkb/mimxrt1050_evkb.mex +++ b/hw/bsp/imxrt/boards/mimxrt1050_evkb/mimxrt1050_evkb.mex @@ -26,6 +26,10 @@ 13.0.2 + + + + @@ -37,13 +41,41 @@ true + + + true + + true + + + true + + + + + true + + - + + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. @@ -712,7 +744,7 @@ - + diff --git a/hw/bsp/imxrt/boards/mimxrt1060_evk/board.h b/hw/bsp/imxrt/boards/mimxrt1060_evk/board.h index 0f45f72e1..40b99860f 100644 --- a/hw/bsp/imxrt/boards/mimxrt1060_evk/board.h +++ b/hw/bsp/imxrt/boards/mimxrt1060_evk/board.h @@ -24,28 +24,24 @@ * This file is part of the TinyUSB stack. */ +#ifndef BOARD_MIMXRT1060_EVKB_H_ +#define BOARD_MIMXRT1060_EVKB_H_ -#ifndef BOARD_H_ -#define BOARD_H_ - -// required since iMX RT10xx SDK include this file for board size +// required since iMXRT MCUX-SDK include this file for board size #define BOARD_FLASH_SIZE (0x800000U) -// LED -#define LED_PINMUX IOMUXC_GPIO_AD_B0_09_GPIO1_IO09 -#define LED_PORT GPIO1 -#define LED_PIN 9 +// LED: IOMUXC_GPIO_AD_B0_09_GPIO1_IO09 +#define LED_PORT BOARD_INITPINS_USER_LED_PERIPHERAL +#define LED_PIN BOARD_INITPINS_USER_LED_CHANNEL #define LED_STATE_ON 0 -// SW8 button -#define BUTTON_PINMUX IOMUXC_SNVS_WAKEUP_GPIO5_IO00 -#define BUTTON_PORT GPIO5 -#define BUTTON_PIN 0 +// SW8 button: IOMUXC_SNVS_WAKEUP_GPIO5_IO00 +#define BUTTON_PORT BOARD_INITPINS_USER_BUTTON_PERIPHERAL +#define BUTTON_PIN BOARD_INITPINS_USER_BUTTON_CHANNEL #define BUTTON_STATE_ACTIVE 0 -// UART +// UART: IOMUXC_GPIO_AD_B0_13_LPUART1_RX, IOMUXC_GPIO_AD_B0_12_LPUART1_TX #define UART_PORT LPUART1 -#define UART_RX_PINMUX IOMUXC_GPIO_AD_B0_13_LPUART1_RX -#define UART_TX_PINMUX IOMUXC_GPIO_AD_B0_12_LPUART1_TX +#define UART_CLK_ROOT BOARD_BOOTCLOCKRUN_UART_CLK_ROOT -#endif /* BOARD_H_ */ +#endif diff --git a/hw/bsp/imxrt/boards/mimxrt1060_evk/board/pin_mux.c b/hw/bsp/imxrt/boards/mimxrt1060_evk/board/pin_mux.c new file mode 100644 index 000000000..5d679709e --- /dev/null +++ b/hw/bsp/imxrt/boards/mimxrt1060_evk/board/pin_mux.c @@ -0,0 +1,497 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Pins v13.1 +processor: MIMXRT1062xxxxA +package_id: MIMXRT1062DVL6A +mcu_data: ksdk2_0 +processor_version: 13.0.2 +board: MIMXRT1060-EVK +pin_labels: +- {pin_num: F14, pin_signal: GPIO_AD_B0_09, label: 'JTAG_TDI/J21[5]/ENET_RST/J22[5]', identifier: USER_LED} +- {pin_num: L6, pin_signal: WAKEUP, label: SD_PWREN, identifier: USER_BUTTON} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +#include "fsl_common.h" +#include "fsl_iomuxc.h" +#include "fsl_gpio.h" +#include "pin_mux.h" + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitBootPins + * Description : Calls initialization functions. + * + * END ****************************************************************************************************************/ +void BOARD_InitBootPins(void) { + BOARD_InitPins(); + BOARD_InitDEBUG_UARTPins(); +} + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitPins: +- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: F14, peripheral: GPIO1, signal: 'gpio_io, 09', pin_signal: GPIO_AD_B0_09, direction: OUTPUT, pull_keeper_select: Keeper} + - {pin_num: L6, peripheral: GPIO5, signal: 'gpio_io, 00', pin_signal: WAKEUP, direction: INPUT} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + CLOCK_EnableClock(kCLOCK_IomuxcSnvs); + + /* GPIO configuration of USER_LED on GPIO_AD_B0_09 (pin F14) */ + gpio_pin_config_t USER_LED_config = { + .direction = kGPIO_DigitalOutput, + .outputLogic = 0U, + .interruptMode = kGPIO_NoIntmode + }; + /* Initialize GPIO functionality on GPIO_AD_B0_09 (pin F14) */ + GPIO_PinInit(GPIO1, 9U, &USER_LED_config); + + /* GPIO configuration of USER_BUTTON on WAKEUP (pin L6) */ + gpio_pin_config_t USER_BUTTON_config = { + .direction = kGPIO_DigitalInput, + .outputLogic = 0U, + .interruptMode = kGPIO_NoIntmode + }; + /* Initialize GPIO functionality on WAKEUP (pin L6) */ + GPIO_PinInit(GPIO5, 0U, &USER_BUTTON_config); + + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, 0U); + IOMUXC_GPR->GPR26 = ((IOMUXC_GPR->GPR26 & + (~(BOARD_INITPINS_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK))) + | IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL(0x00U) + ); + IOMUXC_SetPinMux(IOMUXC_SNVS_WAKEUP_GPIO5_IO00, 0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, 0x50A0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitDEBUG_UARTPins: +- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: K14, peripheral: LPUART1, signal: TX, pin_signal: GPIO_AD_B0_12, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Down_100K_Ohm, + pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} + - {pin_num: L14, peripheral: LPUART1, signal: RX, pin_signal: GPIO_AD_B0_13, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Down_100K_Ohm, + pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitDEBUG_UARTPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitDEBUG_UARTPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, 0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, 0x10B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, 0x10B0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitSDRAMPins: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: C2, peripheral: SEMC, signal: 'ADDR, 00', pin_signal: GPIO_EMC_09} + - {pin_num: G1, peripheral: SEMC, signal: 'ADDR, 01', pin_signal: GPIO_EMC_10} + - {pin_num: G3, peripheral: SEMC, signal: 'ADDR, 02', pin_signal: GPIO_EMC_11} + - {pin_num: H1, peripheral: SEMC, signal: 'ADDR, 03', pin_signal: GPIO_EMC_12} + - {pin_num: A6, peripheral: SEMC, signal: 'ADDR, 04', pin_signal: GPIO_EMC_13} + - {pin_num: B6, peripheral: SEMC, signal: 'ADDR, 05', pin_signal: GPIO_EMC_14} + - {pin_num: B1, peripheral: SEMC, signal: 'ADDR, 06', pin_signal: GPIO_EMC_15} + - {pin_num: A5, peripheral: SEMC, signal: 'ADDR, 07', pin_signal: GPIO_EMC_16} + - {pin_num: A4, peripheral: SEMC, signal: 'ADDR, 08', pin_signal: GPIO_EMC_17} + - {pin_num: B2, peripheral: SEMC, signal: 'ADDR, 09', pin_signal: GPIO_EMC_18} + - {pin_num: G2, peripheral: SEMC, signal: 'ADDR, 10', pin_signal: GPIO_EMC_23} + - {pin_num: B4, peripheral: SEMC, signal: 'ADDR, 11', pin_signal: GPIO_EMC_19} + - {pin_num: A3, peripheral: SEMC, signal: 'ADDR, 12', pin_signal: GPIO_EMC_20} + - {pin_num: C1, peripheral: SEMC, signal: 'BA, 0', pin_signal: GPIO_EMC_21} + - {pin_num: F1, peripheral: SEMC, signal: 'BA, 1', pin_signal: GPIO_EMC_22} + - {pin_num: D3, peripheral: SEMC, signal: semc_cas, pin_signal: GPIO_EMC_24} + - {pin_num: A2, peripheral: SEMC, signal: semc_cke, pin_signal: GPIO_EMC_27} + - {pin_num: B3, peripheral: SEMC, signal: semc_clk, pin_signal: GPIO_EMC_26} + - {pin_num: E3, peripheral: SEMC, signal: 'DATA, 00', pin_signal: GPIO_EMC_00} + - {pin_num: F3, peripheral: SEMC, signal: 'DATA, 01', pin_signal: GPIO_EMC_01} + - {pin_num: F4, peripheral: SEMC, signal: 'DATA, 02', pin_signal: GPIO_EMC_02} + - {pin_num: G4, peripheral: SEMC, signal: 'DATA, 03', pin_signal: GPIO_EMC_03} + - {pin_num: F2, peripheral: SEMC, signal: 'DATA, 04', pin_signal: GPIO_EMC_04} + - {pin_num: G5, peripheral: SEMC, signal: 'DATA, 05', pin_signal: GPIO_EMC_05} + - {pin_num: H5, peripheral: SEMC, signal: 'DATA, 06', pin_signal: GPIO_EMC_06} + - {pin_num: H4, peripheral: SEMC, signal: 'DATA, 07', pin_signal: GPIO_EMC_07} + - {pin_num: C6, peripheral: SEMC, signal: 'DATA, 08', pin_signal: GPIO_EMC_30} + - {pin_num: C5, peripheral: SEMC, signal: 'DATA, 09', pin_signal: GPIO_EMC_31} + - {pin_num: D5, peripheral: SEMC, signal: 'DATA, 10', pin_signal: GPIO_EMC_32} + - {pin_num: C4, peripheral: SEMC, signal: 'DATA, 11', pin_signal: GPIO_EMC_33} + - {pin_num: D4, peripheral: SEMC, signal: 'DATA, 12', pin_signal: GPIO_EMC_34} + - {pin_num: E5, peripheral: SEMC, signal: 'DATA, 13', pin_signal: GPIO_EMC_35} + - {pin_num: C3, peripheral: SEMC, signal: 'DATA, 14', pin_signal: GPIO_EMC_36} + - {pin_num: E4, peripheral: SEMC, signal: 'DATA, 15', pin_signal: GPIO_EMC_37} + - {pin_num: H3, peripheral: SEMC, signal: 'DM, 0', pin_signal: GPIO_EMC_08} + - {pin_num: D6, peripheral: SEMC, signal: 'DM, 1', pin_signal: GPIO_EMC_38} + - {pin_num: D2, peripheral: SEMC, signal: semc_ras, pin_signal: GPIO_EMC_25} + - {pin_num: D1, peripheral: SEMC, signal: semc_we, pin_signal: GPIO_EMC_28} + - {pin_num: E1, peripheral: SEMC, signal: 'CS, 0', pin_signal: GPIO_EMC_29} + - {pin_num: B7, peripheral: SEMC, signal: semc_dqs, pin_signal: GPIO_EMC_39} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitSDRAMPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitSDRAMPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_00_SEMC_DATA00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_01_SEMC_DATA01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_02_SEMC_DATA02, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_03_SEMC_DATA03, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_04_SEMC_DATA04, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_05_SEMC_DATA05, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_06_SEMC_DATA06, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_07_SEMC_DATA07, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_08_SEMC_DM00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_09_SEMC_ADDR00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_10_SEMC_ADDR01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_11_SEMC_ADDR02, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_12_SEMC_ADDR03, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_13_SEMC_ADDR04, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_14_SEMC_ADDR05, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_15_SEMC_ADDR06, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_16_SEMC_ADDR07, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_17_SEMC_ADDR08, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_18_SEMC_ADDR09, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_19_SEMC_ADDR11, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_20_SEMC_ADDR12, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_21_SEMC_BA0, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_22_SEMC_BA1, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_23_SEMC_ADDR10, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_24_SEMC_CAS, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_25_SEMC_RAS, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_26_SEMC_CLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_27_SEMC_CKE, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_28_SEMC_WE, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_29_SEMC_CS0, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_30_SEMC_DATA08, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_31_SEMC_DATA09, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_32_SEMC_DATA10, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_33_SEMC_DATA11, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_34_SEMC_DATA12, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_35_SEMC_DATA13, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_36_SEMC_DATA14, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_37_SEMC_DATA15, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_38_SEMC_DM01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_39_SEMC_DQS, 0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitCSIPins: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: H13, peripheral: CSI, signal: 'csi_data, 09', pin_signal: GPIO_AD_B1_08} + - {pin_num: M13, peripheral: CSI, signal: 'csi_data, 08', pin_signal: GPIO_AD_B1_09} + - {pin_num: L13, peripheral: CSI, signal: 'csi_data, 07', pin_signal: GPIO_AD_B1_10} + - {pin_num: J13, peripheral: CSI, signal: 'csi_data, 06', pin_signal: GPIO_AD_B1_11} + - {pin_num: H12, peripheral: CSI, signal: 'csi_data, 05', pin_signal: GPIO_AD_B1_12} + - {pin_num: H11, peripheral: CSI, signal: 'csi_data, 04', pin_signal: GPIO_AD_B1_13} + - {pin_num: J14, peripheral: CSI, signal: 'csi_data, 02', pin_signal: GPIO_AD_B1_15} + - {pin_num: G12, peripheral: CSI, signal: 'csi_data, 03', pin_signal: GPIO_AD_B1_14} + - {pin_num: L12, peripheral: CSI, signal: csi_pixclk, pin_signal: GPIO_AD_B1_04} + - {pin_num: K12, peripheral: CSI, signal: csi_mclk, pin_signal: GPIO_AD_B1_05} + - {pin_num: J12, peripheral: CSI, signal: csi_vsync, pin_signal: GPIO_AD_B1_06} + - {pin_num: K10, peripheral: CSI, signal: csi_hsync, pin_signal: GPIO_AD_B1_07} + - {pin_num: J11, peripheral: LPI2C1, signal: SCL, pin_signal: GPIO_AD_B1_00, identifier: CSI_I2C_SCL, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Up_22K_Ohm, + pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Enable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} + - {pin_num: K11, peripheral: LPI2C1, signal: SDA, pin_signal: GPIO_AD_B1_01, identifier: CSI_I2C_SDA, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Up_22K_Ohm, + pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Enable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} + - {pin_num: F11, peripheral: GPIO1, signal: 'gpio_io, 04', pin_signal: GPIO_AD_B0_04} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitCSIPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitCSIPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_04_GPIO1_IO04, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_04_CSI_PIXCLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_05_CSI_MCLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_06_CSI_VSYNC, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_07_CSI_HSYNC, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_08_CSI_DATA09, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_09_CSI_DATA08, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_10_CSI_DATA07, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_11_CSI_DATA06, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_12_CSI_DATA05, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_13_CSI_DATA04, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_14_CSI_DATA03, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_15_CSI_DATA02, 0U); + IOMUXC_GPR->GPR26 = ((IOMUXC_GPR->GPR26 & + (~(BOARD_INITCSIPINS_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK))) + | IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL(0x00U) + ); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL, 0xD8B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA, 0xD8B0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitLCDPins: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: C8, peripheral: LCDIF, signal: 'lcdif_data, 00', pin_signal: GPIO_B0_04, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: B8, peripheral: LCDIF, signal: 'lcdif_data, 01', pin_signal: GPIO_B0_05, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: A8, peripheral: LCDIF, signal: 'lcdif_data, 02', pin_signal: GPIO_B0_06, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: D7, peripheral: LCDIF, signal: lcdif_clk, pin_signal: GPIO_B0_00, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: A9, peripheral: LCDIF, signal: 'lcdif_data, 03', pin_signal: GPIO_B0_07, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: B9, peripheral: LCDIF, signal: 'lcdif_data, 04', pin_signal: GPIO_B0_08, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: C9, peripheral: LCDIF, signal: 'lcdif_data, 05', pin_signal: GPIO_B0_09, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: D9, peripheral: LCDIF, signal: 'lcdif_data, 06', pin_signal: GPIO_B0_10, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: A10, peripheral: LCDIF, signal: 'lcdif_data, 07', pin_signal: GPIO_B0_11, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: C10, peripheral: LCDIF, signal: 'lcdif_data, 08', pin_signal: GPIO_B0_12, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: D10, peripheral: LCDIF, signal: 'lcdif_data, 09', pin_signal: GPIO_B0_13, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: E10, peripheral: LCDIF, signal: 'lcdif_data, 10', pin_signal: GPIO_B0_14, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: E11, peripheral: LCDIF, signal: 'lcdif_data, 11', pin_signal: GPIO_B0_15, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: A11, peripheral: LCDIF, signal: 'lcdif_data, 12', pin_signal: GPIO_B1_00, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: B11, peripheral: LCDIF, signal: 'lcdif_data, 13', pin_signal: GPIO_B1_01, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: C11, peripheral: LCDIF, signal: 'lcdif_data, 14', pin_signal: GPIO_B1_02, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: D11, peripheral: LCDIF, signal: 'lcdif_data, 15', pin_signal: GPIO_B1_03, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: E7, peripheral: LCDIF, signal: lcdif_enable, pin_signal: GPIO_B0_01, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: E8, peripheral: LCDIF, signal: lcdif_hsync, pin_signal: GPIO_B0_02, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: D8, peripheral: LCDIF, signal: lcdif_vsync, pin_signal: GPIO_B0_03, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: B14, peripheral: GPIO2, signal: 'gpio_io, 31', pin_signal: GPIO_B1_15, slew_rate: Slow} + - {pin_num: M11, peripheral: GPIO1, signal: 'gpio_io, 02', pin_signal: GPIO_AD_B0_02} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitLCDPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitLCDPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_02_GPIO1_IO02, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_00_LCD_CLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_01_LCD_ENABLE, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_02_LCD_HSYNC, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_03_LCD_VSYNC, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_04_LCD_DATA00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_05_LCD_DATA01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_06_LCD_DATA02, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_07_LCD_DATA03, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_08_LCD_DATA04, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_09_LCD_DATA05, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_10_LCD_DATA06, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_11_LCD_DATA07, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_12_LCD_DATA08, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_13_LCD_DATA09, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_14_LCD_DATA10, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_15_LCD_DATA11, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_00_LCD_DATA12, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_01_LCD_DATA13, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_02_LCD_DATA14, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_03_LCD_DATA15, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_15_GPIO2_IO31, 0U); + IOMUXC_GPR->GPR26 = ((IOMUXC_GPR->GPR26 & + (~(BOARD_INITLCDPINS_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK))) + | IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL(0x00U) + ); + IOMUXC_GPR->GPR27 = ((IOMUXC_GPR->GPR27 & + (~(BOARD_INITLCDPINS_IOMUXC_GPR_GPR27_GPIO_MUX2_GPIO_SEL_MASK))) + | IOMUXC_GPR_GPR27_GPIO_MUX2_GPIO_SEL(0x00U) + ); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_00_LCD_CLK, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_01_LCD_ENABLE, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_02_LCD_HSYNC, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_03_LCD_VSYNC, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_04_LCD_DATA00, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_05_LCD_DATA01, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_06_LCD_DATA02, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_07_LCD_DATA03, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_08_LCD_DATA04, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_09_LCD_DATA05, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_10_LCD_DATA06, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_11_LCD_DATA07, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_12_LCD_DATA08, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_13_LCD_DATA09, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_14_LCD_DATA10, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_15_LCD_DATA11, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_00_LCD_DATA12, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_01_LCD_DATA13, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_02_LCD_DATA14, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_03_LCD_DATA15, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_15_GPIO2_IO31, 0x10B0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitCANPins: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: H14, peripheral: CAN2, signal: TX, pin_signal: GPIO_AD_B0_14} + - {pin_num: L10, peripheral: CAN2, signal: RX, pin_signal: GPIO_AD_B0_15} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitCANPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitCANPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_14_FLEXCAN2_TX, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_15_FLEXCAN2_RX, 0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitENETPins: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: A7, peripheral: ENET, signal: enet_mdc, pin_signal: GPIO_EMC_40} + - {pin_num: C7, peripheral: ENET, signal: enet_mdio, pin_signal: GPIO_EMC_41} + - {pin_num: B13, peripheral: ENET, signal: enet_ref_clk, pin_signal: GPIO_B1_10} + - {pin_num: E12, peripheral: ENET, signal: 'enet_rx_data, 0', pin_signal: GPIO_B1_04} + - {pin_num: D12, peripheral: ENET, signal: 'enet_rx_data, 1', pin_signal: GPIO_B1_05} + - {pin_num: C12, peripheral: ENET, signal: enet_rx_en, pin_signal: GPIO_B1_06} + - {pin_num: C13, peripheral: ENET, signal: enet_rx_er, pin_signal: GPIO_B1_11} + - {pin_num: B12, peripheral: ENET, signal: 'enet_tx_data, 0', pin_signal: GPIO_B1_07} + - {pin_num: A12, peripheral: ENET, signal: 'enet_tx_data, 1', pin_signal: GPIO_B1_08} + - {pin_num: A13, peripheral: ENET, signal: enet_tx_en, pin_signal: GPIO_B1_09} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitENETPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitENETPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_04_ENET_RX_DATA00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_05_ENET_RX_DATA01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_06_ENET_RX_EN, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_07_ENET_TX_DATA00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_08_ENET_TX_DATA01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_09_ENET_TX_EN, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_10_ENET_REF_CLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_11_ENET_RX_ER, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_40_ENET_MDC, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_41_ENET_MDIO, 0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitUSDHCPins: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: J2, peripheral: USDHC1, signal: 'usdhc_data, 3', pin_signal: GPIO_SD_B0_05} + - {pin_num: H2, peripheral: USDHC1, signal: 'usdhc_data, 2', pin_signal: GPIO_SD_B0_04} + - {pin_num: K1, peripheral: USDHC1, signal: 'usdhc_data, 1', pin_signal: GPIO_SD_B0_03} + - {pin_num: J1, peripheral: USDHC1, signal: 'usdhc_data, 0', pin_signal: GPIO_SD_B0_02} + - {pin_num: J4, peripheral: USDHC1, signal: usdhc_cmd, pin_signal: GPIO_SD_B0_00} + - {pin_num: J3, peripheral: USDHC1, signal: usdhc_clk, pin_signal: GPIO_SD_B0_01} + - {pin_num: C14, peripheral: USDHC1, signal: usdhc_vselect, pin_signal: GPIO_B1_14} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitUSDHCPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitUSDHCPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_14_USDHC1_VSELECT, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_00_USDHC1_CMD, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_01_USDHC1_CLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_02_USDHC1_DATA0, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_03_USDHC1_DATA1, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_04_USDHC1_DATA2, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_05_USDHC1_DATA3, 0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitQSPIPins: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: P3, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA0, pin_signal: GPIO_SD_B1_08} + - {pin_num: N4, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA1, pin_signal: GPIO_SD_B1_09} + - {pin_num: P4, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA2, pin_signal: GPIO_SD_B1_10} + - {pin_num: P5, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA3, pin_signal: GPIO_SD_B1_11} + - {pin_num: L4, peripheral: FLEXSPI, signal: FLEXSPI_A_SCLK, pin_signal: GPIO_SD_B1_07} + - {pin_num: L3, peripheral: FLEXSPI, signal: FLEXSPI_A_SS0_B, pin_signal: GPIO_SD_B1_06} + - {pin_num: N3, peripheral: FLEXSPI, signal: FLEXSPI_A_DQS, pin_signal: GPIO_SD_B1_05} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitQSPIPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitQSPIPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_05_FLEXSPIA_DQS, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_06_FLEXSPIA_SS0_B, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_07_FLEXSPIA_SCLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_08_FLEXSPIA_DATA00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_09_FLEXSPIA_DATA01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_10_FLEXSPIA_DATA02, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_11_FLEXSPIA_DATA03, 0U); +} + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/imxrt/boards/mimxrt1060_evk/board/pin_mux.h b/hw/bsp/imxrt/boards/mimxrt1060_evk/board/pin_mux.h new file mode 100644 index 000000000..bf494b6f6 --- /dev/null +++ b/hw/bsp/imxrt/boards/mimxrt1060_evk/board/pin_mux.h @@ -0,0 +1,744 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _PIN_MUX_H_ +#define _PIN_MUX_H_ + +/*********************************************************************************************************************** + * Definitions + **********************************************************************************************************************/ + +/*! @brief Direction type */ +typedef enum _pin_mux_direction +{ + kPIN_MUX_DirectionInput = 0U, /* Input direction */ + kPIN_MUX_DirectionOutput = 1U, /* Output direction */ + kPIN_MUX_DirectionInputOrOutput = 2U /* Input or output direction */ +} pin_mux_direction_t; + +/*! + * @addtogroup pin_mux + * @{ + */ + +/*********************************************************************************************************************** + * API + **********************************************************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Calls initialization functions. + * + */ +void BOARD_InitBootPins(void); + +#define BOARD_INITPINS_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK 0x0200U /*!< GPIO1 and GPIO6 share same IO MUX function, GPIO_MUX1 selects one GPIO function: affected bits mask */ + +/* GPIO_AD_B0_09 (coord F14), JTAG_TDI/J21[5]/ENET_RST/J22[5] */ +/* Routed pin properties */ +#define BOARD_INITPINS_USER_LED_PERIPHERAL GPIO1 /*!< Peripheral name */ +#define BOARD_INITPINS_USER_LED_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITPINS_USER_LED_CHANNEL 9U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_USER_LED_GPIO GPIO1 /*!< GPIO peripheral base pointer */ +#define BOARD_INITPINS_USER_LED_GPIO_PIN 9U /*!< GPIO pin number */ +#define BOARD_INITPINS_USER_LED_GPIO_PIN_MASK (1U << 9U) /*!< GPIO pin mask */ +#define BOARD_INITPINS_USER_LED_PORT GPIO1 /*!< PORT peripheral base pointer */ +#define BOARD_INITPINS_USER_LED_PIN 9U /*!< PORT pin number */ +#define BOARD_INITPINS_USER_LED_PIN_MASK (1U << 9U) /*!< PORT pin mask */ + +/* WAKEUP (coord L6), SD_PWREN */ +/* Routed pin properties */ +#define BOARD_INITPINS_USER_BUTTON_PERIPHERAL GPIO5 /*!< Peripheral name */ +#define BOARD_INITPINS_USER_BUTTON_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITPINS_USER_BUTTON_CHANNEL 0U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_USER_BUTTON_GPIO GPIO5 /*!< GPIO peripheral base pointer */ +#define BOARD_INITPINS_USER_BUTTON_GPIO_PIN 0U /*!< GPIO pin number */ +#define BOARD_INITPINS_USER_BUTTON_GPIO_PIN_MASK (1U << 0U) /*!< GPIO pin mask */ +#define BOARD_INITPINS_USER_BUTTON_PORT GPIO5 /*!< PORT peripheral base pointer */ +#define BOARD_INITPINS_USER_BUTTON_PIN 0U /*!< PORT pin number */ +#define BOARD_INITPINS_USER_BUTTON_PIN_MASK (1U << 0U) /*!< PORT pin mask */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitPins(void); + +/* GPIO_AD_B0_12 (coord K14), UART1_TXD */ +/* Routed pin properties */ +#define BOARD_INITDEBUG_UARTPINS_UART1_TXD_PERIPHERAL LPUART1 /*!< Peripheral name */ +#define BOARD_INITDEBUG_UARTPINS_UART1_TXD_SIGNAL TX /*!< Signal name */ + +/* GPIO_AD_B0_13 (coord L14), UART1_RXD */ +/* Routed pin properties */ +#define BOARD_INITDEBUG_UARTPINS_UART1_RXD_PERIPHERAL LPUART1 /*!< Peripheral name */ +#define BOARD_INITDEBUG_UARTPINS_UART1_RXD_SIGNAL RX /*!< Signal name */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitDEBUG_UARTPins(void); + +/* GPIO_EMC_09 (coord C2), SEMC_A0 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A0_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A0_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_EMC_10 (coord G1), SEMC_A1 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A1_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A1_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_EMC_11 (coord G3), SEMC_A2 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A2_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A2_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A2_CHANNEL 2U /*!< Signal channel */ + +/* GPIO_EMC_12 (coord H1), SEMC_A3 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A3_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A3_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A3_CHANNEL 3U /*!< Signal channel */ + +/* GPIO_EMC_13 (coord A6), SEMC_A4 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A4_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A4_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A4_CHANNEL 4U /*!< Signal channel */ + +/* GPIO_EMC_14 (coord B6), SEMC_A5 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A5_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A5_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A5_CHANNEL 5U /*!< Signal channel */ + +/* GPIO_EMC_15 (coord B1), SEMC_A6 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A6_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A6_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A6_CHANNEL 6U /*!< Signal channel */ + +/* GPIO_EMC_16 (coord A5), SEMC_A7 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A7_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A7_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A7_CHANNEL 7U /*!< Signal channel */ + +/* GPIO_EMC_17 (coord A4), SEMC_A8 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A8_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A8_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A8_CHANNEL 8U /*!< Signal channel */ + +/* GPIO_EMC_18 (coord B2), SEMC_A9 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A9_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A9_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A9_CHANNEL 9U /*!< Signal channel */ + +/* GPIO_EMC_23 (coord G2), SEMC_A10 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A10_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A10_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A10_CHANNEL 10U /*!< Signal channel */ + +/* GPIO_EMC_19 (coord B4), SEMC_A11 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A11_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A11_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A11_CHANNEL 11U /*!< Signal channel */ + +/* GPIO_EMC_20 (coord A3), SEMC_A12 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A12_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A12_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A12_CHANNEL 12U /*!< Signal channel */ + +/* GPIO_EMC_21 (coord C1), SEMC_BA0 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_BA0_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_BA0_SIGNAL BA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_BA0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_EMC_22 (coord F1), SEMC_BA1 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_BA1_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_BA1_SIGNAL BA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_BA1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_EMC_24 (coord D3), SEMC_CAS */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_CAS_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_CAS_SIGNAL semc_cas /*!< Signal name */ + +/* GPIO_EMC_27 (coord A2), SEMC_CKE */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_CKE_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_CKE_SIGNAL semc_cke /*!< Signal name */ + +/* GPIO_EMC_26 (coord B3), SEMC_CLK */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_CLK_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_CLK_SIGNAL semc_clk /*!< Signal name */ + +/* GPIO_EMC_00 (coord E3), SEMC_D0 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D0_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D0_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_EMC_01 (coord F3), SEMC_D1 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D1_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D1_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_EMC_02 (coord F4), SEMC_D2 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D2_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D2_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D2_CHANNEL 2U /*!< Signal channel */ + +/* GPIO_EMC_03 (coord G4), SEMC_D3 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D3_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D3_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D3_CHANNEL 3U /*!< Signal channel */ + +/* GPIO_EMC_04 (coord F2), SEMC_D4 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D4_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D4_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D4_CHANNEL 4U /*!< Signal channel */ + +/* GPIO_EMC_05 (coord G5), SEMC_D5 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D5_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D5_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D5_CHANNEL 5U /*!< Signal channel */ + +/* GPIO_EMC_06 (coord H5), SEMC_D6 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D6_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D6_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D6_CHANNEL 6U /*!< Signal channel */ + +/* GPIO_EMC_07 (coord H4), SEMC_D7 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D7_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D7_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D7_CHANNEL 7U /*!< Signal channel */ + +/* GPIO_EMC_30 (coord C6), SEMC_D8 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D8_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D8_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D8_CHANNEL 8U /*!< Signal channel */ + +/* GPIO_EMC_31 (coord C5), SEMC_D9 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D9_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D9_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D9_CHANNEL 9U /*!< Signal channel */ + +/* GPIO_EMC_32 (coord D5), SEMC_D10 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D10_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D10_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D10_CHANNEL 10U /*!< Signal channel */ + +/* GPIO_EMC_33 (coord C4), SEMC_D11 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D11_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D11_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D11_CHANNEL 11U /*!< Signal channel */ + +/* GPIO_EMC_34 (coord D4), SEMC_D12 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D12_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D12_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D12_CHANNEL 12U /*!< Signal channel */ + +/* GPIO_EMC_35 (coord E5), SEMC_D13 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D13_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D13_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D13_CHANNEL 13U /*!< Signal channel */ + +/* GPIO_EMC_36 (coord C3), SEMC_D14 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D14_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D14_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D14_CHANNEL 14U /*!< Signal channel */ + +/* GPIO_EMC_37 (coord E4), SEMC_D15 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D15_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D15_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D15_CHANNEL 15U /*!< Signal channel */ + +/* GPIO_EMC_08 (coord H3), SEMC_DM0 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_DM0_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_DM0_SIGNAL DM /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_DM0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_EMC_38 (coord D6), SEMC_DM1 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_DM1_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_DM1_SIGNAL DM /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_DM1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_EMC_25 (coord D2), SEMC_RAS */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_RAS_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_RAS_SIGNAL semc_ras /*!< Signal name */ + +/* GPIO_EMC_28 (coord D1), SEMC_WE */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_WE_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_WE_SIGNAL semc_we /*!< Signal name */ + +/* GPIO_EMC_29 (coord E1), SEMC_CS0 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_CS0_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_CS0_SIGNAL CS /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_CS0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_EMC_39 (coord B7), SEMC_DQS */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_DQS_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_DQS_SIGNAL semc_dqs /*!< Signal name */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitSDRAMPins(void); + +#define BOARD_INITCSIPINS_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK 0x10U /*!< GPIO1 and GPIO6 share same IO MUX function, GPIO_MUX1 selects one GPIO function: affected bits mask */ + +/* GPIO_AD_B1_08 (coord H13), AUD_INT/CSI_D9//J35[13]/J22[4] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_D9_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_D9_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSIPINS_CSI_D9_CHANNEL 9U /*!< Signal channel */ + +/* GPIO_AD_B1_09 (coord M13), SAI1_MCLK/CSI_D8/J35[11] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_D8_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_D8_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSIPINS_CSI_D8_CHANNEL 8U /*!< Signal channel */ + +/* GPIO_AD_B1_10 (coord L13), SAI1_RX_SYNC/CSI_D7/J35[9]/J23[1] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_D7_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_D7_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSIPINS_CSI_D7_CHANNEL 7U /*!< Signal channel */ + +/* GPIO_AD_B1_11 (coord J13), SAI1_RX_BCLK/CSI_D6/J35[7]/J23[2] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_D6_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_D6_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSIPINS_CSI_D6_CHANNEL 6U /*!< Signal channel */ + +/* GPIO_AD_B1_12 (coord H12), SAI1_RXD/CSI_D5/J35[5]/U13[16] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_D5_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_D5_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSIPINS_CSI_D5_CHANNEL 5U /*!< Signal channel */ + +/* GPIO_AD_B1_13 (coord H11), SAI1_TXD/CSI_D4/J35[3]/U13[14] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_D4_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_D4_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSIPINS_CSI_D4_CHANNEL 4U /*!< Signal channel */ + +/* GPIO_AD_B1_15 (coord J14), SAI1_TX_SYNC/CSI_D2/J35[6]/U13[13] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_D2_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_D2_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSIPINS_CSI_D2_CHANNEL 2U /*!< Signal channel */ + +/* GPIO_AD_B1_14 (coord G12), SAI1_TX_BCLK/CSI_D3/J35[4]/U13[12] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_D3_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_D3_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSIPINS_CSI_D3_CHANNEL 3U /*!< Signal channel */ + +/* GPIO_AD_B1_04 (coord L12), CSI_PIXCLK/J35[8]/J23[3] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_PIXCLK_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_PIXCLK_SIGNAL csi_pixclk /*!< Signal name */ + +/* GPIO_AD_B1_05 (coord K12), CSI_MCLK/J35[12]/J23[4] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_MCLK_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_MCLK_SIGNAL csi_mclk /*!< Signal name */ + +/* GPIO_AD_B1_06 (coord J12), CSI_VSYNC/J35[18]/J22[2]/UART_TX */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_VSYNC_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_VSYNC_SIGNAL csi_vsync /*!< Signal name */ + +/* GPIO_AD_B1_07 (coord K10), CSI_HSYNC/J35[16]/J22[1]/UART_RX */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_HSYNC_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_HSYNC_SIGNAL csi_hsync /*!< Signal name */ + +/* GPIO_AD_B1_00 (coord J11), I2C1_SCL/CSI_I2C_SCL/J35[20]/J23[6]/U13[17]/U32[4] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_I2C_SCL_PERIPHERAL LPI2C1 /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_I2C_SCL_SIGNAL SCL /*!< Signal name */ + +/* GPIO_AD_B1_01 (coord K11), I2C1_SDA/CSI_I2C_SDA/J35[22]/J23[5]/U13[18]/U32[6] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_I2C_SDA_PERIPHERAL LPI2C1 /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_I2C_SDA_SIGNAL SDA /*!< Signal name */ + +/* GPIO_AD_B0_04 (coord F11), CSI_PWDN/J35[17]/BOOT_MODE[0] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_PWDN_PERIPHERAL GPIO1 /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_PWDN_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITCSIPINS_CSI_PWDN_CHANNEL 4U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITCSIPINS_CSI_PWDN_GPIO GPIO1 /*!< GPIO peripheral base pointer */ +#define BOARD_INITCSIPINS_CSI_PWDN_GPIO_PIN 4U /*!< GPIO pin number */ +#define BOARD_INITCSIPINS_CSI_PWDN_GPIO_PIN_MASK (1U << 4U) /*!< GPIO pin mask */ +#define BOARD_INITCSIPINS_CSI_PWDN_PORT GPIO1 /*!< PORT peripheral base pointer */ +#define BOARD_INITCSIPINS_CSI_PWDN_PIN 4U /*!< PORT pin number */ +#define BOARD_INITCSIPINS_CSI_PWDN_PIN_MASK (1U << 4U) /*!< PORT pin mask */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitCSIPins(void); + +#define BOARD_INITLCDPINS_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK 0x04U /*!< GPIO1 and GPIO6 share same IO MUX function, GPIO_MUX1 selects one GPIO function: affected bits mask */ +#define BOARD_INITLCDPINS_IOMUXC_GPR_GPR27_GPIO_MUX2_GPIO_SEL_MASK 0x80000000U /*!< GPIO2 and GPIO7 share same IO MUX function, GPIO_MUX2 selects one GPIO function: affected bits mask */ + +/* GPIO_B0_04 (coord C8), LCDIF_D0/BT_CFG[0] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D0_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D0_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_B0_05 (coord B8), LCDIF_D1/BT_CFG[1] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D1_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D1_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_B0_06 (coord A8), LCDIF_D2/BT_CFG[2] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D2_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D2_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D2_CHANNEL 2U /*!< Signal channel */ + +/* GPIO_B0_00 (coord D7), LCDIF_CLK */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_CLK_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_CLK_SIGNAL lcdif_clk /*!< Signal name */ + +/* GPIO_B0_07 (coord A9), LCDIF_D3/BT_CFG[3] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D3_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D3_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D3_CHANNEL 3U /*!< Signal channel */ + +/* GPIO_B0_08 (coord B9), LCDIF_D4/BT_CFG[4] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D4_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D4_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D4_CHANNEL 4U /*!< Signal channel */ + +/* GPIO_B0_09 (coord C9), LCDIF_D5/BT_CFG[5] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D5_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D5_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D5_CHANNEL 5U /*!< Signal channel */ + +/* GPIO_B0_10 (coord D9), LCDIF_D6/BT_CFG[6] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D6_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D6_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D6_CHANNEL 6U /*!< Signal channel */ + +/* GPIO_B0_11 (coord A10), LCDIF_D7/BT_CFG[7] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D7_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D7_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D7_CHANNEL 7U /*!< Signal channel */ + +/* GPIO_B0_12 (coord C10), LCDIF_D8/BT_CFG[8] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D8_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D8_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D8_CHANNEL 8U /*!< Signal channel */ + +/* GPIO_B0_13 (coord D10), LCDIF_D9/BT_CFG[9] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D9_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D9_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D9_CHANNEL 9U /*!< Signal channel */ + +/* GPIO_B0_14 (coord E10), LCDIF_D10/BT_CFG[10] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D10_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D10_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D10_CHANNEL 10U /*!< Signal channel */ + +/* GPIO_B0_15 (coord E11), LCDIF_D11/BT_CFG[11] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D11_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D11_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D11_CHANNEL 11U /*!< Signal channel */ + +/* GPIO_B1_00 (coord A11), LCDIF_D12 */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D12_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D12_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D12_CHANNEL 12U /*!< Signal channel */ + +/* GPIO_B1_01 (coord B11), LCDIF_D13 */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D13_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D13_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D13_CHANNEL 13U /*!< Signal channel */ + +/* GPIO_B1_02 (coord C11), LCDIF_D14 */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D14_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D14_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D14_CHANNEL 14U /*!< Signal channel */ + +/* GPIO_B1_03 (coord D11), LCDIF_D15 */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D15_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D15_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D15_CHANNEL 15U /*!< Signal channel */ + +/* GPIO_B0_01 (coord E7), LCDIF_ENABLE */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_ENABLE_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_ENABLE_SIGNAL lcdif_enable /*!< Signal name */ + +/* GPIO_B0_02 (coord E8), LCDIF_HSYNC */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_HSYNC_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_HSYNC_SIGNAL lcdif_hsync /*!< Signal name */ + +/* GPIO_B0_03 (coord D8), LCDIF_VSYNC */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_VSYNC_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_VSYNC_SIGNAL lcdif_vsync /*!< Signal name */ + +/* GPIO_B1_15 (coord B14), USB_HOST_PWR/BACKLIGHT_CTL */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_BACKLIGHT_CTL_PERIPHERAL GPIO2 /*!< Peripheral name */ +#define BOARD_INITLCDPINS_BACKLIGHT_CTL_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITLCDPINS_BACKLIGHT_CTL_CHANNEL 31U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITLCDPINS_BACKLIGHT_CTL_GPIO GPIO2 /*!< GPIO peripheral base pointer */ +#define BOARD_INITLCDPINS_BACKLIGHT_CTL_GPIO_PIN 31U /*!< GPIO pin number */ +#define BOARD_INITLCDPINS_BACKLIGHT_CTL_GPIO_PIN_MASK (1U << 31U) /*!< GPIO pin mask */ +#define BOARD_INITLCDPINS_BACKLIGHT_CTL_PORT GPIO2 /*!< PORT peripheral base pointer */ +#define BOARD_INITLCDPINS_BACKLIGHT_CTL_PIN 31U /*!< PORT pin number */ +#define BOARD_INITLCDPINS_BACKLIGHT_CTL_PIN_MASK (1U << 31U) /*!< PORT pin mask */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitLCDPins(void); + +/* GPIO_AD_B0_14 (coord H14), CAN2_TX/U12[1] */ +/* Routed pin properties */ +#define BOARD_INITCANPINS_CAN2_TX_PERIPHERAL CAN2 /*!< Peripheral name */ +#define BOARD_INITCANPINS_CAN2_TX_SIGNAL TX /*!< Signal name */ + +/* GPIO_AD_B0_15 (coord L10), CAN2_RX/U12[4] */ +/* Routed pin properties */ +#define BOARD_INITCANPINS_CAN2_RX_PERIPHERAL CAN2 /*!< Peripheral name */ +#define BOARD_INITCANPINS_CAN2_RX_SIGNAL RX /*!< Signal name */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitCANPins(void); + +/* GPIO_EMC_40 (coord A7), ENET_MDC */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_MDC_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_MDC_SIGNAL enet_mdc /*!< Signal name */ + +/* GPIO_EMC_41 (coord C7), ENET_MDIO */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_MDIO_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_MDIO_SIGNAL enet_mdio /*!< Signal name */ + +/* GPIO_B1_10 (coord B13), ENET_TX_CLK */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_TX_CLK_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_TX_CLK_SIGNAL enet_ref_clk /*!< Signal name */ + +/* GPIO_B1_04 (coord E12), ENET_RXD0 */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_RXD0_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_RXD0_SIGNAL enet_rx_data /*!< Signal name */ +#define BOARD_INITENETPINS_ENET_RXD0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_B1_05 (coord D12), ENET_RXD1 */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_RXD1_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_RXD1_SIGNAL enet_rx_data /*!< Signal name */ +#define BOARD_INITENETPINS_ENET_RXD1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_B1_06 (coord C12), ENET_CRS_DV */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_CRS_DV_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_CRS_DV_SIGNAL enet_rx_en /*!< Signal name */ + +/* GPIO_B1_11 (coord C13), ENET_RXER */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_RXER_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_RXER_SIGNAL enet_rx_er /*!< Signal name */ + +/* GPIO_B1_07 (coord B12), ENET_TXD0 */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_TXD0_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_TXD0_SIGNAL enet_tx_data /*!< Signal name */ +#define BOARD_INITENETPINS_ENET_TXD0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_B1_08 (coord A12), ENET_TXD1 */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_TXD1_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_TXD1_SIGNAL enet_tx_data /*!< Signal name */ +#define BOARD_INITENETPINS_ENET_TXD1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_B1_09 (coord A13), ENET_TXEN */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_TXEN_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_TXEN_SIGNAL enet_tx_en /*!< Signal name */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitENETPins(void); + +/* GPIO_SD_B0_05 (coord J2), SD1_D3 */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_D3_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_D3_SIGNAL usdhc_data /*!< Signal name */ +#define BOARD_INITUSDHCPINS_SD1_D3_CHANNEL 3U /*!< Signal channel */ + +/* GPIO_SD_B0_04 (coord H2), SD1_D2 */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_D2_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_D2_SIGNAL usdhc_data /*!< Signal name */ +#define BOARD_INITUSDHCPINS_SD1_D2_CHANNEL 2U /*!< Signal channel */ + +/* GPIO_SD_B0_03 (coord K1), SD1_D1/J24[5]/SPI_MISO */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_D1_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_D1_SIGNAL usdhc_data /*!< Signal name */ +#define BOARD_INITUSDHCPINS_SD1_D1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_SD_B0_02 (coord J1), SD1_D0/J24[4]/SPI_MOSI/PWM */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_D0_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_D0_SIGNAL usdhc_data /*!< Signal name */ +#define BOARD_INITUSDHCPINS_SD1_D0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_SD_B0_00 (coord J4), SD1_CMD/J24[6] */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_CMD_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_CMD_SIGNAL usdhc_cmd /*!< Signal name */ + +/* GPIO_SD_B0_01 (coord J3), SD1_CLK/J24[3] */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_CLK_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_CLK_SIGNAL usdhc_clk /*!< Signal name */ + +/* GPIO_B1_14 (coord C14), SD0_VSELECT */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD0_VSELECT_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD0_VSELECT_SIGNAL usdhc_vselect /*!< Signal name */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitUSDHCPins(void); + +/* GPIO_SD_B1_08 (coord P3), FlexSPI_D0_A */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_D0_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_D0_A_SIGNAL FLEXSPI_A_DATA0 /*!< Signal name */ + +/* GPIO_SD_B1_09 (coord N4), FlexSPI_D1_A */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_D1_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_D1_A_SIGNAL FLEXSPI_A_DATA1 /*!< Signal name */ + +/* GPIO_SD_B1_10 (coord P4), FlexSPI_D2_A */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_D2_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_D2_A_SIGNAL FLEXSPI_A_DATA2 /*!< Signal name */ + +/* GPIO_SD_B1_11 (coord P5), FlexSPI_D3_A */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_D3_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_D3_A_SIGNAL FLEXSPI_A_DATA3 /*!< Signal name */ + +/* GPIO_SD_B1_07 (coord L4), FlexSPI_CLK */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_CLK_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_CLK_SIGNAL FLEXSPI_A_SCLK /*!< Signal name */ + +/* GPIO_SD_B1_06 (coord L3), FlexSPI_SS0 */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_SS0_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_SS0_SIGNAL FLEXSPI_A_SS0_B /*!< Signal name */ + +/* GPIO_SD_B1_05 (coord N3), FlexSPI_DQS */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_DQS_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_DQS_SIGNAL FLEXSPI_A_DQS /*!< Signal name */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitQSPIPins(void); + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif /* _PIN_MUX_H_ */ + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/imxrt/boards/mimxrt1060_evk/mimxrt1060_evk.mex b/hw/bsp/imxrt/boards/mimxrt1060_evk/mimxrt1060_evk.mex index 39b3ed606..b9353ba44 100644 --- a/hw/bsp/imxrt/boards/mimxrt1060_evk/mimxrt1060_evk.mex +++ b/hw/bsp/imxrt/boards/mimxrt1060_evk/mimxrt1060_evk.mex @@ -26,6 +26,10 @@ 13.0.2 + + + + @@ -37,13 +41,40 @@ true + + + true + + true + + + true + + + + + true + + - + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. @@ -717,7 +748,7 @@ - + diff --git a/hw/bsp/imxrt/boards/mimxrt1064_evk/board.h b/hw/bsp/imxrt/boards/mimxrt1064_evk/board.h index 37ad94eef..7fca5adef 100644 --- a/hw/bsp/imxrt/boards/mimxrt1064_evk/board.h +++ b/hw/bsp/imxrt/boards/mimxrt1064_evk/board.h @@ -24,29 +24,24 @@ * This file is part of the TinyUSB stack. */ +#ifndef BOARD_MIMXRT1064_EVKB_H_ +#define BOARD_MIMXRT1064_EVKB_H_ -#ifndef BOARD_H_ -#define BOARD_H_ - -// required since iMX RT10xx SDK include this file for board size +// required since iMXRT MCUX-SDK include this file for board size #define BOARD_FLASH_SIZE (0x400000U) -// LED -#define LED_PINMUX IOMUXC_GPIO_AD_B0_09_GPIO1_IO09 -#define LED_PORT GPIO1 -#define LED_PIN 9 +// LED: IOMUXC_GPIO_AD_B0_09_GPIO1_IO09 +#define LED_PORT BOARD_INITPINS_USER_LED_PERIPHERAL +#define LED_PIN BOARD_INITPINS_USER_LED_CHANNEL #define LED_STATE_ON 0 -// SW8 button -#define BUTTON_PINMUX IOMUXC_SNVS_WAKEUP_GPIO5_IO00 -#define BUTTON_PORT GPIO5 -#define BUTTON_PIN 0 +// SW8 button: IOMUXC_SNVS_WAKEUP_GPIO5_IO00 +#define BUTTON_PORT BOARD_INITPINS_USER_BUTTON_PERIPHERAL +#define BUTTON_PIN BOARD_INITPINS_USER_BUTTON_CHANNEL #define BUTTON_STATE_ACTIVE 0 -// UART +// UART: IOMUXC_GPIO_AD_B0_13_LPUART1_RX, IOMUXC_GPIO_AD_B0_12_LPUART1_TX #define UART_PORT LPUART1 -#define UART_RX_PINMUX IOMUXC_GPIO_AD_B0_13_LPUART1_RX -#define UART_TX_PINMUX IOMUXC_GPIO_AD_B0_12_LPUART1_TX +#define UART_CLK_ROOT BOARD_BOOTCLOCKRUN_UART_CLK_ROOT - -#endif /* BOARD_H_ */ +#endif diff --git a/hw/bsp/imxrt/boards/mimxrt1064_evk/board/pin_mux.c b/hw/bsp/imxrt/boards/mimxrt1064_evk/board/pin_mux.c new file mode 100644 index 000000000..8e975dc72 --- /dev/null +++ b/hw/bsp/imxrt/boards/mimxrt1064_evk/board/pin_mux.c @@ -0,0 +1,497 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Pins v13.1 +processor: MIMXRT1064xxxxA +package_id: MIMXRT1064DVL6A +mcu_data: ksdk2_0 +processor_version: 13.0.2 +board: MIMXRT1064-EVK +pin_labels: +- {pin_num: F14, pin_signal: GPIO_AD_B0_09, label: 'JTAG_TDI/J21[5]/ENET_RST/J22[5]', identifier: USER_LED} +- {pin_num: L6, pin_signal: WAKEUP, label: SD_PWREN, identifier: USER_BUTTON} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +#include "fsl_common.h" +#include "fsl_iomuxc.h" +#include "fsl_gpio.h" +#include "pin_mux.h" + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitBootPins + * Description : Calls initialization functions. + * + * END ****************************************************************************************************************/ +void BOARD_InitBootPins(void) { + BOARD_InitPins(); + BOARD_InitDEBUG_UARTPins(); +} + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitPins: +- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: F14, peripheral: GPIO1, signal: 'gpio_io, 09', pin_signal: GPIO_AD_B0_09, direction: OUTPUT, pull_keeper_select: Keeper} + - {pin_num: L6, peripheral: GPIO5, signal: 'gpio_io, 00', pin_signal: WAKEUP, direction: INPUT} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + CLOCK_EnableClock(kCLOCK_IomuxcSnvs); + + /* GPIO configuration of USER_LED on GPIO_AD_B0_09 (pin F14) */ + gpio_pin_config_t USER_LED_config = { + .direction = kGPIO_DigitalOutput, + .outputLogic = 0U, + .interruptMode = kGPIO_NoIntmode + }; + /* Initialize GPIO functionality on GPIO_AD_B0_09 (pin F14) */ + GPIO_PinInit(GPIO1, 9U, &USER_LED_config); + + /* GPIO configuration of USER_BUTTON on WAKEUP (pin L6) */ + gpio_pin_config_t USER_BUTTON_config = { + .direction = kGPIO_DigitalInput, + .outputLogic = 0U, + .interruptMode = kGPIO_NoIntmode + }; + /* Initialize GPIO functionality on WAKEUP (pin L6) */ + GPIO_PinInit(GPIO5, 0U, &USER_BUTTON_config); + + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, 0U); + IOMUXC_GPR->GPR26 = ((IOMUXC_GPR->GPR26 & + (~(BOARD_INITPINS_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK))) + | IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL(0x00U) + ); + IOMUXC_SetPinMux(IOMUXC_SNVS_WAKEUP_GPIO5_IO00, 0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, 0x50A0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitDEBUG_UARTPins: +- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: K14, peripheral: LPUART1, signal: TX, pin_signal: GPIO_AD_B0_12, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Down_100K_Ohm, + pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} + - {pin_num: L14, peripheral: LPUART1, signal: RX, pin_signal: GPIO_AD_B0_13, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Down_100K_Ohm, + pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitDEBUG_UARTPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitDEBUG_UARTPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, 0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, 0x10B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, 0x10B0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitSDRAMPins: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: C2, peripheral: SEMC, signal: 'ADDR, 00', pin_signal: GPIO_EMC_09} + - {pin_num: G1, peripheral: SEMC, signal: 'ADDR, 01', pin_signal: GPIO_EMC_10} + - {pin_num: G3, peripheral: SEMC, signal: 'ADDR, 02', pin_signal: GPIO_EMC_11} + - {pin_num: H1, peripheral: SEMC, signal: 'ADDR, 03', pin_signal: GPIO_EMC_12} + - {pin_num: A6, peripheral: SEMC, signal: 'ADDR, 04', pin_signal: GPIO_EMC_13} + - {pin_num: B6, peripheral: SEMC, signal: 'ADDR, 05', pin_signal: GPIO_EMC_14} + - {pin_num: B1, peripheral: SEMC, signal: 'ADDR, 06', pin_signal: GPIO_EMC_15} + - {pin_num: A5, peripheral: SEMC, signal: 'ADDR, 07', pin_signal: GPIO_EMC_16} + - {pin_num: A4, peripheral: SEMC, signal: 'ADDR, 08', pin_signal: GPIO_EMC_17} + - {pin_num: B2, peripheral: SEMC, signal: 'ADDR, 09', pin_signal: GPIO_EMC_18} + - {pin_num: G2, peripheral: SEMC, signal: 'ADDR, 10', pin_signal: GPIO_EMC_23} + - {pin_num: B4, peripheral: SEMC, signal: 'ADDR, 11', pin_signal: GPIO_EMC_19} + - {pin_num: A3, peripheral: SEMC, signal: 'ADDR, 12', pin_signal: GPIO_EMC_20} + - {pin_num: C1, peripheral: SEMC, signal: 'BA, 0', pin_signal: GPIO_EMC_21} + - {pin_num: F1, peripheral: SEMC, signal: 'BA, 1', pin_signal: GPIO_EMC_22} + - {pin_num: D3, peripheral: SEMC, signal: semc_cas, pin_signal: GPIO_EMC_24} + - {pin_num: A2, peripheral: SEMC, signal: semc_cke, pin_signal: GPIO_EMC_27} + - {pin_num: B3, peripheral: SEMC, signal: semc_clk, pin_signal: GPIO_EMC_26} + - {pin_num: E3, peripheral: SEMC, signal: 'DATA, 00', pin_signal: GPIO_EMC_00} + - {pin_num: F3, peripheral: SEMC, signal: 'DATA, 01', pin_signal: GPIO_EMC_01} + - {pin_num: F4, peripheral: SEMC, signal: 'DATA, 02', pin_signal: GPIO_EMC_02} + - {pin_num: G4, peripheral: SEMC, signal: 'DATA, 03', pin_signal: GPIO_EMC_03} + - {pin_num: F2, peripheral: SEMC, signal: 'DATA, 04', pin_signal: GPIO_EMC_04} + - {pin_num: G5, peripheral: SEMC, signal: 'DATA, 05', pin_signal: GPIO_EMC_05} + - {pin_num: H5, peripheral: SEMC, signal: 'DATA, 06', pin_signal: GPIO_EMC_06} + - {pin_num: H4, peripheral: SEMC, signal: 'DATA, 07', pin_signal: GPIO_EMC_07} + - {pin_num: C6, peripheral: SEMC, signal: 'DATA, 08', pin_signal: GPIO_EMC_30} + - {pin_num: C5, peripheral: SEMC, signal: 'DATA, 09', pin_signal: GPIO_EMC_31} + - {pin_num: D5, peripheral: SEMC, signal: 'DATA, 10', pin_signal: GPIO_EMC_32} + - {pin_num: C4, peripheral: SEMC, signal: 'DATA, 11', pin_signal: GPIO_EMC_33} + - {pin_num: D4, peripheral: SEMC, signal: 'DATA, 12', pin_signal: GPIO_EMC_34} + - {pin_num: E5, peripheral: SEMC, signal: 'DATA, 13', pin_signal: GPIO_EMC_35} + - {pin_num: C3, peripheral: SEMC, signal: 'DATA, 14', pin_signal: GPIO_EMC_36} + - {pin_num: E4, peripheral: SEMC, signal: 'DATA, 15', pin_signal: GPIO_EMC_37} + - {pin_num: H3, peripheral: SEMC, signal: 'DM, 0', pin_signal: GPIO_EMC_08} + - {pin_num: D6, peripheral: SEMC, signal: 'DM, 1', pin_signal: GPIO_EMC_38} + - {pin_num: D2, peripheral: SEMC, signal: semc_ras, pin_signal: GPIO_EMC_25} + - {pin_num: D1, peripheral: SEMC, signal: semc_we, pin_signal: GPIO_EMC_28} + - {pin_num: E1, peripheral: SEMC, signal: 'CS, 0', pin_signal: GPIO_EMC_29} + - {pin_num: B7, peripheral: SEMC, signal: semc_dqs, pin_signal: GPIO_EMC_39} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitSDRAMPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitSDRAMPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_00_SEMC_DATA00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_01_SEMC_DATA01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_02_SEMC_DATA02, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_03_SEMC_DATA03, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_04_SEMC_DATA04, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_05_SEMC_DATA05, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_06_SEMC_DATA06, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_07_SEMC_DATA07, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_08_SEMC_DM00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_09_SEMC_ADDR00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_10_SEMC_ADDR01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_11_SEMC_ADDR02, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_12_SEMC_ADDR03, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_13_SEMC_ADDR04, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_14_SEMC_ADDR05, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_15_SEMC_ADDR06, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_16_SEMC_ADDR07, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_17_SEMC_ADDR08, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_18_SEMC_ADDR09, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_19_SEMC_ADDR11, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_20_SEMC_ADDR12, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_21_SEMC_BA0, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_22_SEMC_BA1, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_23_SEMC_ADDR10, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_24_SEMC_CAS, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_25_SEMC_RAS, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_26_SEMC_CLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_27_SEMC_CKE, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_28_SEMC_WE, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_29_SEMC_CS0, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_30_SEMC_DATA08, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_31_SEMC_DATA09, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_32_SEMC_DATA10, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_33_SEMC_DATA11, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_34_SEMC_DATA12, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_35_SEMC_DATA13, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_36_SEMC_DATA14, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_37_SEMC_DATA15, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_38_SEMC_DM01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_39_SEMC_DQS, 0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitCSIPins: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: H13, peripheral: CSI, signal: 'csi_data, 09', pin_signal: GPIO_AD_B1_08} + - {pin_num: M13, peripheral: CSI, signal: 'csi_data, 08', pin_signal: GPIO_AD_B1_09} + - {pin_num: L13, peripheral: CSI, signal: 'csi_data, 07', pin_signal: GPIO_AD_B1_10} + - {pin_num: J13, peripheral: CSI, signal: 'csi_data, 06', pin_signal: GPIO_AD_B1_11} + - {pin_num: H12, peripheral: CSI, signal: 'csi_data, 05', pin_signal: GPIO_AD_B1_12} + - {pin_num: H11, peripheral: CSI, signal: 'csi_data, 04', pin_signal: GPIO_AD_B1_13} + - {pin_num: J14, peripheral: CSI, signal: 'csi_data, 02', pin_signal: GPIO_AD_B1_15} + - {pin_num: G12, peripheral: CSI, signal: 'csi_data, 03', pin_signal: GPIO_AD_B1_14} + - {pin_num: L12, peripheral: CSI, signal: csi_pixclk, pin_signal: GPIO_AD_B1_04} + - {pin_num: K12, peripheral: CSI, signal: csi_mclk, pin_signal: GPIO_AD_B1_05} + - {pin_num: J12, peripheral: CSI, signal: csi_vsync, pin_signal: GPIO_AD_B1_06} + - {pin_num: K10, peripheral: CSI, signal: csi_hsync, pin_signal: GPIO_AD_B1_07} + - {pin_num: J11, peripheral: LPI2C1, signal: SCL, pin_signal: GPIO_AD_B1_00, identifier: CSI_I2C_SCL, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Up_22K_Ohm, + pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Enable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} + - {pin_num: K11, peripheral: LPI2C1, signal: SDA, pin_signal: GPIO_AD_B1_01, identifier: CSI_I2C_SDA, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Up_22K_Ohm, + pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Enable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} + - {pin_num: F11, peripheral: GPIO1, signal: 'gpio_io, 04', pin_signal: GPIO_AD_B0_04} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitCSIPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitCSIPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_04_GPIO1_IO04, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_04_CSI_PIXCLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_05_CSI_MCLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_06_CSI_VSYNC, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_07_CSI_HSYNC, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_08_CSI_DATA09, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_09_CSI_DATA08, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_10_CSI_DATA07, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_11_CSI_DATA06, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_12_CSI_DATA05, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_13_CSI_DATA04, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_14_CSI_DATA03, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_15_CSI_DATA02, 0U); + IOMUXC_GPR->GPR26 = ((IOMUXC_GPR->GPR26 & + (~(BOARD_INITCSIPINS_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK))) + | IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL(0x00U) + ); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL, 0xD8B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA, 0xD8B0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitLCDPins: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: C8, peripheral: LCDIF, signal: 'lcdif_data, 00', pin_signal: GPIO_B0_04, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: B8, peripheral: LCDIF, signal: 'lcdif_data, 01', pin_signal: GPIO_B0_05, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: A8, peripheral: LCDIF, signal: 'lcdif_data, 02', pin_signal: GPIO_B0_06, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: D7, peripheral: LCDIF, signal: lcdif_clk, pin_signal: GPIO_B0_00, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: A9, peripheral: LCDIF, signal: 'lcdif_data, 03', pin_signal: GPIO_B0_07, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: B9, peripheral: LCDIF, signal: 'lcdif_data, 04', pin_signal: GPIO_B0_08, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: C9, peripheral: LCDIF, signal: 'lcdif_data, 05', pin_signal: GPIO_B0_09, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: D9, peripheral: LCDIF, signal: 'lcdif_data, 06', pin_signal: GPIO_B0_10, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: A10, peripheral: LCDIF, signal: 'lcdif_data, 07', pin_signal: GPIO_B0_11, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: C10, peripheral: LCDIF, signal: 'lcdif_data, 08', pin_signal: GPIO_B0_12, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: D10, peripheral: LCDIF, signal: 'lcdif_data, 09', pin_signal: GPIO_B0_13, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: E10, peripheral: LCDIF, signal: 'lcdif_data, 10', pin_signal: GPIO_B0_14, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: E11, peripheral: LCDIF, signal: 'lcdif_data, 11', pin_signal: GPIO_B0_15, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: A11, peripheral: LCDIF, signal: 'lcdif_data, 12', pin_signal: GPIO_B1_00, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: B11, peripheral: LCDIF, signal: 'lcdif_data, 13', pin_signal: GPIO_B1_01, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: C11, peripheral: LCDIF, signal: 'lcdif_data, 14', pin_signal: GPIO_B1_02, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: D11, peripheral: LCDIF, signal: 'lcdif_data, 15', pin_signal: GPIO_B1_03, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: E7, peripheral: LCDIF, signal: lcdif_enable, pin_signal: GPIO_B0_01, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: E8, peripheral: LCDIF, signal: lcdif_hsync, pin_signal: GPIO_B0_02, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: D8, peripheral: LCDIF, signal: lcdif_vsync, pin_signal: GPIO_B0_03, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + - {pin_num: B14, peripheral: GPIO2, signal: 'gpio_io, 31', pin_signal: GPIO_B1_15, slew_rate: Slow} + - {pin_num: M11, peripheral: GPIO1, signal: 'gpio_io, 02', pin_signal: GPIO_AD_B0_02} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitLCDPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitLCDPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_02_GPIO1_IO02, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_00_LCD_CLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_01_LCD_ENABLE, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_02_LCD_HSYNC, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_03_LCD_VSYNC, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_04_LCD_DATA00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_05_LCD_DATA01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_06_LCD_DATA02, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_07_LCD_DATA03, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_08_LCD_DATA04, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_09_LCD_DATA05, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_10_LCD_DATA06, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_11_LCD_DATA07, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_12_LCD_DATA08, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_13_LCD_DATA09, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_14_LCD_DATA10, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_15_LCD_DATA11, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_00_LCD_DATA12, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_01_LCD_DATA13, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_02_LCD_DATA14, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_03_LCD_DATA15, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_15_GPIO2_IO31, 0U); + IOMUXC_GPR->GPR26 = ((IOMUXC_GPR->GPR26 & + (~(BOARD_INITLCDPINS_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK))) + | IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL(0x00U) + ); + IOMUXC_GPR->GPR27 = ((IOMUXC_GPR->GPR27 & + (~(BOARD_INITLCDPINS_IOMUXC_GPR_GPR27_GPIO_MUX2_GPIO_SEL_MASK))) + | IOMUXC_GPR_GPR27_GPIO_MUX2_GPIO_SEL(0x00U) + ); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_00_LCD_CLK, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_01_LCD_ENABLE, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_02_LCD_HSYNC, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_03_LCD_VSYNC, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_04_LCD_DATA00, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_05_LCD_DATA01, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_06_LCD_DATA02, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_07_LCD_DATA03, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_08_LCD_DATA04, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_09_LCD_DATA05, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_10_LCD_DATA06, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_11_LCD_DATA07, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_12_LCD_DATA08, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_13_LCD_DATA09, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_14_LCD_DATA10, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_15_LCD_DATA11, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_00_LCD_DATA12, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_01_LCD_DATA13, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_02_LCD_DATA14, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_03_LCD_DATA15, 0x01B0B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_15_GPIO2_IO31, 0x10B0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitCANPins: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: H14, peripheral: CAN2, signal: TX, pin_signal: GPIO_AD_B0_14} + - {pin_num: L10, peripheral: CAN2, signal: RX, pin_signal: GPIO_AD_B0_15} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitCANPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitCANPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_14_FLEXCAN2_TX, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_15_FLEXCAN2_RX, 0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitENETPins: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: A7, peripheral: ENET, signal: enet_mdc, pin_signal: GPIO_EMC_40} + - {pin_num: C7, peripheral: ENET, signal: enet_mdio, pin_signal: GPIO_EMC_41} + - {pin_num: B13, peripheral: ENET, signal: enet_ref_clk, pin_signal: GPIO_B1_10} + - {pin_num: E12, peripheral: ENET, signal: 'enet_rx_data, 0', pin_signal: GPIO_B1_04} + - {pin_num: D12, peripheral: ENET, signal: 'enet_rx_data, 1', pin_signal: GPIO_B1_05} + - {pin_num: C12, peripheral: ENET, signal: enet_rx_en, pin_signal: GPIO_B1_06} + - {pin_num: C13, peripheral: ENET, signal: enet_rx_er, pin_signal: GPIO_B1_11} + - {pin_num: B12, peripheral: ENET, signal: 'enet_tx_data, 0', pin_signal: GPIO_B1_07} + - {pin_num: A12, peripheral: ENET, signal: 'enet_tx_data, 1', pin_signal: GPIO_B1_08} + - {pin_num: A13, peripheral: ENET, signal: enet_tx_en, pin_signal: GPIO_B1_09} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitENETPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitENETPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_04_ENET_RX_DATA00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_05_ENET_RX_DATA01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_06_ENET_RX_EN, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_07_ENET_TX_DATA00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_08_ENET_TX_DATA01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_09_ENET_TX_EN, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_10_ENET_REF_CLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_11_ENET_RX_ER, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_40_ENET_MDC, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_41_ENET_MDIO, 0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitUSDHCPins: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: J2, peripheral: USDHC1, signal: 'usdhc_data, 3', pin_signal: GPIO_SD_B0_05} + - {pin_num: H2, peripheral: USDHC1, signal: 'usdhc_data, 2', pin_signal: GPIO_SD_B0_04} + - {pin_num: K1, peripheral: USDHC1, signal: 'usdhc_data, 1', pin_signal: GPIO_SD_B0_03} + - {pin_num: J1, peripheral: USDHC1, signal: 'usdhc_data, 0', pin_signal: GPIO_SD_B0_02} + - {pin_num: J4, peripheral: USDHC1, signal: usdhc_cmd, pin_signal: GPIO_SD_B0_00} + - {pin_num: J3, peripheral: USDHC1, signal: usdhc_clk, pin_signal: GPIO_SD_B0_01} + - {pin_num: C14, peripheral: USDHC1, signal: usdhc_vselect, pin_signal: GPIO_B1_14} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitUSDHCPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitUSDHCPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_14_USDHC1_VSELECT, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_00_USDHC1_CMD, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_01_USDHC1_CLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_02_USDHC1_DATA0, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_03_USDHC1_DATA1, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_04_USDHC1_DATA2, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_05_USDHC1_DATA3, 0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitQSPIPins: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: P3, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA0, pin_signal: GPIO_SD_B1_08} + - {pin_num: N4, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA1, pin_signal: GPIO_SD_B1_09} + - {pin_num: P4, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA2, pin_signal: GPIO_SD_B1_10} + - {pin_num: P5, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA3, pin_signal: GPIO_SD_B1_11} + - {pin_num: L4, peripheral: FLEXSPI, signal: FLEXSPI_A_SCLK, pin_signal: GPIO_SD_B1_07} + - {pin_num: L3, peripheral: FLEXSPI, signal: FLEXSPI_A_SS0_B, pin_signal: GPIO_SD_B1_06} + - {pin_num: N3, peripheral: FLEXSPI, signal: FLEXSPI_A_DQS, pin_signal: GPIO_SD_B1_05} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitQSPIPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitQSPIPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_05_FLEXSPIA_DQS, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_06_FLEXSPIA_SS0_B, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_07_FLEXSPIA_SCLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_08_FLEXSPIA_DATA00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_09_FLEXSPIA_DATA01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_10_FLEXSPIA_DATA02, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_11_FLEXSPIA_DATA03, 0U); +} + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/imxrt/boards/mimxrt1064_evk/board/pin_mux.h b/hw/bsp/imxrt/boards/mimxrt1064_evk/board/pin_mux.h new file mode 100644 index 000000000..bf494b6f6 --- /dev/null +++ b/hw/bsp/imxrt/boards/mimxrt1064_evk/board/pin_mux.h @@ -0,0 +1,744 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _PIN_MUX_H_ +#define _PIN_MUX_H_ + +/*********************************************************************************************************************** + * Definitions + **********************************************************************************************************************/ + +/*! @brief Direction type */ +typedef enum _pin_mux_direction +{ + kPIN_MUX_DirectionInput = 0U, /* Input direction */ + kPIN_MUX_DirectionOutput = 1U, /* Output direction */ + kPIN_MUX_DirectionInputOrOutput = 2U /* Input or output direction */ +} pin_mux_direction_t; + +/*! + * @addtogroup pin_mux + * @{ + */ + +/*********************************************************************************************************************** + * API + **********************************************************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Calls initialization functions. + * + */ +void BOARD_InitBootPins(void); + +#define BOARD_INITPINS_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK 0x0200U /*!< GPIO1 and GPIO6 share same IO MUX function, GPIO_MUX1 selects one GPIO function: affected bits mask */ + +/* GPIO_AD_B0_09 (coord F14), JTAG_TDI/J21[5]/ENET_RST/J22[5] */ +/* Routed pin properties */ +#define BOARD_INITPINS_USER_LED_PERIPHERAL GPIO1 /*!< Peripheral name */ +#define BOARD_INITPINS_USER_LED_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITPINS_USER_LED_CHANNEL 9U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_USER_LED_GPIO GPIO1 /*!< GPIO peripheral base pointer */ +#define BOARD_INITPINS_USER_LED_GPIO_PIN 9U /*!< GPIO pin number */ +#define BOARD_INITPINS_USER_LED_GPIO_PIN_MASK (1U << 9U) /*!< GPIO pin mask */ +#define BOARD_INITPINS_USER_LED_PORT GPIO1 /*!< PORT peripheral base pointer */ +#define BOARD_INITPINS_USER_LED_PIN 9U /*!< PORT pin number */ +#define BOARD_INITPINS_USER_LED_PIN_MASK (1U << 9U) /*!< PORT pin mask */ + +/* WAKEUP (coord L6), SD_PWREN */ +/* Routed pin properties */ +#define BOARD_INITPINS_USER_BUTTON_PERIPHERAL GPIO5 /*!< Peripheral name */ +#define BOARD_INITPINS_USER_BUTTON_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITPINS_USER_BUTTON_CHANNEL 0U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_USER_BUTTON_GPIO GPIO5 /*!< GPIO peripheral base pointer */ +#define BOARD_INITPINS_USER_BUTTON_GPIO_PIN 0U /*!< GPIO pin number */ +#define BOARD_INITPINS_USER_BUTTON_GPIO_PIN_MASK (1U << 0U) /*!< GPIO pin mask */ +#define BOARD_INITPINS_USER_BUTTON_PORT GPIO5 /*!< PORT peripheral base pointer */ +#define BOARD_INITPINS_USER_BUTTON_PIN 0U /*!< PORT pin number */ +#define BOARD_INITPINS_USER_BUTTON_PIN_MASK (1U << 0U) /*!< PORT pin mask */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitPins(void); + +/* GPIO_AD_B0_12 (coord K14), UART1_TXD */ +/* Routed pin properties */ +#define BOARD_INITDEBUG_UARTPINS_UART1_TXD_PERIPHERAL LPUART1 /*!< Peripheral name */ +#define BOARD_INITDEBUG_UARTPINS_UART1_TXD_SIGNAL TX /*!< Signal name */ + +/* GPIO_AD_B0_13 (coord L14), UART1_RXD */ +/* Routed pin properties */ +#define BOARD_INITDEBUG_UARTPINS_UART1_RXD_PERIPHERAL LPUART1 /*!< Peripheral name */ +#define BOARD_INITDEBUG_UARTPINS_UART1_RXD_SIGNAL RX /*!< Signal name */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitDEBUG_UARTPins(void); + +/* GPIO_EMC_09 (coord C2), SEMC_A0 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A0_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A0_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_EMC_10 (coord G1), SEMC_A1 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A1_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A1_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_EMC_11 (coord G3), SEMC_A2 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A2_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A2_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A2_CHANNEL 2U /*!< Signal channel */ + +/* GPIO_EMC_12 (coord H1), SEMC_A3 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A3_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A3_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A3_CHANNEL 3U /*!< Signal channel */ + +/* GPIO_EMC_13 (coord A6), SEMC_A4 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A4_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A4_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A4_CHANNEL 4U /*!< Signal channel */ + +/* GPIO_EMC_14 (coord B6), SEMC_A5 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A5_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A5_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A5_CHANNEL 5U /*!< Signal channel */ + +/* GPIO_EMC_15 (coord B1), SEMC_A6 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A6_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A6_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A6_CHANNEL 6U /*!< Signal channel */ + +/* GPIO_EMC_16 (coord A5), SEMC_A7 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A7_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A7_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A7_CHANNEL 7U /*!< Signal channel */ + +/* GPIO_EMC_17 (coord A4), SEMC_A8 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A8_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A8_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A8_CHANNEL 8U /*!< Signal channel */ + +/* GPIO_EMC_18 (coord B2), SEMC_A9 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A9_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A9_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A9_CHANNEL 9U /*!< Signal channel */ + +/* GPIO_EMC_23 (coord G2), SEMC_A10 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A10_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A10_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A10_CHANNEL 10U /*!< Signal channel */ + +/* GPIO_EMC_19 (coord B4), SEMC_A11 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A11_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A11_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A11_CHANNEL 11U /*!< Signal channel */ + +/* GPIO_EMC_20 (coord A3), SEMC_A12 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_A12_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_A12_SIGNAL ADDR /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_A12_CHANNEL 12U /*!< Signal channel */ + +/* GPIO_EMC_21 (coord C1), SEMC_BA0 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_BA0_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_BA0_SIGNAL BA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_BA0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_EMC_22 (coord F1), SEMC_BA1 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_BA1_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_BA1_SIGNAL BA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_BA1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_EMC_24 (coord D3), SEMC_CAS */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_CAS_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_CAS_SIGNAL semc_cas /*!< Signal name */ + +/* GPIO_EMC_27 (coord A2), SEMC_CKE */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_CKE_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_CKE_SIGNAL semc_cke /*!< Signal name */ + +/* GPIO_EMC_26 (coord B3), SEMC_CLK */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_CLK_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_CLK_SIGNAL semc_clk /*!< Signal name */ + +/* GPIO_EMC_00 (coord E3), SEMC_D0 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D0_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D0_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_EMC_01 (coord F3), SEMC_D1 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D1_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D1_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_EMC_02 (coord F4), SEMC_D2 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D2_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D2_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D2_CHANNEL 2U /*!< Signal channel */ + +/* GPIO_EMC_03 (coord G4), SEMC_D3 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D3_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D3_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D3_CHANNEL 3U /*!< Signal channel */ + +/* GPIO_EMC_04 (coord F2), SEMC_D4 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D4_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D4_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D4_CHANNEL 4U /*!< Signal channel */ + +/* GPIO_EMC_05 (coord G5), SEMC_D5 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D5_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D5_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D5_CHANNEL 5U /*!< Signal channel */ + +/* GPIO_EMC_06 (coord H5), SEMC_D6 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D6_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D6_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D6_CHANNEL 6U /*!< Signal channel */ + +/* GPIO_EMC_07 (coord H4), SEMC_D7 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D7_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D7_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D7_CHANNEL 7U /*!< Signal channel */ + +/* GPIO_EMC_30 (coord C6), SEMC_D8 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D8_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D8_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D8_CHANNEL 8U /*!< Signal channel */ + +/* GPIO_EMC_31 (coord C5), SEMC_D9 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D9_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D9_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D9_CHANNEL 9U /*!< Signal channel */ + +/* GPIO_EMC_32 (coord D5), SEMC_D10 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D10_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D10_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D10_CHANNEL 10U /*!< Signal channel */ + +/* GPIO_EMC_33 (coord C4), SEMC_D11 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D11_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D11_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D11_CHANNEL 11U /*!< Signal channel */ + +/* GPIO_EMC_34 (coord D4), SEMC_D12 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D12_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D12_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D12_CHANNEL 12U /*!< Signal channel */ + +/* GPIO_EMC_35 (coord E5), SEMC_D13 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D13_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D13_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D13_CHANNEL 13U /*!< Signal channel */ + +/* GPIO_EMC_36 (coord C3), SEMC_D14 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D14_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D14_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D14_CHANNEL 14U /*!< Signal channel */ + +/* GPIO_EMC_37 (coord E4), SEMC_D15 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_D15_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_D15_SIGNAL DATA /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_D15_CHANNEL 15U /*!< Signal channel */ + +/* GPIO_EMC_08 (coord H3), SEMC_DM0 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_DM0_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_DM0_SIGNAL DM /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_DM0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_EMC_38 (coord D6), SEMC_DM1 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_DM1_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_DM1_SIGNAL DM /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_DM1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_EMC_25 (coord D2), SEMC_RAS */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_RAS_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_RAS_SIGNAL semc_ras /*!< Signal name */ + +/* GPIO_EMC_28 (coord D1), SEMC_WE */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_WE_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_WE_SIGNAL semc_we /*!< Signal name */ + +/* GPIO_EMC_29 (coord E1), SEMC_CS0 */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_CS0_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_CS0_SIGNAL CS /*!< Signal name */ +#define BOARD_INITSDRAMPINS_SEMC_CS0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_EMC_39 (coord B7), SEMC_DQS */ +/* Routed pin properties */ +#define BOARD_INITSDRAMPINS_SEMC_DQS_PERIPHERAL SEMC /*!< Peripheral name */ +#define BOARD_INITSDRAMPINS_SEMC_DQS_SIGNAL semc_dqs /*!< Signal name */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitSDRAMPins(void); + +#define BOARD_INITCSIPINS_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK 0x10U /*!< GPIO1 and GPIO6 share same IO MUX function, GPIO_MUX1 selects one GPIO function: affected bits mask */ + +/* GPIO_AD_B1_08 (coord H13), AUD_INT/CSI_D9//J35[13]/J22[4] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_D9_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_D9_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSIPINS_CSI_D9_CHANNEL 9U /*!< Signal channel */ + +/* GPIO_AD_B1_09 (coord M13), SAI1_MCLK/CSI_D8/J35[11] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_D8_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_D8_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSIPINS_CSI_D8_CHANNEL 8U /*!< Signal channel */ + +/* GPIO_AD_B1_10 (coord L13), SAI1_RX_SYNC/CSI_D7/J35[9]/J23[1] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_D7_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_D7_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSIPINS_CSI_D7_CHANNEL 7U /*!< Signal channel */ + +/* GPIO_AD_B1_11 (coord J13), SAI1_RX_BCLK/CSI_D6/J35[7]/J23[2] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_D6_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_D6_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSIPINS_CSI_D6_CHANNEL 6U /*!< Signal channel */ + +/* GPIO_AD_B1_12 (coord H12), SAI1_RXD/CSI_D5/J35[5]/U13[16] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_D5_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_D5_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSIPINS_CSI_D5_CHANNEL 5U /*!< Signal channel */ + +/* GPIO_AD_B1_13 (coord H11), SAI1_TXD/CSI_D4/J35[3]/U13[14] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_D4_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_D4_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSIPINS_CSI_D4_CHANNEL 4U /*!< Signal channel */ + +/* GPIO_AD_B1_15 (coord J14), SAI1_TX_SYNC/CSI_D2/J35[6]/U13[13] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_D2_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_D2_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSIPINS_CSI_D2_CHANNEL 2U /*!< Signal channel */ + +/* GPIO_AD_B1_14 (coord G12), SAI1_TX_BCLK/CSI_D3/J35[4]/U13[12] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_D3_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_D3_SIGNAL csi_data /*!< Signal name */ +#define BOARD_INITCSIPINS_CSI_D3_CHANNEL 3U /*!< Signal channel */ + +/* GPIO_AD_B1_04 (coord L12), CSI_PIXCLK/J35[8]/J23[3] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_PIXCLK_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_PIXCLK_SIGNAL csi_pixclk /*!< Signal name */ + +/* GPIO_AD_B1_05 (coord K12), CSI_MCLK/J35[12]/J23[4] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_MCLK_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_MCLK_SIGNAL csi_mclk /*!< Signal name */ + +/* GPIO_AD_B1_06 (coord J12), CSI_VSYNC/J35[18]/J22[2]/UART_TX */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_VSYNC_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_VSYNC_SIGNAL csi_vsync /*!< Signal name */ + +/* GPIO_AD_B1_07 (coord K10), CSI_HSYNC/J35[16]/J22[1]/UART_RX */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_HSYNC_PERIPHERAL CSI /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_HSYNC_SIGNAL csi_hsync /*!< Signal name */ + +/* GPIO_AD_B1_00 (coord J11), I2C1_SCL/CSI_I2C_SCL/J35[20]/J23[6]/U13[17]/U32[4] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_I2C_SCL_PERIPHERAL LPI2C1 /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_I2C_SCL_SIGNAL SCL /*!< Signal name */ + +/* GPIO_AD_B1_01 (coord K11), I2C1_SDA/CSI_I2C_SDA/J35[22]/J23[5]/U13[18]/U32[6] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_I2C_SDA_PERIPHERAL LPI2C1 /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_I2C_SDA_SIGNAL SDA /*!< Signal name */ + +/* GPIO_AD_B0_04 (coord F11), CSI_PWDN/J35[17]/BOOT_MODE[0] */ +/* Routed pin properties */ +#define BOARD_INITCSIPINS_CSI_PWDN_PERIPHERAL GPIO1 /*!< Peripheral name */ +#define BOARD_INITCSIPINS_CSI_PWDN_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITCSIPINS_CSI_PWDN_CHANNEL 4U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITCSIPINS_CSI_PWDN_GPIO GPIO1 /*!< GPIO peripheral base pointer */ +#define BOARD_INITCSIPINS_CSI_PWDN_GPIO_PIN 4U /*!< GPIO pin number */ +#define BOARD_INITCSIPINS_CSI_PWDN_GPIO_PIN_MASK (1U << 4U) /*!< GPIO pin mask */ +#define BOARD_INITCSIPINS_CSI_PWDN_PORT GPIO1 /*!< PORT peripheral base pointer */ +#define BOARD_INITCSIPINS_CSI_PWDN_PIN 4U /*!< PORT pin number */ +#define BOARD_INITCSIPINS_CSI_PWDN_PIN_MASK (1U << 4U) /*!< PORT pin mask */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitCSIPins(void); + +#define BOARD_INITLCDPINS_IOMUXC_GPR_GPR26_GPIO_MUX1_GPIO_SEL_MASK 0x04U /*!< GPIO1 and GPIO6 share same IO MUX function, GPIO_MUX1 selects one GPIO function: affected bits mask */ +#define BOARD_INITLCDPINS_IOMUXC_GPR_GPR27_GPIO_MUX2_GPIO_SEL_MASK 0x80000000U /*!< GPIO2 and GPIO7 share same IO MUX function, GPIO_MUX2 selects one GPIO function: affected bits mask */ + +/* GPIO_B0_04 (coord C8), LCDIF_D0/BT_CFG[0] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D0_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D0_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_B0_05 (coord B8), LCDIF_D1/BT_CFG[1] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D1_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D1_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_B0_06 (coord A8), LCDIF_D2/BT_CFG[2] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D2_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D2_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D2_CHANNEL 2U /*!< Signal channel */ + +/* GPIO_B0_00 (coord D7), LCDIF_CLK */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_CLK_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_CLK_SIGNAL lcdif_clk /*!< Signal name */ + +/* GPIO_B0_07 (coord A9), LCDIF_D3/BT_CFG[3] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D3_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D3_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D3_CHANNEL 3U /*!< Signal channel */ + +/* GPIO_B0_08 (coord B9), LCDIF_D4/BT_CFG[4] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D4_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D4_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D4_CHANNEL 4U /*!< Signal channel */ + +/* GPIO_B0_09 (coord C9), LCDIF_D5/BT_CFG[5] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D5_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D5_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D5_CHANNEL 5U /*!< Signal channel */ + +/* GPIO_B0_10 (coord D9), LCDIF_D6/BT_CFG[6] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D6_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D6_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D6_CHANNEL 6U /*!< Signal channel */ + +/* GPIO_B0_11 (coord A10), LCDIF_D7/BT_CFG[7] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D7_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D7_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D7_CHANNEL 7U /*!< Signal channel */ + +/* GPIO_B0_12 (coord C10), LCDIF_D8/BT_CFG[8] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D8_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D8_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D8_CHANNEL 8U /*!< Signal channel */ + +/* GPIO_B0_13 (coord D10), LCDIF_D9/BT_CFG[9] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D9_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D9_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D9_CHANNEL 9U /*!< Signal channel */ + +/* GPIO_B0_14 (coord E10), LCDIF_D10/BT_CFG[10] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D10_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D10_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D10_CHANNEL 10U /*!< Signal channel */ + +/* GPIO_B0_15 (coord E11), LCDIF_D11/BT_CFG[11] */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D11_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D11_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D11_CHANNEL 11U /*!< Signal channel */ + +/* GPIO_B1_00 (coord A11), LCDIF_D12 */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D12_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D12_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D12_CHANNEL 12U /*!< Signal channel */ + +/* GPIO_B1_01 (coord B11), LCDIF_D13 */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D13_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D13_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D13_CHANNEL 13U /*!< Signal channel */ + +/* GPIO_B1_02 (coord C11), LCDIF_D14 */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D14_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D14_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D14_CHANNEL 14U /*!< Signal channel */ + +/* GPIO_B1_03 (coord D11), LCDIF_D15 */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_D15_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_D15_SIGNAL lcdif_data /*!< Signal name */ +#define BOARD_INITLCDPINS_LCDIF_D15_CHANNEL 15U /*!< Signal channel */ + +/* GPIO_B0_01 (coord E7), LCDIF_ENABLE */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_ENABLE_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_ENABLE_SIGNAL lcdif_enable /*!< Signal name */ + +/* GPIO_B0_02 (coord E8), LCDIF_HSYNC */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_HSYNC_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_HSYNC_SIGNAL lcdif_hsync /*!< Signal name */ + +/* GPIO_B0_03 (coord D8), LCDIF_VSYNC */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_LCDIF_VSYNC_PERIPHERAL LCDIF /*!< Peripheral name */ +#define BOARD_INITLCDPINS_LCDIF_VSYNC_SIGNAL lcdif_vsync /*!< Signal name */ + +/* GPIO_B1_15 (coord B14), USB_HOST_PWR/BACKLIGHT_CTL */ +/* Routed pin properties */ +#define BOARD_INITLCDPINS_BACKLIGHT_CTL_PERIPHERAL GPIO2 /*!< Peripheral name */ +#define BOARD_INITLCDPINS_BACKLIGHT_CTL_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITLCDPINS_BACKLIGHT_CTL_CHANNEL 31U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITLCDPINS_BACKLIGHT_CTL_GPIO GPIO2 /*!< GPIO peripheral base pointer */ +#define BOARD_INITLCDPINS_BACKLIGHT_CTL_GPIO_PIN 31U /*!< GPIO pin number */ +#define BOARD_INITLCDPINS_BACKLIGHT_CTL_GPIO_PIN_MASK (1U << 31U) /*!< GPIO pin mask */ +#define BOARD_INITLCDPINS_BACKLIGHT_CTL_PORT GPIO2 /*!< PORT peripheral base pointer */ +#define BOARD_INITLCDPINS_BACKLIGHT_CTL_PIN 31U /*!< PORT pin number */ +#define BOARD_INITLCDPINS_BACKLIGHT_CTL_PIN_MASK (1U << 31U) /*!< PORT pin mask */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitLCDPins(void); + +/* GPIO_AD_B0_14 (coord H14), CAN2_TX/U12[1] */ +/* Routed pin properties */ +#define BOARD_INITCANPINS_CAN2_TX_PERIPHERAL CAN2 /*!< Peripheral name */ +#define BOARD_INITCANPINS_CAN2_TX_SIGNAL TX /*!< Signal name */ + +/* GPIO_AD_B0_15 (coord L10), CAN2_RX/U12[4] */ +/* Routed pin properties */ +#define BOARD_INITCANPINS_CAN2_RX_PERIPHERAL CAN2 /*!< Peripheral name */ +#define BOARD_INITCANPINS_CAN2_RX_SIGNAL RX /*!< Signal name */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitCANPins(void); + +/* GPIO_EMC_40 (coord A7), ENET_MDC */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_MDC_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_MDC_SIGNAL enet_mdc /*!< Signal name */ + +/* GPIO_EMC_41 (coord C7), ENET_MDIO */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_MDIO_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_MDIO_SIGNAL enet_mdio /*!< Signal name */ + +/* GPIO_B1_10 (coord B13), ENET_TX_CLK */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_TX_CLK_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_TX_CLK_SIGNAL enet_ref_clk /*!< Signal name */ + +/* GPIO_B1_04 (coord E12), ENET_RXD0 */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_RXD0_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_RXD0_SIGNAL enet_rx_data /*!< Signal name */ +#define BOARD_INITENETPINS_ENET_RXD0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_B1_05 (coord D12), ENET_RXD1 */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_RXD1_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_RXD1_SIGNAL enet_rx_data /*!< Signal name */ +#define BOARD_INITENETPINS_ENET_RXD1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_B1_06 (coord C12), ENET_CRS_DV */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_CRS_DV_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_CRS_DV_SIGNAL enet_rx_en /*!< Signal name */ + +/* GPIO_B1_11 (coord C13), ENET_RXER */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_RXER_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_RXER_SIGNAL enet_rx_er /*!< Signal name */ + +/* GPIO_B1_07 (coord B12), ENET_TXD0 */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_TXD0_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_TXD0_SIGNAL enet_tx_data /*!< Signal name */ +#define BOARD_INITENETPINS_ENET_TXD0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_B1_08 (coord A12), ENET_TXD1 */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_TXD1_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_TXD1_SIGNAL enet_tx_data /*!< Signal name */ +#define BOARD_INITENETPINS_ENET_TXD1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_B1_09 (coord A13), ENET_TXEN */ +/* Routed pin properties */ +#define BOARD_INITENETPINS_ENET_TXEN_PERIPHERAL ENET /*!< Peripheral name */ +#define BOARD_INITENETPINS_ENET_TXEN_SIGNAL enet_tx_en /*!< Signal name */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitENETPins(void); + +/* GPIO_SD_B0_05 (coord J2), SD1_D3 */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_D3_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_D3_SIGNAL usdhc_data /*!< Signal name */ +#define BOARD_INITUSDHCPINS_SD1_D3_CHANNEL 3U /*!< Signal channel */ + +/* GPIO_SD_B0_04 (coord H2), SD1_D2 */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_D2_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_D2_SIGNAL usdhc_data /*!< Signal name */ +#define BOARD_INITUSDHCPINS_SD1_D2_CHANNEL 2U /*!< Signal channel */ + +/* GPIO_SD_B0_03 (coord K1), SD1_D1/J24[5]/SPI_MISO */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_D1_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_D1_SIGNAL usdhc_data /*!< Signal name */ +#define BOARD_INITUSDHCPINS_SD1_D1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_SD_B0_02 (coord J1), SD1_D0/J24[4]/SPI_MOSI/PWM */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_D0_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_D0_SIGNAL usdhc_data /*!< Signal name */ +#define BOARD_INITUSDHCPINS_SD1_D0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_SD_B0_00 (coord J4), SD1_CMD/J24[6] */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_CMD_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_CMD_SIGNAL usdhc_cmd /*!< Signal name */ + +/* GPIO_SD_B0_01 (coord J3), SD1_CLK/J24[3] */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_CLK_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_CLK_SIGNAL usdhc_clk /*!< Signal name */ + +/* GPIO_B1_14 (coord C14), SD0_VSELECT */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD0_VSELECT_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD0_VSELECT_SIGNAL usdhc_vselect /*!< Signal name */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitUSDHCPins(void); + +/* GPIO_SD_B1_08 (coord P3), FlexSPI_D0_A */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_D0_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_D0_A_SIGNAL FLEXSPI_A_DATA0 /*!< Signal name */ + +/* GPIO_SD_B1_09 (coord N4), FlexSPI_D1_A */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_D1_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_D1_A_SIGNAL FLEXSPI_A_DATA1 /*!< Signal name */ + +/* GPIO_SD_B1_10 (coord P4), FlexSPI_D2_A */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_D2_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_D2_A_SIGNAL FLEXSPI_A_DATA2 /*!< Signal name */ + +/* GPIO_SD_B1_11 (coord P5), FlexSPI_D3_A */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_D3_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_D3_A_SIGNAL FLEXSPI_A_DATA3 /*!< Signal name */ + +/* GPIO_SD_B1_07 (coord L4), FlexSPI_CLK */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_CLK_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_CLK_SIGNAL FLEXSPI_A_SCLK /*!< Signal name */ + +/* GPIO_SD_B1_06 (coord L3), FlexSPI_SS0 */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_SS0_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_SS0_SIGNAL FLEXSPI_A_SS0_B /*!< Signal name */ + +/* GPIO_SD_B1_05 (coord N3), FlexSPI_DQS */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_DQS_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_DQS_SIGNAL FLEXSPI_A_DQS /*!< Signal name */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitQSPIPins(void); + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif /* _PIN_MUX_H_ */ + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/imxrt/boards/mimxrt1064_evk/evkmimxrt1064_flexspi_nor_config.c b/hw/bsp/imxrt/boards/mimxrt1064_evk/evkmimxrt1064_flexspi_nor_config.c index bfb1c2d59..9d30f26bd 100644 --- a/hw/bsp/imxrt/boards/mimxrt1064_evk/evkmimxrt1064_flexspi_nor_config.c +++ b/hw/bsp/imxrt/boards/mimxrt1064_evk/evkmimxrt1064_flexspi_nor_config.c @@ -17,7 +17,7 @@ ******************************************************************************/ #if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) #if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) -__attribute__((section(".boot_hdr.conf"))) +__attribute__((section(".boot_hdr.conf"), used)) #elif defined(__ICCARM__) #pragma location = ".boot_hdr.conf" #endif diff --git a/hw/bsp/imxrt/boards/mimxrt1064_evk/mimxrt1064_evk.mex b/hw/bsp/imxrt/boards/mimxrt1064_evk/mimxrt1064_evk.mex index 5e0fc72d3..3f0948101 100644 --- a/hw/bsp/imxrt/boards/mimxrt1064_evk/mimxrt1064_evk.mex +++ b/hw/bsp/imxrt/boards/mimxrt1064_evk/mimxrt1064_evk.mex @@ -26,6 +26,10 @@ 13.0.2 + + + + @@ -37,13 +41,40 @@ true + + + true + + true + + + true + + + + + true + + - + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. @@ -719,7 +750,7 @@ - + diff --git a/hw/bsp/imxrt/boards/mimxrt1170_evkb/board.cmake b/hw/bsp/imxrt/boards/mimxrt1170_evkb/board.cmake new file mode 100644 index 000000000..692d9e498 --- /dev/null +++ b/hw/bsp/imxrt/boards/mimxrt1170_evkb/board.cmake @@ -0,0 +1,17 @@ +set(MCU_VARIANT MIMXRT1176) +set(MCU_CORE _cm7) + +set(JLINK_DEVICE MIMXRT1176xxxA_M7) +set(PYOCD_TARGET mimxrt1170_cm7) +set(NXPLINK_DEVICE MIMXRT1176xxxxx:MIMXRT1170-EVK) + +function(update_board TARGET) + target_sources(${TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/evkbmimxrt1170_flexspi_nor_config.c + ) + target_compile_definitions(${TARGET} PUBLIC + CPU_MIMXRT1176DVMAA_cm7 + BOARD_TUD_RHPORT=0 + BOARD_TUH_RHPORT=1 + ) +endfunction() diff --git a/hw/bsp/imxrt/boards/mimxrt1170_evkb/board.h b/hw/bsp/imxrt/boards/mimxrt1170_evkb/board.h new file mode 100644 index 000000000..303935517 --- /dev/null +++ b/hw/bsp/imxrt/boards/mimxrt1170_evkb/board.h @@ -0,0 +1,47 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019, 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_MIMXRT1170_EVKB_H_ +#define BOARD_MIMXRT1170_EVKB_H_ + +// required since iMXRT MCUX-SDK include this file for board size +#define BOARD_FLASH_SIZE (0x1000000U) + +// LED: IOMUXC_GPIO_AD_04_GPIO9_IO03 +#define LED_PORT BOARD_INITPINS_USER_LED_PERIPHERAL +#define LED_PIN BOARD_INITPINS_USER_LED_CHANNEL +#define LED_STATE_ON 0 + +// SW8 button: IOMUXC_WAKEUP_DIG_GPIO13_IO00 +#define BUTTON_PORT BOARD_INITPINS_USER_BUTTON_PERIPHERAL +#define BUTTON_PIN BOARD_INITPINS_USER_BUTTON_CHANNEL +#define BUTTON_STATE_ACTIVE 0 + +// UART: IOMUXC_GPIO_AD_B0_13_LPUART1_RX, IOMUXC_GPIO_AD_B0_12_LPUART1_TX +#define UART_PORT LPUART1 +#define UART_CLK_ROOT BOARD_BOOTCLOCKRUN_LPUART10_CLK_ROOT + +#endif diff --git a/hw/bsp/imxrt/boards/mimxrt1170_evkb/board.mk b/hw/bsp/imxrt/boards/mimxrt1170_evkb/board.mk new file mode 100644 index 000000000..e8500a4c9 --- /dev/null +++ b/hw/bsp/imxrt/boards/mimxrt1170_evkb/board.mk @@ -0,0 +1,15 @@ +CFLAGS += -DCPU_MIMXRT1176DVMAA_cm7 +MCU_VARIANT = MIMXRT1176 +MCU_CORE = _cm7 + +# For flash-jlink target +JLINK_DEVICE = MIMXRT1176xxxA_M7 + +# For flash-pyocd target +PYOCD_TARGET = mimxrt1170_cm7 + +BOARD_TUD_RHPORT = 0 +BOARD_TUH_RHPORT = 1 + +# flash using pyocd +flash: flash-pyocd diff --git a/hw/bsp/imxrt/boards/mimxrt1170_evkb/board/clock_config.c b/hw/bsp/imxrt/boards/mimxrt1170_evkb/board/clock_config.c new file mode 100644 index 000000000..88b3b3770 --- /dev/null +++ b/hw/bsp/imxrt/boards/mimxrt1170_evkb/board/clock_config.c @@ -0,0 +1,879 @@ +/* + * How to setup clock using clock driver functions: + * + * 1. Call CLOCK_InitXXXPLL() to configure corresponding PLL clock. + * + * 2. Call CLOCK_InitXXXpfd() to configure corresponding PLL pfd clock. + * + * 3. Call CLOCK_SetRootClock() to configure corresponding module clock source and divider. + * + */ + +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Clocks v12.0 +processor: MIMXRT1176xxxxx +package_id: MIMXRT1176DVMAA +mcu_data: ksdk2_0 +processor_version: 14.0.1 +board: MIMXRT1170-EVKB + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ + +#include "clock_config.h" +#include "fsl_iomuxc.h" +#include "fsl_dcdc.h" +#include "fsl_pmu.h" +#include "fsl_clock.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ +void BOARD_InitBootClocks(void) +{ + BOARD_BootClockRUN(); +} + +#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1) +/* This function should not run from SDRAM since it will change SEMC configuration. */ +AT_QUICKACCESS_SECTION_CODE(void UpdateSemcClock(void)); +void UpdateSemcClock(void) +{ + /* Enable self-refresh mode and update semc clock root to 200MHz. */ + SEMC->IPCMD = 0xA55A000D; + while ((SEMC->INTR & 0x3) == 0) + ; + SEMC->INTR = 0x3; + SEMC->DCCR = 0x0B; + /* + * Currently we are using SEMC parameter which fit both 166MHz and 200MHz, only + * need to change the SEMC clock root here. If customer is using their own DCD and + * want to switch from 166MHz to 200MHz, extra SEMC configuration might need to be + * adjusted here to fine tune the SDRAM performance + */ + CCM->CLOCK_ROOT[kCLOCK_Root_Semc].CONTROL = 0x602; +} +#endif +#endif + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockRUN +called_from_default_init: true +outputs: +- {id: ACMP_CLK_ROOT.outFreq, value: 24 MHz} +- {id: ADC1_CLK_ROOT.outFreq, value: 24 MHz} +- {id: ADC2_CLK_ROOT.outFreq, value: 24 MHz} +- {id: ARM_PLL_CLK.outFreq, value: 996 MHz} +- {id: ASRC_CLK_ROOT.outFreq, value: 24 MHz} +- {id: AXI_CLK_ROOT.outFreq, value: 996 MHz} +- {id: BUS_CLK_ROOT.outFreq, value: 240 MHz} +- {id: BUS_LPSR_CLK_ROOT.outFreq, value: 160 MHz} +- {id: CAN1_CLK_ROOT.outFreq, value: 24 MHz} +- {id: CAN2_CLK_ROOT.outFreq, value: 24 MHz} +- {id: CAN3_CLK_ROOT.outFreq, value: 24 MHz} +- {id: CCM_CLKO1_CLK_ROOT.outFreq, value: 24 MHz} +- {id: CCM_CLKO2_CLK_ROOT.outFreq, value: 24 MHz} +- {id: CLK_1M.outFreq, value: 1 MHz} +- {id: CSI2_CLK_ROOT.outFreq, value: 24 MHz} +- {id: CSI2_ESC_CLK_ROOT.outFreq, value: 24 MHz} +- {id: CSI2_UI_CLK_ROOT.outFreq, value: 24 MHz} +- {id: CSI_CLK_ROOT.outFreq, value: 24 MHz} +- {id: CSSYS_CLK_ROOT.outFreq, value: 24 MHz} +- {id: CSTRACE_CLK_ROOT.outFreq, value: 132 MHz} +- {id: ELCDIF_CLK_ROOT.outFreq, value: 24 MHz} +- {id: EMV1_CLK_ROOT.outFreq, value: 24 MHz} +- {id: EMV2_CLK_ROOT.outFreq, value: 24 MHz} +- {id: ENET1_CLK_ROOT.outFreq, value: 24 MHz} +- {id: ENET2_CLK_ROOT.outFreq, value: 24 MHz} +- {id: ENET_1G_TX_CLK.outFreq, value: 24 MHz} +- {id: ENET_25M_CLK_ROOT.outFreq, value: 24 MHz} +- {id: ENET_QOS_CLK_ROOT.outFreq, value: 24 MHz} +- {id: ENET_TIMER1_CLK_ROOT.outFreq, value: 24 MHz} +- {id: ENET_TIMER2_CLK_ROOT.outFreq, value: 24 MHz} +- {id: ENET_TIMER3_CLK_ROOT.outFreq, value: 24 MHz} +- {id: FLEXIO1_CLK_ROOT.outFreq, value: 24 MHz} +- {id: FLEXIO2_CLK_ROOT.outFreq, value: 24 MHz} +- {id: FLEXSPI1_CLK_ROOT.outFreq, value: 24 MHz} +- {id: FLEXSPI2_CLK_ROOT.outFreq, value: 24 MHz} +- {id: GC355_CLK_ROOT.outFreq, value: 492.0000125 MHz} +- {id: GPT1_CLK_ROOT.outFreq, value: 24 MHz} +- {id: GPT1_ipg_clk_highfreq.outFreq, value: 24 MHz} +- {id: GPT2_CLK_ROOT.outFreq, value: 24 MHz} +- {id: GPT2_ipg_clk_highfreq.outFreq, value: 24 MHz} +- {id: GPT3_CLK_ROOT.outFreq, value: 24 MHz} +- {id: GPT3_ipg_clk_highfreq.outFreq, value: 24 MHz} +- {id: GPT4_CLK_ROOT.outFreq, value: 24 MHz} +- {id: GPT4_ipg_clk_highfreq.outFreq, value: 24 MHz} +- {id: GPT5_CLK_ROOT.outFreq, value: 24 MHz} +- {id: GPT5_ipg_clk_highfreq.outFreq, value: 24 MHz} +- {id: GPT6_CLK_ROOT.outFreq, value: 24 MHz} +- {id: GPT6_ipg_clk_highfreq.outFreq, value: 24 MHz} +- {id: LCDIFV2_CLK_ROOT.outFreq, value: 24 MHz} +- {id: LPI2C1_CLK_ROOT.outFreq, value: 24 MHz} +- {id: LPI2C2_CLK_ROOT.outFreq, value: 24 MHz} +- {id: LPI2C3_CLK_ROOT.outFreq, value: 24 MHz} +- {id: LPI2C4_CLK_ROOT.outFreq, value: 24 MHz} +- {id: LPI2C5_CLK_ROOT.outFreq, value: 24 MHz} +- {id: LPI2C6_CLK_ROOT.outFreq, value: 24 MHz} +- {id: LPSPI1_CLK_ROOT.outFreq, value: 24 MHz} +- {id: LPSPI2_CLK_ROOT.outFreq, value: 24 MHz} +- {id: LPSPI3_CLK_ROOT.outFreq, value: 24 MHz} +- {id: LPSPI4_CLK_ROOT.outFreq, value: 24 MHz} +- {id: LPSPI5_CLK_ROOT.outFreq, value: 24 MHz} +- {id: LPSPI6_CLK_ROOT.outFreq, value: 24 MHz} +- {id: LPUART10_CLK_ROOT.outFreq, value: 24 MHz} +- {id: LPUART11_CLK_ROOT.outFreq, value: 24 MHz} +- {id: LPUART12_CLK_ROOT.outFreq, value: 24 MHz} +- {id: LPUART1_CLK_ROOT.outFreq, value: 24 MHz} +- {id: LPUART2_CLK_ROOT.outFreq, value: 24 MHz} +- {id: LPUART3_CLK_ROOT.outFreq, value: 24 MHz} +- {id: LPUART4_CLK_ROOT.outFreq, value: 24 MHz} +- {id: LPUART5_CLK_ROOT.outFreq, value: 24 MHz} +- {id: LPUART6_CLK_ROOT.outFreq, value: 24 MHz} +- {id: LPUART7_CLK_ROOT.outFreq, value: 24 MHz} +- {id: LPUART8_CLK_ROOT.outFreq, value: 24 MHz} +- {id: LPUART9_CLK_ROOT.outFreq, value: 24 MHz} +- {id: M4_CLK_ROOT.outFreq, value: 4320/11 MHz} +- {id: M4_SYSTICK_CLK_ROOT.outFreq, value: 24 MHz} +- {id: M7_CLK_ROOT.outFreq, value: 996 MHz} +- {id: M7_SYSTICK_CLK_ROOT.outFreq, value: 100 kHz} +- {id: MIC_CLK_ROOT.outFreq, value: 24 MHz} +- {id: MIPI_DSI_TX_CLK_ESC_ROOT.outFreq, value: 24 MHz} +- {id: MIPI_ESC_CLK_ROOT.outFreq, value: 24 MHz} +- {id: MIPI_REF_CLK_ROOT.outFreq, value: 24 MHz} +- {id: MQS_CLK_ROOT.outFreq, value: 24 MHz} +- {id: MQS_MCLK.outFreq, value: 24 MHz} +- {id: OSC_24M.outFreq, value: 24 MHz} +- {id: OSC_32K.outFreq, value: 32.768 kHz} +- {id: OSC_RC_16M.outFreq, value: 16 MHz} +- {id: OSC_RC_400M.outFreq, value: 400 MHz} +- {id: OSC_RC_48M.outFreq, value: 48 MHz} +- {id: OSC_RC_48M_DIV2.outFreq, value: 24 MHz} +- {id: PLL_VIDEO_CLK.outFreq, value: 984.000025 MHz} +- {id: SAI1_CLK_ROOT.outFreq, value: 24 MHz} +- {id: SAI1_MCLK1.outFreq, value: 24 MHz} +- {id: SAI1_MCLK3.outFreq, value: 24 MHz} +- {id: SAI2_CLK_ROOT.outFreq, value: 24 MHz} +- {id: SAI2_MCLK1.outFreq, value: 24 MHz} +- {id: SAI2_MCLK3.outFreq, value: 24 MHz} +- {id: SAI3_CLK_ROOT.outFreq, value: 24 MHz} +- {id: SAI3_MCLK1.outFreq, value: 24 MHz} +- {id: SAI3_MCLK3.outFreq, value: 24 MHz} +- {id: SAI4_CLK_ROOT.outFreq, value: 24 MHz} +- {id: SAI4_MCLK1.outFreq, value: 24 MHz} +- {id: SEMC_CLK_ROOT.outFreq, value: 198 MHz} +- {id: SPDIF_CLK_ROOT.outFreq, value: 24 MHz} +- {id: SYS_PLL2_CLK.outFreq, value: 528 MHz} +- {id: SYS_PLL2_PFD0_CLK.outFreq, value: 352 MHz} +- {id: SYS_PLL2_PFD1_CLK.outFreq, value: 594 MHz} +- {id: SYS_PLL2_PFD2_CLK.outFreq, value: 396 MHz} +- {id: SYS_PLL2_PFD3_CLK.outFreq, value: 297 MHz} +- {id: SYS_PLL3_CLK.outFreq, value: 480 MHz} +- {id: SYS_PLL3_DIV2_CLK.outFreq, value: 240 MHz} +- {id: SYS_PLL3_PFD0_CLK.outFreq, value: 8640/13 MHz} +- {id: SYS_PLL3_PFD1_CLK.outFreq, value: 8640/17 MHz} +- {id: SYS_PLL3_PFD2_CLK.outFreq, value: 270 MHz} +- {id: SYS_PLL3_PFD3_CLK.outFreq, value: 4320/11 MHz} +- {id: USDHC1_CLK_ROOT.outFreq, value: 24 MHz} +- {id: USDHC2_CLK_ROOT.outFreq, value: 24 MHz} +settings: +- {id: CoreBusClockRootsInitializationConfig, value: selectedCore} +- {id: SOCDomainVoltage, value: OD} +- {id: ANADIG_OSC_OSC_24M_CTRL_LP_EN_CFG, value: Low} +- {id: ANADIG_OSC_OSC_24M_CTRL_OSC_EN_CFG, value: Enabled} +- {id: ANADIG_PLL.PLL_AUDIO_BYPASS.sel, value: ANADIG_OSC.OSC_24M} +- {id: ANADIG_PLL.PLL_VIDEO.denom, value: '960000'} +- {id: ANADIG_PLL.PLL_VIDEO.div, value: '41'} +- {id: ANADIG_PLL.PLL_VIDEO.num, value: '1'} +- {id: ANADIG_PLL.SYS_PLL1_BYPASS.sel, value: ANADIG_OSC.OSC_24M} +- {id: ANADIG_PLL.SYS_PLL2.denom, value: '268435455'} +- {id: ANADIG_PLL.SYS_PLL2.div, value: '22'} +- {id: ANADIG_PLL.SYS_PLL2.num, value: '0'} +- {id: ANADIG_PLL.SYS_PLL2_SS_DIV.scale, value: '268435455'} +- {id: ANADIG_PLL.SYS_PLL3_PFD3_DIV.scale, value: '22', locked: true} +- {id: ANADIG_PLL.SYS_PLL3_PFD3_MUL.scale, value: '18', locked: true} +- {id: ANADIG_PLL_ARM_PLL_CTRL_POWERUP_CFG, value: Enabled} +- {id: ANADIG_PLL_PLL_AUDIO_CTRL_GATE_CFG, value: Disabled} +- {id: ANADIG_PLL_PLL_VIDEO_CTRL0_POWERUP_CFG, value: Enabled} +- {id: ANADIG_PLL_SYS_PLL1_CTRL0_POWERUP_CFG, value: Disabled} +- {id: ANADIG_PLL_SYS_PLL1_CTRL_GATE_CFG, value: Disabled} +- {id: ANADIG_PLL_SYS_PLL2_CTRL_POWERUP_CFG, value: Enabled} +- {id: ANADIG_PLL_SYS_PLL3_CTRL_POWERUP_CFG, value: Enabled} +- {id: ANADIG_PLL_SYS_PLL3_CTRL_SYS_PLL3_DIV2_CFG, value: Enabled} +- {id: CCM.CLOCK_ROOT0.MUX.sel, value: ANADIG_PLL.ARM_PLL_CLK} +- {id: CCM.CLOCK_ROOT1.MUX.sel, value: ANADIG_PLL.SYS_PLL3_PFD3_CLK} +- {id: CCM.CLOCK_ROOT2.DIV.scale, value: '2'} +- {id: CCM.CLOCK_ROOT2.MUX.sel, value: ANADIG_PLL.SYS_PLL3_CLK} +- {id: CCM.CLOCK_ROOT25.DIV.scale, value: '22'} +- {id: CCM.CLOCK_ROOT25.MUX.sel, value: ANADIG_PLL.SYS_PLL2_CLK} +- {id: CCM.CLOCK_ROOT26.DIV.scale, value: '22'} +- {id: CCM.CLOCK_ROOT26.MUX.sel, value: ANADIG_PLL.SYS_PLL2_CLK} +- {id: CCM.CLOCK_ROOT3.DIV.scale, value: '3'} +- {id: CCM.CLOCK_ROOT3.MUX.sel, value: ANADIG_PLL.SYS_PLL3_CLK} +- {id: CCM.CLOCK_ROOT4.DIV.scale, value: '3'} +- {id: CCM.CLOCK_ROOT4.MUX.sel, value: ANADIG_PLL.SYS_PLL2_PFD1_CLK} +- {id: CCM.CLOCK_ROOT6.DIV.scale, value: '4'} +- {id: CCM.CLOCK_ROOT6.MUX.sel, value: ANADIG_PLL.SYS_PLL2_CLK} +- {id: CCM.CLOCK_ROOT68.DIV.scale, value: '2'} +- {id: CCM.CLOCK_ROOT68.MUX.sel, value: ANADIG_PLL.PLL_VIDEO_CLK} +- {id: CCM.CLOCK_ROOT8.DIV.scale, value: '240'} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ + +/******************************************************************************* + * Variables for BOARD_BootClockRUN configuration + ******************************************************************************/ + +#ifndef SKIP_POWER_ADJUSTMENT +#if __CORTEX_M == 7 +#define BYPASS_LDO_LPSR 1 +#define SKIP_LDO_ADJUSTMENT 1 +#elif __CORTEX_M == 4 +#define SKIP_DCDC_ADJUSTMENT 1 +#define SKIP_FBB_ENABLE 1 +#endif +#endif + +const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN = + { + .postDivider = kCLOCK_PllPostDiv2, /* Post divider, 0 - DIV by 2, 1 - DIV by 4, 2 - DIV by 8, 3 - DIV by 1 */ + .loopDivider = 166, /* PLL Loop divider, Fout = Fin * ( loopDivider / ( 2 * postDivider ) ) */ + }; + +const clock_sys_pll2_config_t sysPll2Config_BOARD_BootClockRUN = + { + .mfd = 268435455, /* Denominator of spread spectrum */ + .ss = NULL, /* Spread spectrum parameter */ + .ssEnable = false, /* Enable spread spectrum or not */ + }; + +const clock_video_pll_config_t videoPllConfig_BOARD_BootClockRUN = + { + .loopDivider = 41, /* PLL Loop divider, valid range for DIV_SELECT divider value: 27 ~ 54. */ + .postDivider = 0, /* Divider after PLL, should only be 1, 2, 4, 8, 16, 32 */ + .numerator = 1, /* 30 bit numerator of fractional loop divider, Fout = Fin * ( loopDivider + numerator / denominator ) */ + .denominator = 960000, /* 30 bit denominator of fractional loop divider, Fout = Fin * ( loopDivider + numerator / denominator ) */ + .ss = NULL, /* Spread spectrum parameter */ + .ssEnable = false, /* Enable spread spectrum or not */ + }; + +/******************************************************************************* + * Code for BOARD_BootClockRUN configuration + ******************************************************************************/ +void BOARD_BootClockRUN(void) +{ + clock_root_config_t rootCfg = {0}; + +#if !defined(SKIP_DCDC_CONFIGURATION) || (!SKIP_DCDC_CONFIGURATION) + /* Set DCDC to DCM mode to improve the efficiency for light loading in run mode and transient performance with a big loading step. */ + DCDC_BootIntoDCM(DCDC); + +#if !defined(SKIP_DCDC_ADJUSTMENT) || (!SKIP_DCDC_ADJUSTMENT) + if((OCOTP->FUSEN[16].FUSE == 0x57AC5969U) && ((OCOTP->FUSEN[17].FUSE & 0xFFU) == 0x0BU)) + { + DCDC_SetVDD1P0BuckModeTargetVoltage(DCDC, kDCDC_1P0BuckTarget1P15V); + } + else + { + /* Set 1.125V for production samples to align with data sheet requirement */ + DCDC_SetVDD1P0BuckModeTargetVoltage(DCDC, kDCDC_1P0BuckTarget1P125V); + } +#endif /* SKIP_DCDC_ADJUSTMENT */ +#endif /* SKIP_DCDC_CONFIGURATION */ + +#if !defined(SKIP_FBB_ENABLE) || (!SKIP_FBB_ENABLE) + /* Check if FBB need to be enabled in OverDrive(OD) mode */ + if(((OCOTP->FUSEN[7].FUSE & 0x10U) >> 4U) != 1) + { + PMU_EnableBodyBias(ANADIG_PMU, kPMU_FBB_CM7, true); + } + else + { + PMU_EnableBodyBias(ANADIG_PMU, kPMU_FBB_CM7, false); + } +#endif + +#if defined(BYPASS_LDO_LPSR) && BYPASS_LDO_LPSR + PMU_StaticEnableLpsrAnaLdoBypassMode(ANADIG_LDO_SNVS, true); + PMU_StaticEnableLpsrDigLdoBypassMode(ANADIG_LDO_SNVS, true); +#endif + +#if !defined(SKIP_LDO_ADJUSTMENT) || (!SKIP_LDO_ADJUSTMENT) + pmu_static_lpsr_ana_ldo_config_t lpsrAnaConfig; + pmu_static_lpsr_dig_config_t lpsrDigConfig; + + if((ANADIG_LDO_SNVS->PMU_LDO_LPSR_ANA & ANADIG_LDO_SNVS_PMU_LDO_LPSR_ANA_BYPASS_MODE_EN_MASK) == 0UL) + { + PMU_StaticGetLpsrAnaLdoDefaultConfig(&lpsrAnaConfig); + PMU_StaticLpsrAnaLdoInit(ANADIG_LDO_SNVS, &lpsrAnaConfig); + } + + if((ANADIG_LDO_SNVS->PMU_LDO_LPSR_DIG & ANADIG_LDO_SNVS_PMU_LDO_LPSR_DIG_BYPASS_MODE_MASK) == 0UL) + { + PMU_StaticGetLpsrDigLdoDefaultConfig(&lpsrDigConfig); + lpsrDigConfig.targetVoltage = kPMU_LpsrDigTargetStableVoltage1P117V; + PMU_StaticLpsrDigLdoInit(ANADIG_LDO_SNVS, &lpsrDigConfig); + } +#endif + + /* Config CLK_1M */ + CLOCK_OSC_Set1MHzOutputBehavior(kCLOCK_1MHzOutEnableFreeRunning1Mhz); + + /* Init OSC RC 16M */ + ANADIG_OSC->OSC_16M_CTRL |= ANADIG_OSC_OSC_16M_CTRL_EN_IRC4M16M_MASK; + + /* Init OSC RC 400M */ + CLOCK_OSC_EnableOscRc400M(); + CLOCK_OSC_GateOscRc400M(false); + + /* Init OSC RC 48M */ + CLOCK_OSC_EnableOsc48M(true); + CLOCK_OSC_EnableOsc48MDiv2(true); + + /* Config OSC 24M */ + ANADIG_OSC->OSC_24M_CTRL |= ANADIG_OSC_OSC_24M_CTRL_OSC_EN(1) | ANADIG_OSC_OSC_24M_CTRL_BYPASS_EN(0) | ANADIG_OSC_OSC_24M_CTRL_BYPASS_CLK(0) | ANADIG_OSC_OSC_24M_CTRL_LP_EN(1) | ANADIG_OSC_OSC_24M_CTRL_OSC_24M_GATE(0); + /* Wait for 24M OSC to be stable. */ + while (ANADIG_OSC_OSC_24M_CTRL_OSC_24M_STABLE_MASK != + (ANADIG_OSC->OSC_24M_CTRL & ANADIG_OSC_OSC_24M_CTRL_OSC_24M_STABLE_MASK)) + { + } + + /* Switch both core, M7 Systick and Bus_Lpsr to OscRC48MDiv2 first */ +#if __CORTEX_M == 7 + rootCfg.mux = kCLOCK_M7_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_M7, &rootCfg); + + rootCfg.mux = kCLOCK_M7_SYSTICK_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_M7_Systick, &rootCfg); +#endif + +#if __CORTEX_M == 4 + rootCfg.mux = kCLOCK_M4_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_M4, &rootCfg); + + rootCfg.mux = kCLOCK_BUS_LPSR_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Bus_Lpsr, &rootCfg); +#endif + + /* + * if DCD is used, please make sure the clock source of SEMC is not changed in the following PLL/PFD configuration code. + */ + /* Init Arm Pll. */ + CLOCK_InitArmPll(&armPllConfig_BOARD_BootClockRUN); + + /* Bypass Sys Pll1. */ + CLOCK_SetPllBypass(kCLOCK_PllSys1, true); + + /* DeInit Sys Pll1. */ + CLOCK_DeinitSysPll1(); + + /* Init Sys Pll2. */ + CLOCK_InitSysPll2(&sysPll2Config_BOARD_BootClockRUN); + + /* Init System Pll2 pfd0. */ + CLOCK_InitPfd(kCLOCK_PllSys2, kCLOCK_Pfd0, 27); + + /* Init System Pll2 pfd1. */ + CLOCK_InitPfd(kCLOCK_PllSys2, kCLOCK_Pfd1, 16); + + /* Init System Pll2 pfd2. */ + CLOCK_InitPfd(kCLOCK_PllSys2, kCLOCK_Pfd2, 24); + + /* Init System Pll2 pfd3. */ + CLOCK_InitPfd(kCLOCK_PllSys2, kCLOCK_Pfd3, 32); + + /* Init Sys Pll3. */ + CLOCK_InitSysPll3(); + + /* Init System Pll3 pfd0. */ + CLOCK_InitPfd(kCLOCK_PllSys3, kCLOCK_Pfd0, 13); + + /* Init System Pll3 pfd1. */ + CLOCK_InitPfd(kCLOCK_PllSys3, kCLOCK_Pfd1, 17); + + /* Init System Pll3 pfd2. */ + CLOCK_InitPfd(kCLOCK_PllSys3, kCLOCK_Pfd2, 32); + + /* Init System Pll3 pfd3. */ + CLOCK_InitPfd(kCLOCK_PllSys3, kCLOCK_Pfd3, 22); + + /* Bypass Audio Pll. */ + CLOCK_SetPllBypass(kCLOCK_PllAudio, true); + + /* DeInit Audio Pll. */ + CLOCK_DeinitAudioPll(); + + /* Init Video Pll. */ + CLOCK_InitVideoPll(&videoPllConfig_BOARD_BootClockRUN); + + /* Module clock root configurations. */ + /* Configure M7 using ARM_PLL_CLK */ +#if __CORTEX_M == 7 + rootCfg.mux = kCLOCK_M7_ClockRoot_MuxArmPllOut; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_M7, &rootCfg); +#endif + + /* Configure M4 using SYS_PLL3_PFD3_CLK */ +#if __CORTEX_M == 4 + rootCfg.mux = kCLOCK_M4_ClockRoot_MuxSysPll3Pfd3; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_M4, &rootCfg); +#endif + + /* Configure BUS using SYS_PLL3_CLK */ + rootCfg.mux = kCLOCK_BUS_ClockRoot_MuxSysPll3Out; + rootCfg.div = 2; + CLOCK_SetRootClock(kCLOCK_Root_Bus, &rootCfg); + + /* Configure BUS_LPSR using SYS_PLL3_CLK */ + rootCfg.mux = kCLOCK_BUS_LPSR_ClockRoot_MuxSysPll3Out; + rootCfg.div = 3; + CLOCK_SetRootClock(kCLOCK_Root_Bus_Lpsr, &rootCfg); + + /* Configure SEMC using SYS_PLL2_PFD1_CLK */ +#ifndef SKIP_SEMC_INIT + rootCfg.mux = kCLOCK_SEMC_ClockRoot_MuxSysPll2Pfd1; + rootCfg.div = 3; + CLOCK_SetRootClock(kCLOCK_Root_Semc, &rootCfg); +#endif + +#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1) + UpdateSemcClock(); +#endif +#endif + + /* Configure CSSYS using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_CSSYS_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Cssys, &rootCfg); + + /* Configure CSTRACE using SYS_PLL2_CLK */ + rootCfg.mux = kCLOCK_CSTRACE_ClockRoot_MuxSysPll2Out; + rootCfg.div = 4; + CLOCK_SetRootClock(kCLOCK_Root_Cstrace, &rootCfg); + + /* Configure M4_SYSTICK using OSC_RC_48M_DIV2 */ +#if __CORTEX_M == 4 + rootCfg.mux = kCLOCK_M4_SYSTICK_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_M4_Systick, &rootCfg); +#endif + + /* Configure M7_SYSTICK using OSC_RC_48M_DIV2 */ +#if __CORTEX_M == 7 + rootCfg.mux = kCLOCK_M7_SYSTICK_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 240; + CLOCK_SetRootClock(kCLOCK_Root_M7_Systick, &rootCfg); +#endif + + /* Configure ADC1 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_ADC1_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Adc1, &rootCfg); + + /* Configure ADC2 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_ADC2_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Adc2, &rootCfg); + + /* Configure ACMP using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_ACMP_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Acmp, &rootCfg); + + /* Configure FLEXIO1 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_FLEXIO1_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Flexio1, &rootCfg); + + /* Configure FLEXIO2 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_FLEXIO2_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Flexio2, &rootCfg); + + /* Configure GPT1 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_GPT1_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Gpt1, &rootCfg); + + /* Configure GPT2 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_GPT2_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Gpt2, &rootCfg); + + /* Configure GPT3 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_GPT3_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Gpt3, &rootCfg); + + /* Configure GPT4 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_GPT4_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Gpt4, &rootCfg); + + /* Configure GPT5 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_GPT5_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Gpt5, &rootCfg); + + /* Configure GPT6 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_GPT6_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Gpt6, &rootCfg); + + /* Configure FLEXSPI1 using OSC_RC_48M_DIV2 */ +#if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1) || defined(FLEXSPI_IN_USE)) + rootCfg.mux = kCLOCK_FLEXSPI1_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Flexspi1, &rootCfg); +#endif + + /* Configure FLEXSPI2 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_FLEXSPI2_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Flexspi2, &rootCfg); + + /* Configure CAN1 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_CAN1_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Can1, &rootCfg); + + /* Configure CAN2 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_CAN2_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Can2, &rootCfg); + + /* Configure CAN3 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_CAN3_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Can3, &rootCfg); + + /* Configure LPUART1 using SYS_PLL2_CLK */ + rootCfg.mux = kCLOCK_LPUART1_ClockRoot_MuxSysPll2Out; + rootCfg.div = 22; + CLOCK_SetRootClock(kCLOCK_Root_Lpuart1, &rootCfg); + + /* Configure LPUART2 using SYS_PLL2_CLK */ + rootCfg.mux = kCLOCK_LPUART2_ClockRoot_MuxSysPll2Out; + rootCfg.div = 22; + CLOCK_SetRootClock(kCLOCK_Root_Lpuart2, &rootCfg); + + /* Configure LPUART3 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_LPUART3_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Lpuart3, &rootCfg); + + /* Configure LPUART4 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_LPUART4_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Lpuart4, &rootCfg); + + /* Configure LPUART5 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_LPUART5_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Lpuart5, &rootCfg); + + /* Configure LPUART6 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_LPUART6_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Lpuart6, &rootCfg); + + /* Configure LPUART7 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_LPUART7_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Lpuart7, &rootCfg); + + /* Configure LPUART8 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_LPUART8_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Lpuart8, &rootCfg); + + /* Configure LPUART9 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_LPUART9_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Lpuart9, &rootCfg); + + /* Configure LPUART10 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_LPUART10_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Lpuart10, &rootCfg); + + /* Configure LPUART11 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_LPUART11_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Lpuart11, &rootCfg); + + /* Configure LPUART12 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_LPUART12_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Lpuart12, &rootCfg); + + /* Configure LPI2C1 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_LPI2C1_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Lpi2c1, &rootCfg); + + /* Configure LPI2C2 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_LPI2C2_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Lpi2c2, &rootCfg); + + /* Configure LPI2C3 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_LPI2C3_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Lpi2c3, &rootCfg); + + /* Configure LPI2C4 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_LPI2C4_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Lpi2c4, &rootCfg); + + /* Configure LPI2C5 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_LPI2C5_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Lpi2c5, &rootCfg); + + /* Configure LPI2C6 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_LPI2C6_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Lpi2c6, &rootCfg); + + /* Configure LPSPI1 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_LPSPI1_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Lpspi1, &rootCfg); + + /* Configure LPSPI2 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_LPSPI2_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Lpspi2, &rootCfg); + + /* Configure LPSPI3 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_LPSPI3_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Lpspi3, &rootCfg); + + /* Configure LPSPI4 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_LPSPI4_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Lpspi4, &rootCfg); + + /* Configure LPSPI5 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_LPSPI5_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Lpspi5, &rootCfg); + + /* Configure LPSPI6 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_LPSPI6_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Lpspi6, &rootCfg); + + /* Configure EMV1 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_EMV1_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Emv1, &rootCfg); + + /* Configure EMV2 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_EMV2_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Emv2, &rootCfg); + + /* Configure ENET1 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_ENET1_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Enet1, &rootCfg); + + /* Configure ENET2 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_ENET2_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Enet2, &rootCfg); + + /* Configure ENET_QOS using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_ENET_QOS_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Enet_Qos, &rootCfg); + + /* Configure ENET_25M using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_ENET_25M_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Enet_25m, &rootCfg); + + /* Configure ENET_TIMER1 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_ENET_TIMER1_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Enet_Timer1, &rootCfg); + + /* Configure ENET_TIMER2 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_ENET_TIMER2_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Enet_Timer2, &rootCfg); + + /* Configure ENET_TIMER3 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_ENET_TIMER3_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Enet_Timer3, &rootCfg); + + /* Configure USDHC1 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_USDHC1_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Usdhc1, &rootCfg); + + /* Configure USDHC2 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_USDHC2_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Usdhc2, &rootCfg); + + /* Configure ASRC using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_ASRC_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Asrc, &rootCfg); + + /* Configure MQS using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_MQS_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Mqs, &rootCfg); + + /* Configure MIC using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_MIC_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Mic, &rootCfg); + + /* Configure SPDIF using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_SPDIF_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Spdif, &rootCfg); + + /* Configure SAI1 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_SAI1_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Sai1, &rootCfg); + + /* Configure SAI2 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_SAI2_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Sai2, &rootCfg); + + /* Configure SAI3 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_SAI3_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Sai3, &rootCfg); + + /* Configure SAI4 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_SAI4_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Sai4, &rootCfg); + + /* Configure GC355 using PLL_VIDEO_CLK */ + rootCfg.mux = kCLOCK_GC355_ClockRoot_MuxVideoPllOut; + rootCfg.div = 2; + CLOCK_SetRootClock(kCLOCK_Root_Gc355, &rootCfg); + + /* Configure LCDIF using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_LCDIF_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Lcdif, &rootCfg); + + /* Configure LCDIFV2 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_LCDIFV2_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Lcdifv2, &rootCfg); + + /* Configure MIPI_REF using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_MIPI_REF_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Mipi_Ref, &rootCfg); + + /* Configure MIPI_ESC using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_MIPI_ESC_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Mipi_Esc, &rootCfg); + + /* Configure CSI2 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_CSI2_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Csi2, &rootCfg); + + /* Configure CSI2_ESC using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_CSI2_ESC_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Csi2_Esc, &rootCfg); + + /* Configure CSI2_UI using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_CSI2_UI_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Csi2_Ui, &rootCfg); + + /* Configure CSI using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_CSI_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Csi, &rootCfg); + + /* Configure CKO1 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_CKO1_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Cko1, &rootCfg); + + /* Configure CKO2 using OSC_RC_48M_DIV2 */ + rootCfg.mux = kCLOCK_CKO2_ClockRoot_MuxOscRc48MDiv2; + rootCfg.div = 1; + CLOCK_SetRootClock(kCLOCK_Root_Cko2, &rootCfg); + + /* Set SAI1 MCLK1 clock source. */ + IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk1Sel, 0); + /* Set SAI1 MCLK2 clock source. */ + IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk2Sel, 3); + /* Set SAI1 MCLK3 clock source. */ + IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk3Sel, 0); + /* Set SAI2 MCLK3 clock source. */ + IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI2MClk3Sel, 0); + /* Set SAI3 MCLK3 clock source. */ + IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI3MClk3Sel, 0); + + /* Set MQS configuration. */ + IOMUXC_MQSConfig(IOMUXC_GPR,kIOMUXC_MqsPwmOverSampleRate32, 0); + /* Set ENET Ref clock source. */ + IOMUXC_GPR->GPR4 &= ~IOMUXC_GPR_GPR4_ENET_REF_CLK_DIR_MASK; + /* Set ENET_1G Tx clock source. */ + IOMUXC_GPR->GPR5 = ((IOMUXC_GPR->GPR5 & ~IOMUXC_GPR_GPR5_ENET1G_TX_CLK_SEL_MASK) | IOMUXC_GPR_GPR5_ENET1G_RGMII_EN_MASK); + /* Set ENET_1G Ref clock source. */ + IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_ENET1G_REF_CLK_DIR_MASK; + /* Set ENET_QOS Tx clock source. */ + IOMUXC_GPR->GPR6 &= ~IOMUXC_GPR_GPR6_ENET_QOS_RGMII_EN_MASK; + /* Set ENET_QOS Ref clock source. */ + IOMUXC_GPR->GPR6 &= ~IOMUXC_GPR_GPR6_ENET_QOS_REF_CLK_DIR_MASK; + /* Set GPT1 High frequency reference clock source. */ + IOMUXC_GPR->GPR22 &= ~IOMUXC_GPR_GPR22_REF_1M_CLK_GPT1_MASK; + /* Set GPT2 High frequency reference clock source. */ + IOMUXC_GPR->GPR23 &= ~IOMUXC_GPR_GPR23_REF_1M_CLK_GPT2_MASK; + /* Set GPT3 High frequency reference clock source. */ + IOMUXC_GPR->GPR24 &= ~IOMUXC_GPR_GPR24_REF_1M_CLK_GPT3_MASK; + /* Set GPT4 High frequency reference clock source. */ + IOMUXC_GPR->GPR25 &= ~IOMUXC_GPR_GPR25_REF_1M_CLK_GPT4_MASK; + /* Set GPT5 High frequency reference clock source. */ + IOMUXC_GPR->GPR26 &= ~IOMUXC_GPR_GPR26_REF_1M_CLK_GPT5_MASK; + /* Set GPT6 High frequency reference clock source. */ + IOMUXC_GPR->GPR27 &= ~IOMUXC_GPR_GPR27_REF_1M_CLK_GPT6_MASK; + +#if __CORTEX_M == 7 + SystemCoreClock = CLOCK_GetRootClockFreq(kCLOCK_Root_M7); +#else + SystemCoreClock = CLOCK_GetRootClockFreq(kCLOCK_Root_M4); +#endif +} diff --git a/hw/bsp/imxrt/boards/mimxrt1170_evkb/board/clock_config.h b/hw/bsp/imxrt/boards/mimxrt1170_evkb/board/clock_config.h new file mode 100644 index 000000000..4a4d35eaa --- /dev/null +++ b/hw/bsp/imxrt/boards/mimxrt1170_evkb/board/clock_config.h @@ -0,0 +1,202 @@ +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +#define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */ + +#define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32k frequency in Hz */ + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockRUN configuration + ******************************************************************************/ +#if __CORTEX_M == 7 + #define BOARD_BOOTCLOCKRUN_CORE_CLOCK 996000000UL /*!< CM7 Core clock frequency: 996000000Hz */ +#else + #define BOARD_BOOTCLOCKRUN_CORE_CLOCK 392727272UL /*!< CM4 Core clock frequency: 392727272Hz */ +#endif + +/* Clock outputs (values are in Hz): */ +#define BOARD_BOOTCLOCKRUN_ACMP_CLK_ROOT 24000000UL /* Clock consumers of ACMP_CLK_ROOT output : CMP1, CMP2, CMP3, CMP4 */ +#define BOARD_BOOTCLOCKRUN_ADC1_CLK_ROOT 24000000UL /* Clock consumers of ADC1_CLK_ROOT output : LPADC1 */ +#define BOARD_BOOTCLOCKRUN_ADC2_CLK_ROOT 24000000UL /* Clock consumers of ADC2_CLK_ROOT output : LPADC2 */ +#define BOARD_BOOTCLOCKRUN_ARM_PLL_CLK 996000000UL /* Clock consumers of ARM_PLL_CLK output : N/A */ +#define BOARD_BOOTCLOCKRUN_ASRC_CLK_ROOT 24000000UL /* Clock consumers of ASRC_CLK_ROOT output : ASRC */ +#define BOARD_BOOTCLOCKRUN_AXI_CLK_ROOT 996000000UL /* Clock consumers of AXI_CLK_ROOT output : FLEXRAM */ +#define BOARD_BOOTCLOCKRUN_BUS_CLK_ROOT 240000000UL /* Clock consumers of BUS_CLK_ROOT output : ADC_ETC, AOI1, AOI2, CAAM, CAN1, CAN2, CM7_GPIO2, CM7_GPIO3, CMP1, CMP2, CMP3, CMP4, CSI, DAC, DMA0, DMAMUX0, DSI_HOST, EMVSIM1, EMVSIM2, ENC1, ENC2, ENC3, ENC4, ENET, ENET_1G, ENET_QOS, EWM, FLEXIO1, FLEXIO2, FLEXSPI1, FLEXSPI2, GPIO1, GPIO2, GPIO3, GPIO4, GPIO5, GPIO6, IEE_APC, IOMUXC, IOMUXC_GPR, KPP, LCDIF, LCDIFV2, LPADC1, LPADC2, LPI2C1, LPI2C2, LPI2C3, LPI2C4, LPSPI1, LPSPI2, LPSPI3, LPSPI4, LPUART1, LPUART10, LPUART2, LPUART3, LPUART4, LPUART5, LPUART6, LPUART7, LPUART8, LPUART9, MECC1, MECC2, MIPI_CSI2RX, PIT1, PWM1, PWM2, PWM3, PWM4, PXP, RTWDOG3, SAI1, SAI2, SAI3, SPDIF, TMR1, TMR2, TMR3, TMR4, USBPHY1, USBPHY2, USB_OTG1, USB_OTG2, USDHC1, USDHC2, WDOG1, WDOG2, XBARA1, XBARB2, XBARB3, XECC_FLEXSPI1, XECC_FLEXSPI2, XECC_SEMC, XRDC2_D0, XRDC2_D1 */ +#define BOARD_BOOTCLOCKRUN_BUS_LPSR_CLK_ROOT 160000000UL /* Clock consumers of BUS_LPSR_CLK_ROOT output : CAN3, GPIO10, GPIO11, GPIO12, GPIO7, GPIO8, GPIO9, IOMUXC_LPSR, LPI2C5, LPI2C6, LPSPI5, LPSPI6, LPUART11, LPUART12, MUA, MUB, PDM, PIT2, RDC, RTWDOG4, SAI4, SNVS, XRDC2_D0, XRDC2_D1 */ +#define BOARD_BOOTCLOCKRUN_CAN1_CLK_ROOT 24000000UL /* Clock consumers of CAN1_CLK_ROOT output : CAN1 */ +#define BOARD_BOOTCLOCKRUN_CAN2_CLK_ROOT 24000000UL /* Clock consumers of CAN2_CLK_ROOT output : CAN2 */ +#define BOARD_BOOTCLOCKRUN_CAN3_CLK_ROOT 24000000UL /* Clock consumers of CAN3_CLK_ROOT output : CAN3 */ +#define BOARD_BOOTCLOCKRUN_CCM_CLKO1_CLK_ROOT 24000000UL /* Clock consumers of CCM_CLKO1_CLK_ROOT output : N/A */ +#define BOARD_BOOTCLOCKRUN_CCM_CLKO2_CLK_ROOT 24000000UL /* Clock consumers of CCM_CLKO2_CLK_ROOT output : N/A */ +#define BOARD_BOOTCLOCKRUN_CLK_1M 1000000UL /* Clock consumers of CLK_1M output : EWM, RTWDOG3, RTWDOG4 */ +#define BOARD_BOOTCLOCKRUN_CSI2_CLK_ROOT 24000000UL /* Clock consumers of CSI2_CLK_ROOT output : MIPI_CSI2RX */ +#define BOARD_BOOTCLOCKRUN_CSI2_ESC_CLK_ROOT 24000000UL /* Clock consumers of CSI2_ESC_CLK_ROOT output : MIPI_CSI2RX */ +#define BOARD_BOOTCLOCKRUN_CSI2_UI_CLK_ROOT 24000000UL /* Clock consumers of CSI2_UI_CLK_ROOT output : MIPI_CSI2RX */ +#define BOARD_BOOTCLOCKRUN_CSI_CLK_ROOT 24000000UL /* Clock consumers of CSI_CLK_ROOT output : N/A */ +#define BOARD_BOOTCLOCKRUN_CSSYS_CLK_ROOT 24000000UL /* Clock consumers of CSSYS_CLK_ROOT output : ARM */ +#define BOARD_BOOTCLOCKRUN_CSTRACE_CLK_ROOT 132000000UL /* Clock consumers of CSTRACE_CLK_ROOT output : ARM */ +#define BOARD_BOOTCLOCKRUN_ELCDIF_CLK_ROOT 24000000UL /* Clock consumers of ELCDIF_CLK_ROOT output : LCDIF */ +#define BOARD_BOOTCLOCKRUN_EMV1_CLK_ROOT 24000000UL /* Clock consumers of EMV1_CLK_ROOT output : EMVSIM1 */ +#define BOARD_BOOTCLOCKRUN_EMV2_CLK_ROOT 24000000UL /* Clock consumers of EMV2_CLK_ROOT output : EMVSIM2 */ +#define BOARD_BOOTCLOCKRUN_ENET1_CLK_ROOT 24000000UL /* Clock consumers of ENET1_CLK_ROOT output : N/A */ +#define BOARD_BOOTCLOCKRUN_ENET2_CLK_ROOT 24000000UL /* Clock consumers of ENET2_CLK_ROOT output : N/A */ +#define BOARD_BOOTCLOCKRUN_ENET_1G_REF_CLK 0UL /* Clock consumers of ENET_1G_REF_CLK output : ENET_1G */ +#define BOARD_BOOTCLOCKRUN_ENET_1G_TX_CLK 24000000UL /* Clock consumers of ENET_1G_TX_CLK output : ENET_1G */ +#define BOARD_BOOTCLOCKRUN_ENET_25M_CLK_ROOT 24000000UL /* Clock consumers of ENET_25M_CLK_ROOT output : N/A */ +#define BOARD_BOOTCLOCKRUN_ENET_QOS_CLK_ROOT 24000000UL /* Clock consumers of ENET_QOS_CLK_ROOT output : N/A */ +#define BOARD_BOOTCLOCKRUN_ENET_QOS_REF_CLK 0UL /* Clock consumers of ENET_QOS_REF_CLK output : ENET_QOS */ +#define BOARD_BOOTCLOCKRUN_ENET_QOS_TX_CLK 0UL /* Clock consumers of ENET_QOS_TX_CLK output : ENET_QOS */ +#define BOARD_BOOTCLOCKRUN_ENET_REF_CLK 0UL /* Clock consumers of ENET_REF_CLK output : ENET */ +#define BOARD_BOOTCLOCKRUN_ENET_TIMER1_CLK_ROOT 24000000UL /* Clock consumers of ENET_TIMER1_CLK_ROOT output : ENET */ +#define BOARD_BOOTCLOCKRUN_ENET_TIMER2_CLK_ROOT 24000000UL /* Clock consumers of ENET_TIMER2_CLK_ROOT output : ENET_1G */ +#define BOARD_BOOTCLOCKRUN_ENET_TIMER3_CLK_ROOT 24000000UL /* Clock consumers of ENET_TIMER3_CLK_ROOT output : ENET_QOS */ +#define BOARD_BOOTCLOCKRUN_ENET_TX_CLK 0UL /* Clock consumers of ENET_TX_CLK output : ENET */ +#define BOARD_BOOTCLOCKRUN_FLEXIO1_CLK_ROOT 24000000UL /* Clock consumers of FLEXIO1_CLK_ROOT output : FLEXIO1 */ +#define BOARD_BOOTCLOCKRUN_FLEXIO2_CLK_ROOT 24000000UL /* Clock consumers of FLEXIO2_CLK_ROOT output : FLEXIO2 */ +#define BOARD_BOOTCLOCKRUN_FLEXSPI1_CLK_ROOT 24000000UL /* Clock consumers of FLEXSPI1_CLK_ROOT output : FLEXSPI1 */ +#define BOARD_BOOTCLOCKRUN_FLEXSPI2_CLK_ROOT 24000000UL /* Clock consumers of FLEXSPI2_CLK_ROOT output : FLEXSPI2 */ +#define BOARD_BOOTCLOCKRUN_GC355_CLK_ROOT 492000012UL /* Clock consumers of GC355_CLK_ROOT output : N/A */ +#define BOARD_BOOTCLOCKRUN_GPT1_CLK_ROOT 24000000UL /* Clock consumers of GPT1_CLK_ROOT output : GPT1 */ +#define BOARD_BOOTCLOCKRUN_GPT1_IPG_CLK_HIGHFREQ 24000000UL /* Clock consumers of GPT1_ipg_clk_highfreq output : N/A */ +#define BOARD_BOOTCLOCKRUN_GPT2_CLK_ROOT 24000000UL /* Clock consumers of GPT2_CLK_ROOT output : GPT2 */ +#define BOARD_BOOTCLOCKRUN_GPT2_IPG_CLK_HIGHFREQ 24000000UL /* Clock consumers of GPT2_ipg_clk_highfreq output : N/A */ +#define BOARD_BOOTCLOCKRUN_GPT3_CLK_ROOT 24000000UL /* Clock consumers of GPT3_CLK_ROOT output : GPT3 */ +#define BOARD_BOOTCLOCKRUN_GPT3_IPG_CLK_HIGHFREQ 24000000UL /* Clock consumers of GPT3_ipg_clk_highfreq output : N/A */ +#define BOARD_BOOTCLOCKRUN_GPT4_CLK_ROOT 24000000UL /* Clock consumers of GPT4_CLK_ROOT output : GPT4 */ +#define BOARD_BOOTCLOCKRUN_GPT4_IPG_CLK_HIGHFREQ 24000000UL /* Clock consumers of GPT4_ipg_clk_highfreq output : N/A */ +#define BOARD_BOOTCLOCKRUN_GPT5_CLK_ROOT 24000000UL /* Clock consumers of GPT5_CLK_ROOT output : GPT5 */ +#define BOARD_BOOTCLOCKRUN_GPT5_IPG_CLK_HIGHFREQ 24000000UL /* Clock consumers of GPT5_ipg_clk_highfreq output : N/A */ +#define BOARD_BOOTCLOCKRUN_GPT6_CLK_ROOT 24000000UL /* Clock consumers of GPT6_CLK_ROOT output : GPT6 */ +#define BOARD_BOOTCLOCKRUN_GPT6_IPG_CLK_HIGHFREQ 24000000UL /* Clock consumers of GPT6_ipg_clk_highfreq output : N/A */ +#define BOARD_BOOTCLOCKRUN_LCDIFV2_CLK_ROOT 24000000UL /* Clock consumers of LCDIFV2_CLK_ROOT output : LCDIFV2 */ +#define BOARD_BOOTCLOCKRUN_LPI2C1_CLK_ROOT 24000000UL /* Clock consumers of LPI2C1_CLK_ROOT output : LPI2C1 */ +#define BOARD_BOOTCLOCKRUN_LPI2C2_CLK_ROOT 24000000UL /* Clock consumers of LPI2C2_CLK_ROOT output : LPI2C2 */ +#define BOARD_BOOTCLOCKRUN_LPI2C3_CLK_ROOT 24000000UL /* Clock consumers of LPI2C3_CLK_ROOT output : LPI2C3 */ +#define BOARD_BOOTCLOCKRUN_LPI2C4_CLK_ROOT 24000000UL /* Clock consumers of LPI2C4_CLK_ROOT output : LPI2C4 */ +#define BOARD_BOOTCLOCKRUN_LPI2C5_CLK_ROOT 24000000UL /* Clock consumers of LPI2C5_CLK_ROOT output : LPI2C5 */ +#define BOARD_BOOTCLOCKRUN_LPI2C6_CLK_ROOT 24000000UL /* Clock consumers of LPI2C6_CLK_ROOT output : LPI2C6 */ +#define BOARD_BOOTCLOCKRUN_LPSPI1_CLK_ROOT 24000000UL /* Clock consumers of LPSPI1_CLK_ROOT output : LPSPI1 */ +#define BOARD_BOOTCLOCKRUN_LPSPI2_CLK_ROOT 24000000UL /* Clock consumers of LPSPI2_CLK_ROOT output : LPSPI2 */ +#define BOARD_BOOTCLOCKRUN_LPSPI3_CLK_ROOT 24000000UL /* Clock consumers of LPSPI3_CLK_ROOT output : LPSPI3 */ +#define BOARD_BOOTCLOCKRUN_LPSPI4_CLK_ROOT 24000000UL /* Clock consumers of LPSPI4_CLK_ROOT output : LPSPI4 */ +#define BOARD_BOOTCLOCKRUN_LPSPI5_CLK_ROOT 24000000UL /* Clock consumers of LPSPI5_CLK_ROOT output : LPSPI5 */ +#define BOARD_BOOTCLOCKRUN_LPSPI6_CLK_ROOT 24000000UL /* Clock consumers of LPSPI6_CLK_ROOT output : LPSPI6 */ +#define BOARD_BOOTCLOCKRUN_LPUART10_CLK_ROOT 24000000UL /* Clock consumers of LPUART10_CLK_ROOT output : LPUART10 */ +#define BOARD_BOOTCLOCKRUN_LPUART11_CLK_ROOT 24000000UL /* Clock consumers of LPUART11_CLK_ROOT output : LPUART11 */ +#define BOARD_BOOTCLOCKRUN_LPUART12_CLK_ROOT 24000000UL /* Clock consumers of LPUART12_CLK_ROOT output : LPUART12 */ +#define BOARD_BOOTCLOCKRUN_LPUART1_CLK_ROOT 24000000UL /* Clock consumers of LPUART1_CLK_ROOT output : LPUART1 */ +#define BOARD_BOOTCLOCKRUN_LPUART2_CLK_ROOT 24000000UL /* Clock consumers of LPUART2_CLK_ROOT output : LPUART2 */ +#define BOARD_BOOTCLOCKRUN_LPUART3_CLK_ROOT 24000000UL /* Clock consumers of LPUART3_CLK_ROOT output : LPUART3 */ +#define BOARD_BOOTCLOCKRUN_LPUART4_CLK_ROOT 24000000UL /* Clock consumers of LPUART4_CLK_ROOT output : LPUART4 */ +#define BOARD_BOOTCLOCKRUN_LPUART5_CLK_ROOT 24000000UL /* Clock consumers of LPUART5_CLK_ROOT output : LPUART5 */ +#define BOARD_BOOTCLOCKRUN_LPUART6_CLK_ROOT 24000000UL /* Clock consumers of LPUART6_CLK_ROOT output : LPUART6 */ +#define BOARD_BOOTCLOCKRUN_LPUART7_CLK_ROOT 24000000UL /* Clock consumers of LPUART7_CLK_ROOT output : LPUART7 */ +#define BOARD_BOOTCLOCKRUN_LPUART8_CLK_ROOT 24000000UL /* Clock consumers of LPUART8_CLK_ROOT output : LPUART8 */ +#define BOARD_BOOTCLOCKRUN_LPUART9_CLK_ROOT 24000000UL /* Clock consumers of LPUART9_CLK_ROOT output : LPUART9 */ +#define BOARD_BOOTCLOCKRUN_M4_CLK_ROOT 392727272UL /* Clock consumers of M4_CLK_ROOT output : ARM, DMA1, DMAMUX1, SSARC_HP, SSARC_LP, XRDC2_D0, XRDC2_D1 */ +#define BOARD_BOOTCLOCKRUN_M4_SYSTICK_CLK_ROOT 24000000UL /* Clock consumers of M4_SYSTICK_CLK_ROOT output : N/A */ +#define BOARD_BOOTCLOCKRUN_M7_CLK_ROOT 996000000UL /* Clock consumers of M7_CLK_ROOT output : ARM */ +#define BOARD_BOOTCLOCKRUN_M7_SYSTICK_CLK_ROOT 100000UL /* Clock consumers of M7_SYSTICK_CLK_ROOT output : N/A */ +#define BOARD_BOOTCLOCKRUN_MIC_CLK_ROOT 24000000UL /* Clock consumers of MIC_CLK_ROOT output : ASRC, PDM, SPDIF */ +#define BOARD_BOOTCLOCKRUN_MIPI_DSI_TX_CLK_ESC_ROOT 24000000UL /* Clock consumers of MIPI_DSI_TX_CLK_ESC_ROOT output : N/A */ +#define BOARD_BOOTCLOCKRUN_MIPI_ESC_CLK_ROOT 24000000UL /* Clock consumers of MIPI_ESC_CLK_ROOT output : DSI_HOST */ +#define BOARD_BOOTCLOCKRUN_MIPI_REF_CLK_ROOT 24000000UL /* Clock consumers of MIPI_REF_CLK_ROOT output : DSI_HOST */ +#define BOARD_BOOTCLOCKRUN_MQS_CLK_ROOT 24000000UL /* Clock consumers of MQS_CLK_ROOT output : ASRC */ +#define BOARD_BOOTCLOCKRUN_MQS_MCLK 24000000UL /* Clock consumers of MQS_MCLK output : N/A */ +#define BOARD_BOOTCLOCKRUN_OSC_24M 24000000UL /* Clock consumers of OSC_24M output : SPDIF, TMPSNS, USBPHY1, USBPHY2 */ +#define BOARD_BOOTCLOCKRUN_OSC_32K 32768UL /* Clock consumers of OSC_32K output : GPIO13, RTWDOG3, RTWDOG4 */ +#define BOARD_BOOTCLOCKRUN_OSC_RC_16M 16000000UL /* Clock consumers of OSC_RC_16M output : CCM, DCDC, EWM, GPT1, GPT2, GPT3, GPT4, GPT5, GPT6, SSARC_LP */ +#define BOARD_BOOTCLOCKRUN_OSC_RC_400M 400000000UL /* Clock consumers of OSC_RC_400M output : N/A */ +#define BOARD_BOOTCLOCKRUN_OSC_RC_48M 48000000UL /* Clock consumers of OSC_RC_48M output : N/A */ +#define BOARD_BOOTCLOCKRUN_OSC_RC_48M_DIV2 24000000UL /* Clock consumers of OSC_RC_48M_DIV2 output : N/A */ +#define BOARD_BOOTCLOCKRUN_PLL_AUDIO_CLK 0UL /* Clock consumers of PLL_AUDIO_CLK output : N/A */ +#define BOARD_BOOTCLOCKRUN_PLL_AUDIO_SS_MODULATION 0UL /* Clock consumers of PLL_AUDIO_SS_MODULATION output : N/A */ +#define BOARD_BOOTCLOCKRUN_PLL_AUDIO_SS_RANGE 0UL /* Clock consumers of PLL_AUDIO_SS_RANGE output : N/A */ +#define BOARD_BOOTCLOCKRUN_PLL_VIDEO_CLK 984000025UL /* Clock consumers of PLL_VIDEO_CLK output : N/A */ +#define BOARD_BOOTCLOCKRUN_PLL_VIDEO_SS_MODULATION 0UL /* Clock consumers of PLL_VIDEO_SS_MODULATION output : N/A */ +#define BOARD_BOOTCLOCKRUN_PLL_VIDEO_SS_RANGE 0UL /* Clock consumers of PLL_VIDEO_SS_RANGE output : N/A */ +#define BOARD_BOOTCLOCKRUN_SAI1_CLK_ROOT 24000000UL /* Clock consumers of SAI1_CLK_ROOT output : SPDIF */ +#define BOARD_BOOTCLOCKRUN_SAI1_MCLK1 24000000UL /* Clock consumers of SAI1_MCLK1 output : SAI1 */ +#define BOARD_BOOTCLOCKRUN_SAI1_MCLK2 0UL /* Clock consumers of SAI1_MCLK2 output : SAI1 */ +#define BOARD_BOOTCLOCKRUN_SAI1_MCLK3 24000000UL /* Clock consumers of SAI1_MCLK3 output : SAI1 */ +#define BOARD_BOOTCLOCKRUN_SAI2_CLK_ROOT 24000000UL /* Clock consumers of SAI2_CLK_ROOT output : ASRC */ +#define BOARD_BOOTCLOCKRUN_SAI2_MCLK1 24000000UL /* Clock consumers of SAI2_MCLK1 output : SAI2 */ +#define BOARD_BOOTCLOCKRUN_SAI2_MCLK2 0UL /* Clock consumers of SAI2_MCLK2 output : SAI2 */ +#define BOARD_BOOTCLOCKRUN_SAI2_MCLK3 24000000UL /* Clock consumers of SAI2_MCLK3 output : SAI2 */ +#define BOARD_BOOTCLOCKRUN_SAI3_CLK_ROOT 24000000UL /* Clock consumers of SAI3_CLK_ROOT output : ASRC, SPDIF */ +#define BOARD_BOOTCLOCKRUN_SAI3_MCLK1 24000000UL /* Clock consumers of SAI3_MCLK1 output : SAI3 */ +#define BOARD_BOOTCLOCKRUN_SAI3_MCLK2 0UL /* Clock consumers of SAI3_MCLK2 output : SAI3 */ +#define BOARD_BOOTCLOCKRUN_SAI3_MCLK3 24000000UL /* Clock consumers of SAI3_MCLK3 output : SAI3 */ +#define BOARD_BOOTCLOCKRUN_SAI4_CLK_ROOT 24000000UL /* Clock consumers of SAI4_CLK_ROOT output : ASRC, SPDIF */ +#define BOARD_BOOTCLOCKRUN_SAI4_MCLK1 24000000UL /* Clock consumers of SAI4_MCLK1 output : SAI4 */ +#define BOARD_BOOTCLOCKRUN_SAI4_MCLK2 0UL /* Clock consumers of SAI4_MCLK2 output : SAI4 */ +#define BOARD_BOOTCLOCKRUN_SEMC_CLK_ROOT 198000000UL /* Clock consumers of SEMC_CLK_ROOT output : SEMC, XECC_FLEXSPI1, XECC_FLEXSPI2, XECC_SEMC, XRDC2_D0, XRDC2_D1 */ +#define BOARD_BOOTCLOCKRUN_SPDIF_CLK_ROOT 24000000UL /* Clock consumers of SPDIF_CLK_ROOT output : SPDIF */ +#define BOARD_BOOTCLOCKRUN_SPDIF_EXTCLK_OUT 0UL /* Clock consumers of SPDIF_EXTCLK_OUT output : N/A */ +#define BOARD_BOOTCLOCKRUN_SYS_PLL1_CLK 0UL /* Clock consumers of SYS_PLL1_CLK output : N/A */ +#define BOARD_BOOTCLOCKRUN_SYS_PLL1_DIV2_CLK 0UL /* Clock consumers of SYS_PLL1_DIV2_CLK output : N/A */ +#define BOARD_BOOTCLOCKRUN_SYS_PLL1_DIV5_CLK 0UL /* Clock consumers of SYS_PLL1_DIV5_CLK output : N/A */ +#define BOARD_BOOTCLOCKRUN_SYS_PLL1_SS_MODULATION 0UL /* Clock consumers of SYS_PLL1_SS_MODULATION output : N/A */ +#define BOARD_BOOTCLOCKRUN_SYS_PLL1_SS_RANGE 0UL /* Clock consumers of SYS_PLL1_SS_RANGE output : N/A */ +#define BOARD_BOOTCLOCKRUN_SYS_PLL2_CLK 528000000UL /* Clock consumers of SYS_PLL2_CLK output : N/A */ +#define BOARD_BOOTCLOCKRUN_SYS_PLL2_PFD0_CLK 352000000UL /* Clock consumers of SYS_PLL2_PFD0_CLK output : N/A */ +#define BOARD_BOOTCLOCKRUN_SYS_PLL2_PFD1_CLK 594000000UL /* Clock consumers of SYS_PLL2_PFD1_CLK output : N/A */ +#define BOARD_BOOTCLOCKRUN_SYS_PLL2_PFD2_CLK 396000000UL /* Clock consumers of SYS_PLL2_PFD2_CLK output : N/A */ +#define BOARD_BOOTCLOCKRUN_SYS_PLL2_PFD3_CLK 297000000UL /* Clock consumers of SYS_PLL2_PFD3_CLK output : N/A */ +#define BOARD_BOOTCLOCKRUN_SYS_PLL2_SS_MODULATION 0UL /* Clock consumers of SYS_PLL2_SS_MODULATION output : N/A */ +#define BOARD_BOOTCLOCKRUN_SYS_PLL2_SS_RANGE 0UL /* Clock consumers of SYS_PLL2_SS_RANGE output : N/A */ +#define BOARD_BOOTCLOCKRUN_SYS_PLL3_CLK 480000000UL /* Clock consumers of SYS_PLL3_CLK output : N/A */ +#define BOARD_BOOTCLOCKRUN_SYS_PLL3_DIV2_CLK 240000000UL /* Clock consumers of SYS_PLL3_DIV2_CLK output : N/A */ +#define BOARD_BOOTCLOCKRUN_SYS_PLL3_PFD0_CLK 664615384UL /* Clock consumers of SYS_PLL3_PFD0_CLK output : N/A */ +#define BOARD_BOOTCLOCKRUN_SYS_PLL3_PFD1_CLK 508235294UL /* Clock consumers of SYS_PLL3_PFD1_CLK output : N/A */ +#define BOARD_BOOTCLOCKRUN_SYS_PLL3_PFD2_CLK 270000000UL /* Clock consumers of SYS_PLL3_PFD2_CLK output : N/A */ +#define BOARD_BOOTCLOCKRUN_SYS_PLL3_PFD3_CLK 392727272UL /* Clock consumers of SYS_PLL3_PFD3_CLK output : N/A */ +#define BOARD_BOOTCLOCKRUN_USDHC1_CLK_ROOT 24000000UL /* Clock consumers of USDHC1_CLK_ROOT output : USDHC1 */ +#define BOARD_BOOTCLOCKRUN_USDHC2_CLK_ROOT 24000000UL /* Clock consumers of USDHC2_CLK_ROOT output : USDHC2 */ + + +/******************************************************************************* + * API for BOARD_BootClockRUN configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ diff --git a/hw/bsp/imxrt/boards/mimxrt1170_evkb/board/pin_mux.c b/hw/bsp/imxrt/boards/mimxrt1170_evkb/board/pin_mux.c new file mode 100644 index 000000000..81ffb35e3 --- /dev/null +++ b/hw/bsp/imxrt/boards/mimxrt1170_evkb/board/pin_mux.c @@ -0,0 +1,129 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Pins v14.0 +processor: MIMXRT1176xxxxx +package_id: MIMXRT1176DVMAA +mcu_data: ksdk2_0 +processor_version: 14.0.1 +board: MIMXRT1170-EVKB +external_user_signals: {} +pin_labels: +- {pin_num: M13, pin_signal: GPIO_AD_04, label: 'SIM1_PD/J44[C8]/USER_LED_CTL1/J9[8]/J25[7]', identifier: SIM1_PD;LED;USER_LED} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +#include "fsl_common.h" +#include "fsl_iomuxc.h" +#include "fsl_gpio.h" +#include "pin_mux.h" + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitBootPins + * Description : Calls initialization functions. + * + * END ****************************************************************************************************************/ +void BOARD_InitBootPins(void) { + BOARD_InitPins(); +} + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitPins: +- options: {callFromInitBoot: 'true', coreID: cm7, enableClock: 'true'} +- pin_list: + - {pin_num: M15, peripheral: LPUART1, signal: RXD, pin_signal: GPIO_AD_25, software_input_on: Disable, pull_up_down_config: Pull_Down, pull_keeper_select: Keeper, + open_drain: Disable, drive_strength: High, slew_rate: Slow} + - {pin_num: L13, peripheral: LPUART1, signal: TXD, pin_signal: GPIO_AD_24, software_input_on: Disable, pull_up_down_config: Pull_Down, pull_keeper_select: Keeper, + open_drain: Disable, drive_strength: High, slew_rate: Slow} + - {pin_num: M13, peripheral: GPIO9, signal: 'gpio_io, 03', pin_signal: GPIO_AD_04, identifier: USER_LED, direction: OUTPUT, pull_up_down_config: Pull_Down, pull_keeper_select: Keeper} + - {pin_num: T8, peripheral: GPIO13, signal: 'gpio_io, 00', pin_signal: WAKEUP, direction: INPUT, pull_up_down_config: Pull_Up} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitPins, assigned for the Cortex-M7F core. + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); /* LPCG on: LPCG is ON. */ + + /* GPIO configuration of USER_LED on GPIO_AD_04 (pin M13) */ + gpio_pin_config_t USER_LED_config = { + .direction = kGPIO_DigitalOutput, + .outputLogic = 0U, + .interruptMode = kGPIO_NoIntmode + }; + /* Initialize GPIO functionality on GPIO_AD_04 (pin M13) */ + GPIO_PinInit(GPIO9, 3U, &USER_LED_config); + + /* GPIO configuration of USER_BUTTON on WAKEUP_DIG (pin T8) */ + gpio_pin_config_t USER_BUTTON_config = { + .direction = kGPIO_DigitalInput, + .outputLogic = 0U, + .interruptMode = kGPIO_NoIntmode + }; + /* Initialize GPIO functionality on WAKEUP_DIG (pin T8) */ + GPIO_PinInit(GPIO13, 0U, &USER_BUTTON_config); + + IOMUXC_SetPinMux( + IOMUXC_GPIO_AD_04_GPIO9_IO03, /* GPIO_AD_04 is configured as GPIO9_IO03 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_AD_24_LPUART1_TXD, /* GPIO_AD_24 is configured as LPUART1_TXD */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_GPIO_AD_25_LPUART1_RXD, /* GPIO_AD_25 is configured as LPUART1_RXD */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinMux( + IOMUXC_WAKEUP_DIG_GPIO13_IO00, /* WAKEUP_DIG is configured as GPIO13_IO00 */ + 0U); /* Software Input On Field: Input Path is determined by functionality */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_AD_04_GPIO9_IO03, /* GPIO_AD_04 PAD functional properties : */ + 0x02U); /* Slew Rate Field: Slow Slew Rate + Drive Strength Field: high drive strength + Pull / Keep Select Field: Pull Disable, Highz + Pull Up / Down Config. Field: Weak pull down + Open Drain Field: Disabled + Domain write protection: Both cores are allowed + Domain write protection lock: Neither of DWP bits is locked */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_AD_24_LPUART1_TXD, /* GPIO_AD_24 PAD functional properties : */ + 0x02U); /* Slew Rate Field: Slow Slew Rate + Drive Strength Field: high drive strength + Pull / Keep Select Field: Pull Disable, Highz + Pull Up / Down Config. Field: Weak pull down + Open Drain Field: Disabled + Domain write protection: Both cores are allowed + Domain write protection lock: Neither of DWP bits is locked */ + IOMUXC_SetPinConfig( + IOMUXC_GPIO_AD_25_LPUART1_RXD, /* GPIO_AD_25 PAD functional properties : */ + 0x02U); /* Slew Rate Field: Slow Slew Rate + Drive Strength Field: high drive strength + Pull / Keep Select Field: Pull Disable, Highz + Pull Up / Down Config. Field: Weak pull down + Open Drain Field: Disabled + Domain write protection: Both cores are allowed + Domain write protection lock: Neither of DWP bits is locked */ + IOMUXC_SetPinConfig( + IOMUXC_WAKEUP_DIG_GPIO13_IO00, /* WAKEUP_DIG PAD functional properties : */ + 0x0EU); /* Slew Rate Field: Slow Slew Rate + Drive Strength Field: high driver + Pull / Keep Select Field: Pull Enable + Pull Up / Down Config. Field: Weak pull up + Open Drain SNVS Field: Disabled + Domain write protection: Both cores are allowed + Domain write protection lock: Neither of DWP bits is locked */ +} + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/imxrt/boards/mimxrt1170_evkb/board/pin_mux.h b/hw/bsp/imxrt/boards/mimxrt1170_evkb/board/pin_mux.h new file mode 100644 index 000000000..550bd1474 --- /dev/null +++ b/hw/bsp/imxrt/boards/mimxrt1170_evkb/board/pin_mux.h @@ -0,0 +1,77 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _PIN_MUX_H_ +#define _PIN_MUX_H_ + +/*! + * @addtogroup pin_mux + * @{ + */ + +/*********************************************************************************************************************** + * API + **********************************************************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Calls initialization functions. + * + */ +void BOARD_InitBootPins(void); + +/* GPIO_AD_25 (coord M15), LPUART1_RXD */ +/* Routed pin properties */ +#define BOARD_INITPINS_LPUART1_RXD_PERIPHERAL LPUART1 /*!< Peripheral name */ +#define BOARD_INITPINS_LPUART1_RXD_SIGNAL RXD /*!< Signal name */ + +/* GPIO_AD_24 (coord L13), LPUART1_TXD */ +/* Routed pin properties */ +#define BOARD_INITPINS_LPUART1_TXD_PERIPHERAL LPUART1 /*!< Peripheral name */ +#define BOARD_INITPINS_LPUART1_TXD_SIGNAL TXD /*!< Signal name */ + +/* GPIO_AD_04 (coord M13), SIM1_PD/J44[C8]/USER_LED_CTL1/J9[8]/J25[7] */ +/* Routed pin properties */ +#define BOARD_INITPINS_USER_LED_PERIPHERAL GPIO9 /*!< Peripheral name */ +#define BOARD_INITPINS_USER_LED_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITPINS_USER_LED_CHANNEL 3U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_USER_LED_GPIO GPIO9 /*!< GPIO peripheral base pointer */ +#define BOARD_INITPINS_USER_LED_GPIO_PIN 3U /*!< GPIO pin number */ +#define BOARD_INITPINS_USER_LED_GPIO_PIN_MASK (1U << 3U) /*!< GPIO pin mask */ + +/* WAKEUP (coord T8), USER_BUTTON */ +/* Routed pin properties */ +#define BOARD_INITPINS_USER_BUTTON_PERIPHERAL GPIO13 /*!< Peripheral name */ +#define BOARD_INITPINS_USER_BUTTON_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITPINS_USER_BUTTON_CHANNEL 0U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_USER_BUTTON_GPIO GPIO13 /*!< GPIO peripheral base pointer */ +#define BOARD_INITPINS_USER_BUTTON_GPIO_PIN 0U /*!< GPIO pin number */ +#define BOARD_INITPINS_USER_BUTTON_GPIO_PIN_MASK (1U << 0U) /*!< GPIO pin mask */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitPins(void); /* Function assigned for the Cortex-M7F */ + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif /* _PIN_MUX_H_ */ + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/imxrt/boards/mimxrt1170_evkb/evkbmimxrt1170_flexspi_nor_config.c b/hw/bsp/imxrt/boards/mimxrt1170_evkb/evkbmimxrt1170_flexspi_nor_config.c new file mode 100644 index 000000000..0425cb2cb --- /dev/null +++ b/hw/bsp/imxrt/boards/mimxrt1170_evkb/evkbmimxrt1170_flexspi_nor_config.c @@ -0,0 +1,71 @@ +/* + * Copyright 2018-2022 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "evkbmimxrt1170_flexspi_nor_config.h" + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.xip_board" +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ +#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) +__attribute__((section(".boot_hdr.conf"), used)) +#elif defined(__ICCARM__) +#pragma location = ".boot_hdr.conf" +#endif + +const flexspi_nor_config_t qspiflash_config = { + .memConfig = + { + .tag = FLEXSPI_CFG_BLK_TAG, + .version = FLEXSPI_CFG_BLK_VERSION, + .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .csHoldTime = 3u, + .csSetupTime = 3u, + // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock + .controllerMiscOption = 0x10, + .deviceType = kFlexSpiDeviceType_SerialNOR, + .sflashPadType = kSerialFlash_4Pads, + .serialClkFreq = kFlexSpiSerialClk_133MHz, + .sflashA1Size = 64u * 1024u * 1024u, + .lookupTable = + { + // Read LUTs + [0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEC, RADDR_SDR, FLEXSPI_4PAD, 0x20), + [1] = FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), + + // Read Status LUTs + [4 * 1 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x04), + + // Write Enable LUTs + [4 * 3 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0x0), + + // Erase Sector LUTs + [4 * 5 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x21, RADDR_SDR, FLEXSPI_1PAD, 0x20), + + // Erase Block LUTs + [4 * 8 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8, RADDR_SDR, FLEXSPI_1PAD, 0x18), + + // Pape Program LUTs + [4 * 9 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x12, RADDR_SDR, FLEXSPI_1PAD, 0x20), + [4 * 9 + 1] = FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04, STOP, FLEXSPI_1PAD, 0x0), + + // Erase Chip LUTs + [4 * 11 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0x0), + }, + }, + .pageSize = 256u, + .sectorSize = 4u * 1024u, + .ipcmdSerialClkFreq = 0x1, + .blockSize = 64u * 1024u, + .isUniformBlockSize = false, +}; +#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/hw/bsp/imxrt/boards/mimxrt1170_evkb/evkbmimxrt1170_flexspi_nor_config.h b/hw/bsp/imxrt/boards/mimxrt1170_evkb/evkbmimxrt1170_flexspi_nor_config.h new file mode 100644 index 000000000..839bb78f5 --- /dev/null +++ b/hw/bsp/imxrt/boards/mimxrt1170_evkb/evkbmimxrt1170_flexspi_nor_config.h @@ -0,0 +1,270 @@ +/* + * Copyright 2018-2022 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __EVKMIMXRT1170_FLEXSPI_NOR_CONFIG__ +#define __EVKMIMXRT1170_FLEXSPI_NOR_CONFIG__ + +#include +#include +#include "fsl_common.h" + +/*! @name Driver version */ +/*@{*/ +/*! @brief XIP_BOARD driver version 2.0.1. */ +#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) +/*@}*/ + +/* FLEXSPI memory config block related definitions */ +#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian +#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 +#define FLEXSPI_CFG_BLK_SIZE (512) + +/* FLEXSPI Feature related definitions */ +#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 + +/* Lookup table related definitions */ +#define CMD_INDEX_READ 0 +#define CMD_INDEX_READSTATUS 1 +#define CMD_INDEX_WRITEENABLE 2 +#define CMD_INDEX_WRITE 4 + +#define CMD_LUT_SEQ_IDX_READ 0 +#define CMD_LUT_SEQ_IDX_READSTATUS 1 +#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define CMD_LUT_SEQ_IDX_WRITE 9 + +#define CMD_SDR 0x01 +#define CMD_DDR 0x21 +#define RADDR_SDR 0x02 +#define RADDR_DDR 0x22 +#define CADDR_SDR 0x03 +#define CADDR_DDR 0x23 +#define MODE1_SDR 0x04 +#define MODE1_DDR 0x24 +#define MODE2_SDR 0x05 +#define MODE2_DDR 0x25 +#define MODE4_SDR 0x06 +#define MODE4_DDR 0x26 +#define MODE8_SDR 0x07 +#define MODE8_DDR 0x27 +#define WRITE_SDR 0x08 +#define WRITE_DDR 0x28 +#define READ_SDR 0x09 +#define READ_DDR 0x29 +#define LEARN_SDR 0x0A +#define LEARN_DDR 0x2A +#define DATSZ_SDR 0x0B +#define DATSZ_DDR 0x2B +#define DUMMY_SDR 0x0C +#define DUMMY_DDR 0x2C +#define DUMMY_RWDS_SDR 0x0D +#define DUMMY_RWDS_DDR 0x2D +#define JMP_ON_CS 0x1F +#define STOP 0 + +#define FLEXSPI_1PAD 0 +#define FLEXSPI_2PAD 1 +#define FLEXSPI_4PAD 2 +#define FLEXSPI_8PAD 3 + +#define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \ + (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \ + FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1)) + +//!@brief Definitions for FlexSPI Serial Clock Frequency +typedef enum _FlexSpiSerialClockFreq +{ + kFlexSpiSerialClk_30MHz = 1, + kFlexSpiSerialClk_50MHz = 2, + kFlexSpiSerialClk_60MHz = 3, + kFlexSpiSerialClk_80MHz = 4, + kFlexSpiSerialClk_100MHz = 5, + kFlexSpiSerialClk_120MHz = 6, + kFlexSpiSerialClk_133MHz = 7, + kFlexSpiSerialClk_166MHz = 8, + kFlexSpiSerialClk_200MHz = 9, +} flexspi_serial_clk_freq_t; + +//!@brief FlexSPI clock configuration type +enum +{ + kFlexSpiClk_SDR, //!< Clock configure for SDR mode + kFlexSpiClk_DDR, //!< Clock configurat for DDR mode +}; + +//!@brief FlexSPI Read Sample Clock Source definition +typedef enum _FlashReadSampleClkSource +{ + kFlexSPIReadSampleClk_LoopbackInternally = 0, + kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, + kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, + kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, +} flexspi_read_sample_clk_t; + +//!@brief Misc feature bit definitions +enum +{ + kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable + kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable + kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable + kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable + kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable + kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable + kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication. +}; + +//!@brief Flash Type Definition +enum +{ + kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR + kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND + kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH + kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND + kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial RAMs +}; + +//!@brief Flash Pad Definitions +enum +{ + kSerialFlash_1Pad = 1, + kSerialFlash_2Pads = 2, + kSerialFlash_4Pads = 4, + kSerialFlash_8Pads = 8, +}; + +//!@brief FlexSPI LUT Sequence structure +typedef struct _lut_sequence +{ + uint8_t seqNum; //!< Sequence Number, valid number: 1-16 + uint8_t seqId; //!< Sequence Index, valid number: 0-15 + uint16_t reserved; +} flexspi_lut_seq_t; + +//!@brief Flash Configuration Command Type +enum +{ + kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc + kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command + kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode + kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode + kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode + kDeviceConfigCmdType_Reset, //!< Reset device command +}; + +//!@brief FlexSPI Memory Configuration Block +typedef struct _FlexSPIConfig +{ + uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL + uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix + uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use + uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 + uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3 + uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3 + uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For + //! Serial NAND, need to refer to datasheet + uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable + uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, + //! Generic configuration, etc. + uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for + //! DPI/QPI/OPI switch or reset command + flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt + //! sequence number, [31:16] Reserved + uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration + uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable + uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe + flexspi_lut_seq_t + configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq + uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use + uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands + uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use + uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more + //! details + uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details + uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal + uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequency, device specific definitions, See System Boot + //! Chapter for more details + uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot + //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH + uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use + uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1 + uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 + uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1 + uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 + uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value + uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value + uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value + uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value + uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command + uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands + uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns + uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31 + uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - + //! busy flag is 0 when flash device is busy + uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences + flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences + uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use +} flexspi_mem_config_t; + +/* */ +#define NOR_CMD_INDEX_READ CMD_INDEX_READ //!< 0 +#define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS //!< 1 +#define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE //!< 2 +#define NOR_CMD_INDEX_ERASESECTOR 3 //!< 3 +#define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE //!< 4 +#define NOR_CMD_INDEX_CHIPERASE 5 //!< 5 +#define NOR_CMD_INDEX_DUMMY 6 //!< 6 +#define NOR_CMD_INDEX_ERASEBLOCK 7 //!< 7 + +#define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ //!< 0 READ LUT sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS \ + CMD_LUT_SEQ_IDX_READSTATUS //!< 1 Read Status LUT sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \ + 2 //!< 2 Read status DPI/QPI/OPI sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE \ + CMD_LUT_SEQ_IDX_WRITEENABLE //!< 3 Write Enable sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \ + 4 //!< 4 Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 //!< 5 Erase Sector sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 //!< 8 Erase Block sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM \ + CMD_LUT_SEQ_IDX_WRITE //!< 9 Program sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 //!< 11 Chip Erase sequence in lookupTable id stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 //!< 13 Read SFDP sequence in lookupTable id stored in config block +#define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \ + 14 //!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \ + 15 //!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk + +/* + * Serial NOR configuration block + */ +typedef struct _flexspi_nor_config +{ + flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI + uint32_t pageSize; //!< Page size of Serial NOR + uint32_t sectorSize; //!< Sector size of Serial NOR + uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command + uint8_t isUniformBlockSize; //!< Sector/Block size is the same + uint8_t isDataOrderSwapped; //!< The data order is swapped in OPI DDR mode + uint8_t reserved0; //!< Reserved for future use + uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3 + uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command + uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false + uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP command execution + uint32_t blockSize; //!< Block size + uint32_t FlashStateCtx; //!< Flash State Context after being configured + uint32_t reserve2[10]; //!< Reserved for future use +} flexspi_nor_config_t; + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __EVKMIMXRT1170_FLEXSPI_NOR_CONFIG__ */ diff --git a/hw/bsp/imxrt/boards/mimxrt1170_evkb/mimxrt1170_evkb.mex b/hw/bsp/imxrt/boards/mimxrt1170_evkb/mimxrt1170_evkb.mex new file mode 100644 index 000000000..e68b9ea7e --- /dev/null +++ b/hw/bsp/imxrt/boards/mimxrt1170_evkb/mimxrt1170_evkb.mex @@ -0,0 +1,662 @@ + + + + MIMXRT1176xxxxx + MIMXRT1176DVMAA + MIMXRT1170-EVKB + ksdk2_0 + + + + + Configuration imported from evkbmimxrt1170_dev_cdc_vcom_lite_bm_cm7 + + + true + false + false + true + false + + + + + + + + + 14.0.1 + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. + + true + cm7 + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 14.0.1 + + + + + + + + + true + + + + + INPUT + + + + + true + + + + + OUTPUT + + + + + true + + + + + INPUT + + + + + true + + + + + OUTPUT + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + 13.0.2 + c_array + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + 2.5.1 + + + + + + 13.0.2 + + + + + + + + + 0 + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + N/A + + + + diff --git a/hw/bsp/imxrt/boards/teensy_40/board.h b/hw/bsp/imxrt/boards/teensy_40/board.h index cac773442..4a173c834 100644 --- a/hw/bsp/imxrt/boards/teensy_40/board.h +++ b/hw/bsp/imxrt/boards/teensy_40/board.h @@ -29,24 +29,21 @@ #define BOARD_H_ -// required since iMX RT10xx SDK include this file for board size +// required since iMXRT MCUX-SDK include this file for board size #define BOARD_FLASH_SIZE (2 * 1024 * 1024) -// LED -#define LED_PINMUX IOMUXC_GPIO_B0_03_GPIO2_IO03 // D13 -#define LED_PORT GPIO2 -#define LED_PIN 3 +// LED D13: IOMUXC_GPIO_B0_03_GPIO2_IO03 +#define LED_PORT BOARD_INITPINS_USER_LED_PERIPHERAL +#define LED_PIN BOARD_INITPINS_USER_LED_CHANNEL #define LED_STATE_ON 0 -// no button -#define BUTTON_PINMUX IOMUXC_GPIO_B0_01_GPIO2_IO01 // D12 -#define BUTTON_PORT GPIO2 -#define BUTTON_PIN 1 +// no button D12: IOMUXC_GPIO_B0_01_GPIO2_IO01 +#define BUTTON_PORT BOARD_INITPINS_USER_BUTTON_PERIPHERAL +#define BUTTON_PIN BOARD_INITPINS_USER_BUTTON_CHANNEL #define BUTTON_STATE_ACTIVE 0 -// UART +// UART D0, D1: IOMUXC_GPIO_AD_B0_03_LPUART6_RX, IOMUXC_GPIO_AD_B0_02_LPUART6_TX #define UART_PORT LPUART6 -#define UART_RX_PINMUX IOMUXC_GPIO_AD_B0_03_LPUART6_RX // D0 -#define UART_TX_PINMUX IOMUXC_GPIO_AD_B0_02_LPUART6_TX // D1 +#define UART_CLK_ROOT BOARD_BOOTCLOCKRUN_UART_CLK_ROOT #endif /* BOARD_H_ */ diff --git a/hw/bsp/imxrt/boards/teensy_40/board/pin_mux.c b/hw/bsp/imxrt/boards/teensy_40/board/pin_mux.c new file mode 100644 index 000000000..4c16be993 --- /dev/null +++ b/hw/bsp/imxrt/boards/teensy_40/board/pin_mux.c @@ -0,0 +1,181 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Pins v13.1 +processor: MIMXRT1062xxxxA +package_id: MIMXRT1062DVL6A +mcu_data: ksdk2_0 +processor_version: 13.0.2 +board: MIMXRT1060-EVK +pin_labels: +- {pin_num: E7, pin_signal: GPIO_B0_01, label: LCDIF_ENABLE, identifier: USER_BUTTON} +- {pin_num: D8, pin_signal: GPIO_B0_03, label: LCDIF_VSYNC, identifier: USER_LED} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +#include "fsl_common.h" +#include "fsl_iomuxc.h" +#include "fsl_gpio.h" +#include "pin_mux.h" + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitBootPins + * Description : Calls initialization functions. + * + * END ****************************************************************************************************************/ +void BOARD_InitBootPins(void) { + BOARD_InitPins(); + BOARD_InitDEBUG_UARTPins(); +} + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitPins: +- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: D8, peripheral: GPIO2, signal: 'gpio_io, 03', pin_signal: GPIO_B0_03, direction: OUTPUT} + - {pin_num: E7, peripheral: GPIO2, signal: 'gpio_io, 01', pin_signal: GPIO_B0_01, direction: INPUT, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + /* GPIO configuration of USER_BUTTON on GPIO_B0_01 (pin E7) */ + gpio_pin_config_t USER_BUTTON_config = { + .direction = kGPIO_DigitalInput, + .outputLogic = 0U, + .interruptMode = kGPIO_NoIntmode + }; + /* Initialize GPIO functionality on GPIO_B0_01 (pin E7) */ + GPIO_PinInit(GPIO2, 1U, &USER_BUTTON_config); + + /* GPIO configuration of USER_LED on GPIO_B0_03 (pin D8) */ + gpio_pin_config_t USER_LED_config = { + .direction = kGPIO_DigitalOutput, + .outputLogic = 0U, + .interruptMode = kGPIO_NoIntmode + }; + /* Initialize GPIO functionality on GPIO_B0_03 (pin D8) */ + GPIO_PinInit(GPIO2, 3U, &USER_LED_config); + + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_01_GPIO2_IO01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_03_GPIO2_IO03, 0U); + IOMUXC_GPR->GPR27 = ((IOMUXC_GPR->GPR27 & + (~(BOARD_INITPINS_IOMUXC_GPR_GPR27_GPIO_MUX2_GPIO_SEL_MASK))) + | IOMUXC_GPR_GPR27_GPIO_MUX2_GPIO_SEL(0x00U) + ); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_01_GPIO2_IO01, 0xB0B0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitDEBUG_UARTPins: +- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: K14, peripheral: LPUART1, signal: TX, pin_signal: GPIO_AD_B0_12, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Down_100K_Ohm, + pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} + - {pin_num: L14, peripheral: LPUART1, signal: RX, pin_signal: GPIO_AD_B0_13, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Down_100K_Ohm, + pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitDEBUG_UARTPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitDEBUG_UARTPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, 0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, 0x10B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, 0x10B0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitUSDHCPins: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: J2, peripheral: USDHC1, signal: 'usdhc_data, 3', pin_signal: GPIO_SD_B0_05} + - {pin_num: H2, peripheral: USDHC1, signal: 'usdhc_data, 2', pin_signal: GPIO_SD_B0_04} + - {pin_num: K1, peripheral: USDHC1, signal: 'usdhc_data, 1', pin_signal: GPIO_SD_B0_03} + - {pin_num: J1, peripheral: USDHC1, signal: 'usdhc_data, 0', pin_signal: GPIO_SD_B0_02} + - {pin_num: J4, peripheral: USDHC1, signal: usdhc_cmd, pin_signal: GPIO_SD_B0_00} + - {pin_num: J3, peripheral: USDHC1, signal: usdhc_clk, pin_signal: GPIO_SD_B0_01} + - {pin_num: C14, peripheral: USDHC1, signal: usdhc_vselect, pin_signal: GPIO_B1_14} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitUSDHCPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitUSDHCPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_14_USDHC1_VSELECT, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_00_USDHC1_CMD, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_01_USDHC1_CLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_02_USDHC1_DATA0, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_03_USDHC1_DATA1, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_04_USDHC1_DATA2, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_05_USDHC1_DATA3, 0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitQSPIPins: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: P3, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA0, pin_signal: GPIO_SD_B1_08} + - {pin_num: N4, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA1, pin_signal: GPIO_SD_B1_09} + - {pin_num: P4, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA2, pin_signal: GPIO_SD_B1_10} + - {pin_num: P5, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA3, pin_signal: GPIO_SD_B1_11} + - {pin_num: L4, peripheral: FLEXSPI, signal: FLEXSPI_A_SCLK, pin_signal: GPIO_SD_B1_07} + - {pin_num: L3, peripheral: FLEXSPI, signal: FLEXSPI_A_SS0_B, pin_signal: GPIO_SD_B1_06} + - {pin_num: N3, peripheral: FLEXSPI, signal: FLEXSPI_A_DQS, pin_signal: GPIO_SD_B1_05} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitQSPIPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitQSPIPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_05_FLEXSPIA_DQS, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_06_FLEXSPIA_SS0_B, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_07_FLEXSPIA_SCLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_08_FLEXSPIA_DATA00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_09_FLEXSPIA_DATA01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_10_FLEXSPIA_DATA02, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_11_FLEXSPIA_DATA03, 0U); +} + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/imxrt/boards/teensy_40/board/pin_mux.h b/hw/bsp/imxrt/boards/teensy_40/board/pin_mux.h new file mode 100644 index 000000000..f31f91598 --- /dev/null +++ b/hw/bsp/imxrt/boards/teensy_40/board/pin_mux.h @@ -0,0 +1,189 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _PIN_MUX_H_ +#define _PIN_MUX_H_ + +/*********************************************************************************************************************** + * Definitions + **********************************************************************************************************************/ + +/*! @brief Direction type */ +typedef enum _pin_mux_direction +{ + kPIN_MUX_DirectionInput = 0U, /* Input direction */ + kPIN_MUX_DirectionOutput = 1U, /* Output direction */ + kPIN_MUX_DirectionInputOrOutput = 2U /* Input or output direction */ +} pin_mux_direction_t; + +/*! + * @addtogroup pin_mux + * @{ + */ + +/*********************************************************************************************************************** + * API + **********************************************************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Calls initialization functions. + * + */ +void BOARD_InitBootPins(void); + +#define BOARD_INITPINS_IOMUXC_GPR_GPR27_GPIO_MUX2_GPIO_SEL_MASK 0x0AU /*!< GPIO2 and GPIO7 share same IO MUX function, GPIO_MUX2 selects one GPIO function: affected bits mask */ + +/* GPIO_B0_03 (coord D8), LCDIF_VSYNC */ +/* Routed pin properties */ +#define BOARD_INITPINS_USER_LED_PERIPHERAL GPIO2 /*!< Peripheral name */ +#define BOARD_INITPINS_USER_LED_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITPINS_USER_LED_CHANNEL 3U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_USER_LED_GPIO GPIO2 /*!< GPIO peripheral base pointer */ +#define BOARD_INITPINS_USER_LED_GPIO_PIN 3U /*!< GPIO pin number */ +#define BOARD_INITPINS_USER_LED_GPIO_PIN_MASK (1U << 3U) /*!< GPIO pin mask */ +#define BOARD_INITPINS_USER_LED_PORT GPIO2 /*!< PORT peripheral base pointer */ +#define BOARD_INITPINS_USER_LED_PIN 3U /*!< PORT pin number */ +#define BOARD_INITPINS_USER_LED_PIN_MASK (1U << 3U) /*!< PORT pin mask */ + +/* GPIO_B0_01 (coord E7), LCDIF_ENABLE */ +/* Routed pin properties */ +#define BOARD_INITPINS_USER_BUTTON_PERIPHERAL GPIO2 /*!< Peripheral name */ +#define BOARD_INITPINS_USER_BUTTON_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITPINS_USER_BUTTON_CHANNEL 1U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_USER_BUTTON_GPIO GPIO2 /*!< GPIO peripheral base pointer */ +#define BOARD_INITPINS_USER_BUTTON_GPIO_PIN 1U /*!< GPIO pin number */ +#define BOARD_INITPINS_USER_BUTTON_GPIO_PIN_MASK (1U << 1U) /*!< GPIO pin mask */ +#define BOARD_INITPINS_USER_BUTTON_PORT GPIO2 /*!< PORT peripheral base pointer */ +#define BOARD_INITPINS_USER_BUTTON_PIN 1U /*!< PORT pin number */ +#define BOARD_INITPINS_USER_BUTTON_PIN_MASK (1U << 1U) /*!< PORT pin mask */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitPins(void); + +/* GPIO_AD_B0_12 (coord K14), UART1_TXD */ +/* Routed pin properties */ +#define BOARD_INITDEBUG_UARTPINS_UART1_TXD_PERIPHERAL LPUART1 /*!< Peripheral name */ +#define BOARD_INITDEBUG_UARTPINS_UART1_TXD_SIGNAL TX /*!< Signal name */ + +/* GPIO_AD_B0_13 (coord L14), UART1_RXD */ +/* Routed pin properties */ +#define BOARD_INITDEBUG_UARTPINS_UART1_RXD_PERIPHERAL LPUART1 /*!< Peripheral name */ +#define BOARD_INITDEBUG_UARTPINS_UART1_RXD_SIGNAL RX /*!< Signal name */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitDEBUG_UARTPins(void); + +/* GPIO_SD_B0_05 (coord J2), SD1_D3 */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_D3_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_D3_SIGNAL usdhc_data /*!< Signal name */ +#define BOARD_INITUSDHCPINS_SD1_D3_CHANNEL 3U /*!< Signal channel */ + +/* GPIO_SD_B0_04 (coord H2), SD1_D2 */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_D2_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_D2_SIGNAL usdhc_data /*!< Signal name */ +#define BOARD_INITUSDHCPINS_SD1_D2_CHANNEL 2U /*!< Signal channel */ + +/* GPIO_SD_B0_03 (coord K1), SD1_D1/J24[5]/SPI_MISO */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_D1_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_D1_SIGNAL usdhc_data /*!< Signal name */ +#define BOARD_INITUSDHCPINS_SD1_D1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_SD_B0_02 (coord J1), SD1_D0/J24[4]/SPI_MOSI/PWM */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_D0_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_D0_SIGNAL usdhc_data /*!< Signal name */ +#define BOARD_INITUSDHCPINS_SD1_D0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_SD_B0_00 (coord J4), SD1_CMD/J24[6] */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_CMD_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_CMD_SIGNAL usdhc_cmd /*!< Signal name */ + +/* GPIO_SD_B0_01 (coord J3), SD1_CLK/J24[3] */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_CLK_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_CLK_SIGNAL usdhc_clk /*!< Signal name */ + +/* GPIO_B1_14 (coord C14), SD0_VSELECT */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD0_VSELECT_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD0_VSELECT_SIGNAL usdhc_vselect /*!< Signal name */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitUSDHCPins(void); + +/* GPIO_SD_B1_08 (coord P3), FlexSPI_D0_A */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_D0_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_D0_A_SIGNAL FLEXSPI_A_DATA0 /*!< Signal name */ + +/* GPIO_SD_B1_09 (coord N4), FlexSPI_D1_A */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_D1_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_D1_A_SIGNAL FLEXSPI_A_DATA1 /*!< Signal name */ + +/* GPIO_SD_B1_10 (coord P4), FlexSPI_D2_A */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_D2_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_D2_A_SIGNAL FLEXSPI_A_DATA2 /*!< Signal name */ + +/* GPIO_SD_B1_11 (coord P5), FlexSPI_D3_A */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_D3_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_D3_A_SIGNAL FLEXSPI_A_DATA3 /*!< Signal name */ + +/* GPIO_SD_B1_07 (coord L4), FlexSPI_CLK */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_CLK_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_CLK_SIGNAL FLEXSPI_A_SCLK /*!< Signal name */ + +/* GPIO_SD_B1_06 (coord L3), FlexSPI_SS0 */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_SS0_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_SS0_SIGNAL FLEXSPI_A_SS0_B /*!< Signal name */ + +/* GPIO_SD_B1_05 (coord N3), FlexSPI_DQS */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_DQS_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_DQS_SIGNAL FLEXSPI_A_DQS /*!< Signal name */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitQSPIPins(void); + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif /* _PIN_MUX_H_ */ + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/imxrt/boards/teensy_40/teensy40.mex b/hw/bsp/imxrt/boards/teensy_40/teensy40.mex index 39b3ed606..1ade853ae 100644 --- a/hw/bsp/imxrt/boards/teensy_40/teensy40.mex +++ b/hw/bsp/imxrt/boards/teensy_40/teensy40.mex @@ -26,6 +26,10 @@ 13.0.2 + + + + @@ -37,13 +41,41 @@ true + + + true + + true + + + true + + + + + true + + - + + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. @@ -98,385 +130,6 @@ - - Configures pin routing and optionally pin electrical features. - - false - core0 - true - - - - - true - - - - - true - - - - - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Configures pin routing and optionally pin electrical features. - - false - core0 - true - - - - - true - - - - - true - - - - - true - - - - - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Configures pin routing and optionally pin electrical features. - - false - core0 - true - - - - - true - - - - - true - - - - - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Configures pin routing and optionally pin electrical features. - - false - core0 - true - - - - - true - - - - - true - - - - - true - - - - - - - - - - Configures pin routing and optionally pin electrical features. - - false - core0 - true - - - - - true - - - - - true - - - - - true - - - - - - - - - - - - - - - - Configures pin routing and optionally pin electrical features. @@ -717,11 +370,8 @@ - - - - - + + 13.0.2 diff --git a/hw/bsp/imxrt/boards/teensy_41/board.h b/hw/bsp/imxrt/boards/teensy_41/board.h index 72c18f540..358684126 100644 --- a/hw/bsp/imxrt/boards/teensy_41/board.h +++ b/hw/bsp/imxrt/boards/teensy_41/board.h @@ -29,24 +29,21 @@ #define BOARD_H_ -// required since iMX RT10xx SDK include this file for board size +// required since iMXRT MCUX-SDK include this file for board size #define BOARD_FLASH_SIZE (8 * 1024 * 1024) -// LED -#define LED_PINMUX IOMUXC_GPIO_B0_03_GPIO2_IO03 // D13 -#define LED_PORT GPIO2 -#define LED_PIN 3 +// LED D13: IOMUXC_GPIO_B0_03_GPIO2_IO03 +#define LED_PORT BOARD_INITPINS_USER_LED_PERIPHERAL +#define LED_PIN BOARD_INITPINS_USER_LED_CHANNEL #define LED_STATE_ON 0 -// no button -#define BUTTON_PINMUX IOMUXC_GPIO_B0_01_GPIO2_IO01 // D12 -#define BUTTON_PORT GPIO2 -#define BUTTON_PIN 1 +// no button D12: IOMUXC_GPIO_B0_01_GPIO2_IO01 +#define BUTTON_PORT BOARD_INITPINS_USER_BUTTON_PERIPHERAL +#define BUTTON_PIN BOARD_INITPINS_USER_BUTTON_CHANNEL #define BUTTON_STATE_ACTIVE 0 -// UART +// UART D0, D1: IOMUXC_GPIO_AD_B0_03_LPUART6_RX, IOMUXC_GPIO_AD_B0_02_LPUART6_TX #define UART_PORT LPUART6 -#define UART_RX_PINMUX IOMUXC_GPIO_AD_B0_03_LPUART6_RX // D0 -#define UART_TX_PINMUX IOMUXC_GPIO_AD_B0_02_LPUART6_TX // D1 +#define UART_CLK_ROOT BOARD_BOOTCLOCKRUN_UART_CLK_ROOT #endif /* BOARD_H_ */ diff --git a/hw/bsp/imxrt/boards/teensy_41/board/pin_mux.c b/hw/bsp/imxrt/boards/teensy_41/board/pin_mux.c new file mode 100644 index 000000000..4c16be993 --- /dev/null +++ b/hw/bsp/imxrt/boards/teensy_41/board/pin_mux.c @@ -0,0 +1,181 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Pins v13.1 +processor: MIMXRT1062xxxxA +package_id: MIMXRT1062DVL6A +mcu_data: ksdk2_0 +processor_version: 13.0.2 +board: MIMXRT1060-EVK +pin_labels: +- {pin_num: E7, pin_signal: GPIO_B0_01, label: LCDIF_ENABLE, identifier: USER_BUTTON} +- {pin_num: D8, pin_signal: GPIO_B0_03, label: LCDIF_VSYNC, identifier: USER_LED} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +#include "fsl_common.h" +#include "fsl_iomuxc.h" +#include "fsl_gpio.h" +#include "pin_mux.h" + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitBootPins + * Description : Calls initialization functions. + * + * END ****************************************************************************************************************/ +void BOARD_InitBootPins(void) { + BOARD_InitPins(); + BOARD_InitDEBUG_UARTPins(); +} + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitPins: +- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: D8, peripheral: GPIO2, signal: 'gpio_io, 03', pin_signal: GPIO_B0_03, direction: OUTPUT} + - {pin_num: E7, peripheral: GPIO2, signal: 'gpio_io, 01', pin_signal: GPIO_B0_01, direction: INPUT, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + /* GPIO configuration of USER_BUTTON on GPIO_B0_01 (pin E7) */ + gpio_pin_config_t USER_BUTTON_config = { + .direction = kGPIO_DigitalInput, + .outputLogic = 0U, + .interruptMode = kGPIO_NoIntmode + }; + /* Initialize GPIO functionality on GPIO_B0_01 (pin E7) */ + GPIO_PinInit(GPIO2, 1U, &USER_BUTTON_config); + + /* GPIO configuration of USER_LED on GPIO_B0_03 (pin D8) */ + gpio_pin_config_t USER_LED_config = { + .direction = kGPIO_DigitalOutput, + .outputLogic = 0U, + .interruptMode = kGPIO_NoIntmode + }; + /* Initialize GPIO functionality on GPIO_B0_03 (pin D8) */ + GPIO_PinInit(GPIO2, 3U, &USER_LED_config); + + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_01_GPIO2_IO01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_03_GPIO2_IO03, 0U); + IOMUXC_GPR->GPR27 = ((IOMUXC_GPR->GPR27 & + (~(BOARD_INITPINS_IOMUXC_GPR_GPR27_GPIO_MUX2_GPIO_SEL_MASK))) + | IOMUXC_GPR_GPR27_GPIO_MUX2_GPIO_SEL(0x00U) + ); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_01_GPIO2_IO01, 0xB0B0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitDEBUG_UARTPins: +- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: K14, peripheral: LPUART1, signal: TX, pin_signal: GPIO_AD_B0_12, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Down_100K_Ohm, + pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} + - {pin_num: L14, peripheral: LPUART1, signal: RX, pin_signal: GPIO_AD_B0_13, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Down_100K_Ohm, + pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitDEBUG_UARTPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitDEBUG_UARTPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, 0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, 0x10B0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, 0x10B0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitUSDHCPins: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: J2, peripheral: USDHC1, signal: 'usdhc_data, 3', pin_signal: GPIO_SD_B0_05} + - {pin_num: H2, peripheral: USDHC1, signal: 'usdhc_data, 2', pin_signal: GPIO_SD_B0_04} + - {pin_num: K1, peripheral: USDHC1, signal: 'usdhc_data, 1', pin_signal: GPIO_SD_B0_03} + - {pin_num: J1, peripheral: USDHC1, signal: 'usdhc_data, 0', pin_signal: GPIO_SD_B0_02} + - {pin_num: J4, peripheral: USDHC1, signal: usdhc_cmd, pin_signal: GPIO_SD_B0_00} + - {pin_num: J3, peripheral: USDHC1, signal: usdhc_clk, pin_signal: GPIO_SD_B0_01} + - {pin_num: C14, peripheral: USDHC1, signal: usdhc_vselect, pin_signal: GPIO_B1_14} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitUSDHCPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitUSDHCPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_B1_14_USDHC1_VSELECT, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_00_USDHC1_CMD, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_01_USDHC1_CLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_02_USDHC1_DATA0, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_03_USDHC1_DATA1, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_04_USDHC1_DATA2, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_05_USDHC1_DATA3, 0U); +} + + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitQSPIPins: +- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: P3, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA0, pin_signal: GPIO_SD_B1_08} + - {pin_num: N4, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA1, pin_signal: GPIO_SD_B1_09} + - {pin_num: P4, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA2, pin_signal: GPIO_SD_B1_10} + - {pin_num: P5, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA3, pin_signal: GPIO_SD_B1_11} + - {pin_num: L4, peripheral: FLEXSPI, signal: FLEXSPI_A_SCLK, pin_signal: GPIO_SD_B1_07} + - {pin_num: L3, peripheral: FLEXSPI, signal: FLEXSPI_A_SS0_B, pin_signal: GPIO_SD_B1_06} + - {pin_num: N3, peripheral: FLEXSPI, signal: FLEXSPI_A_DQS, pin_signal: GPIO_SD_B1_05} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitQSPIPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitQSPIPins(void) { + CLOCK_EnableClock(kCLOCK_Iomuxc); + + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_05_FLEXSPIA_DQS, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_06_FLEXSPIA_SS0_B, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_07_FLEXSPIA_SCLK, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_08_FLEXSPIA_DATA00, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_09_FLEXSPIA_DATA01, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_10_FLEXSPIA_DATA02, 0U); + IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_11_FLEXSPIA_DATA03, 0U); +} + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/imxrt/boards/teensy_41/board/pin_mux.h b/hw/bsp/imxrt/boards/teensy_41/board/pin_mux.h new file mode 100644 index 000000000..f31f91598 --- /dev/null +++ b/hw/bsp/imxrt/boards/teensy_41/board/pin_mux.h @@ -0,0 +1,189 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _PIN_MUX_H_ +#define _PIN_MUX_H_ + +/*********************************************************************************************************************** + * Definitions + **********************************************************************************************************************/ + +/*! @brief Direction type */ +typedef enum _pin_mux_direction +{ + kPIN_MUX_DirectionInput = 0U, /* Input direction */ + kPIN_MUX_DirectionOutput = 1U, /* Output direction */ + kPIN_MUX_DirectionInputOrOutput = 2U /* Input or output direction */ +} pin_mux_direction_t; + +/*! + * @addtogroup pin_mux + * @{ + */ + +/*********************************************************************************************************************** + * API + **********************************************************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Calls initialization functions. + * + */ +void BOARD_InitBootPins(void); + +#define BOARD_INITPINS_IOMUXC_GPR_GPR27_GPIO_MUX2_GPIO_SEL_MASK 0x0AU /*!< GPIO2 and GPIO7 share same IO MUX function, GPIO_MUX2 selects one GPIO function: affected bits mask */ + +/* GPIO_B0_03 (coord D8), LCDIF_VSYNC */ +/* Routed pin properties */ +#define BOARD_INITPINS_USER_LED_PERIPHERAL GPIO2 /*!< Peripheral name */ +#define BOARD_INITPINS_USER_LED_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITPINS_USER_LED_CHANNEL 3U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_USER_LED_GPIO GPIO2 /*!< GPIO peripheral base pointer */ +#define BOARD_INITPINS_USER_LED_GPIO_PIN 3U /*!< GPIO pin number */ +#define BOARD_INITPINS_USER_LED_GPIO_PIN_MASK (1U << 3U) /*!< GPIO pin mask */ +#define BOARD_INITPINS_USER_LED_PORT GPIO2 /*!< PORT peripheral base pointer */ +#define BOARD_INITPINS_USER_LED_PIN 3U /*!< PORT pin number */ +#define BOARD_INITPINS_USER_LED_PIN_MASK (1U << 3U) /*!< PORT pin mask */ + +/* GPIO_B0_01 (coord E7), LCDIF_ENABLE */ +/* Routed pin properties */ +#define BOARD_INITPINS_USER_BUTTON_PERIPHERAL GPIO2 /*!< Peripheral name */ +#define BOARD_INITPINS_USER_BUTTON_SIGNAL gpio_io /*!< Signal name */ +#define BOARD_INITPINS_USER_BUTTON_CHANNEL 1U /*!< Signal channel */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_INITPINS_USER_BUTTON_GPIO GPIO2 /*!< GPIO peripheral base pointer */ +#define BOARD_INITPINS_USER_BUTTON_GPIO_PIN 1U /*!< GPIO pin number */ +#define BOARD_INITPINS_USER_BUTTON_GPIO_PIN_MASK (1U << 1U) /*!< GPIO pin mask */ +#define BOARD_INITPINS_USER_BUTTON_PORT GPIO2 /*!< PORT peripheral base pointer */ +#define BOARD_INITPINS_USER_BUTTON_PIN 1U /*!< PORT pin number */ +#define BOARD_INITPINS_USER_BUTTON_PIN_MASK (1U << 1U) /*!< PORT pin mask */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitPins(void); + +/* GPIO_AD_B0_12 (coord K14), UART1_TXD */ +/* Routed pin properties */ +#define BOARD_INITDEBUG_UARTPINS_UART1_TXD_PERIPHERAL LPUART1 /*!< Peripheral name */ +#define BOARD_INITDEBUG_UARTPINS_UART1_TXD_SIGNAL TX /*!< Signal name */ + +/* GPIO_AD_B0_13 (coord L14), UART1_RXD */ +/* Routed pin properties */ +#define BOARD_INITDEBUG_UARTPINS_UART1_RXD_PERIPHERAL LPUART1 /*!< Peripheral name */ +#define BOARD_INITDEBUG_UARTPINS_UART1_RXD_SIGNAL RX /*!< Signal name */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitDEBUG_UARTPins(void); + +/* GPIO_SD_B0_05 (coord J2), SD1_D3 */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_D3_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_D3_SIGNAL usdhc_data /*!< Signal name */ +#define BOARD_INITUSDHCPINS_SD1_D3_CHANNEL 3U /*!< Signal channel */ + +/* GPIO_SD_B0_04 (coord H2), SD1_D2 */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_D2_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_D2_SIGNAL usdhc_data /*!< Signal name */ +#define BOARD_INITUSDHCPINS_SD1_D2_CHANNEL 2U /*!< Signal channel */ + +/* GPIO_SD_B0_03 (coord K1), SD1_D1/J24[5]/SPI_MISO */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_D1_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_D1_SIGNAL usdhc_data /*!< Signal name */ +#define BOARD_INITUSDHCPINS_SD1_D1_CHANNEL 1U /*!< Signal channel */ + +/* GPIO_SD_B0_02 (coord J1), SD1_D0/J24[4]/SPI_MOSI/PWM */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_D0_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_D0_SIGNAL usdhc_data /*!< Signal name */ +#define BOARD_INITUSDHCPINS_SD1_D0_CHANNEL 0U /*!< Signal channel */ + +/* GPIO_SD_B0_00 (coord J4), SD1_CMD/J24[6] */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_CMD_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_CMD_SIGNAL usdhc_cmd /*!< Signal name */ + +/* GPIO_SD_B0_01 (coord J3), SD1_CLK/J24[3] */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD1_CLK_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD1_CLK_SIGNAL usdhc_clk /*!< Signal name */ + +/* GPIO_B1_14 (coord C14), SD0_VSELECT */ +/* Routed pin properties */ +#define BOARD_INITUSDHCPINS_SD0_VSELECT_PERIPHERAL USDHC1 /*!< Peripheral name */ +#define BOARD_INITUSDHCPINS_SD0_VSELECT_SIGNAL usdhc_vselect /*!< Signal name */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitUSDHCPins(void); + +/* GPIO_SD_B1_08 (coord P3), FlexSPI_D0_A */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_D0_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_D0_A_SIGNAL FLEXSPI_A_DATA0 /*!< Signal name */ + +/* GPIO_SD_B1_09 (coord N4), FlexSPI_D1_A */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_D1_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_D1_A_SIGNAL FLEXSPI_A_DATA1 /*!< Signal name */ + +/* GPIO_SD_B1_10 (coord P4), FlexSPI_D2_A */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_D2_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_D2_A_SIGNAL FLEXSPI_A_DATA2 /*!< Signal name */ + +/* GPIO_SD_B1_11 (coord P5), FlexSPI_D3_A */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_D3_A_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_D3_A_SIGNAL FLEXSPI_A_DATA3 /*!< Signal name */ + +/* GPIO_SD_B1_07 (coord L4), FlexSPI_CLK */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_CLK_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_CLK_SIGNAL FLEXSPI_A_SCLK /*!< Signal name */ + +/* GPIO_SD_B1_06 (coord L3), FlexSPI_SS0 */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_SS0_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_SS0_SIGNAL FLEXSPI_A_SS0_B /*!< Signal name */ + +/* GPIO_SD_B1_05 (coord N3), FlexSPI_DQS */ +/* Routed pin properties */ +#define BOARD_INITQSPIPINS_FlexSPI_DQS_PERIPHERAL FLEXSPI /*!< Peripheral name */ +#define BOARD_INITQSPIPINS_FlexSPI_DQS_SIGNAL FLEXSPI_A_DQS /*!< Signal name */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitQSPIPins(void); + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif /* _PIN_MUX_H_ */ + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/imxrt/boards/teensy_41/teensy41.mex b/hw/bsp/imxrt/boards/teensy_41/teensy41.mex index 39b3ed606..1ade853ae 100644 --- a/hw/bsp/imxrt/boards/teensy_41/teensy41.mex +++ b/hw/bsp/imxrt/boards/teensy_41/teensy41.mex @@ -26,6 +26,10 @@ 13.0.2 + + + + @@ -37,13 +41,41 @@ true + + + true + + true + + + true + + + + + true + + - + + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. @@ -98,385 +130,6 @@ - - Configures pin routing and optionally pin electrical features. - - false - core0 - true - - - - - true - - - - - true - - - - - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Configures pin routing and optionally pin electrical features. - - false - core0 - true - - - - - true - - - - - true - - - - - true - - - - - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Configures pin routing and optionally pin electrical features. - - false - core0 - true - - - - - true - - - - - true - - - - - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Configures pin routing and optionally pin electrical features. - - false - core0 - true - - - - - true - - - - - true - - - - - true - - - - - - - - - - Configures pin routing and optionally pin electrical features. - - false - core0 - true - - - - - true - - - - - true - - - - - true - - - - - - - - - - - - - - - - Configures pin routing and optionally pin electrical features. @@ -717,11 +370,8 @@ - - - - - + + 13.0.2 diff --git a/hw/bsp/imxrt/family.c b/hw/bsp/imxrt/family.c index ec95a8b24..c9c4918ef 100644 --- a/hw/bsp/imxrt/family.c +++ b/hw/bsp/imxrt/family.c @@ -25,6 +25,8 @@ */ #include "bsp/board_api.h" +#include "board/clock_config.h" +#include "board/pin_mux.h" #include "board.h" // Suppress warning caused by mcu driver @@ -43,8 +45,6 @@ #pragma GCC diagnostic pop #endif -#include "clock_config.h" - #if defined(BOARD_TUD_RHPORT) && CFG_TUD_ENABLED #define PORT_SUPPORT_DEVICE(_n) (BOARD_TUD_RHPORT == _n) #else @@ -58,14 +58,36 @@ #endif // needed by fsl_flexspi_nor_boot -TU_ATTR_USED -const uint8_t dcd_data[] = { 0x00 }; +TU_ATTR_USED const uint8_t dcd_data[] = { 0x00 }; //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ -static void init_usb_phy(USBPHY_Type* usb_phy) { +// unify naming convention +#if !defined(USBPHY1) && defined(USBPHY) + #define USBPHY1 USBPHY +#endif + +static void init_usb_phy(uint8_t usb_id) { + USBPHY_Type* usb_phy; + + if (usb_id == 0) { + usb_phy = USBPHY1; + CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usbphy480M, BOARD_XTAL0_CLK_HZ); + CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M, BOARD_XTAL0_CLK_HZ); + } + #ifdef USBPHY2 + else if (usb_id == 1) { + usb_phy = USBPHY2; + CLOCK_EnableUsbhs1PhyPllClock(kCLOCK_Usbphy480M, BOARD_XTAL0_CLK_HZ); + CLOCK_EnableUsbhs1Clock(kCLOCK_Usb480M, BOARD_XTAL0_CLK_HZ); + } + #endif + else { + return; + } + // Enable PHY support for Low speed device + LS via FS Hub usb_phy->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK | USBPHY_CTRL_SET_ENUTMILEVEL3_MASK; @@ -87,23 +109,14 @@ void board_init(void) if (SCB_CCR_DC_Msk != (SCB_CCR_DC_Msk & SCB->CCR)) SCB_EnableDCache(); #endif - // Init clock + BOARD_InitPins(); BOARD_BootClockRUN(); SystemCoreClockUpdate(); #ifdef TRACE_ETM - // RT1011 ETM pins -// IOMUXC_SetPinMux(IOMUXC_GPIO_11_ARM_TRACE3, 0U); -// IOMUXC_SetPinMux(IOMUXC_GPIO_12_ARM_TRACE2, 0U); -// IOMUXC_SetPinMux(IOMUXC_GPIO_13_ARM_TRACE1, 0U); -// IOMUXC_SetPinMux(IOMUXC_GPIO_AD_00_ARM_TRACE0, 0U); -// IOMUXC_SetPinMux(IOMUXC_GPIO_AD_02_ARM_TRACE_CLK, 0U); -// CLOCK_EnableClock(kCLOCK_Trace); + //CLOCK_EnableClock(kCLOCK_Trace); #endif - // Enable IOCON clock - CLOCK_EnableClock(kCLOCK_Iomuxc); - #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); @@ -116,90 +129,48 @@ void board_init(void) #endif #endif - // LED - IOMUXC_SetPinMux( LED_PINMUX, 0U); - IOMUXC_SetPinConfig( LED_PINMUX, 0x10B0U); - - gpio_pin_config_t led_config = { kGPIO_DigitalOutput, 0, kGPIO_NoIntmode }; - GPIO_PinInit(LED_PORT, LED_PIN, &led_config); board_led_write(true); - // Button - IOMUXC_SetPinMux( BUTTON_PINMUX, 0U); - IOMUXC_SetPinConfig(BUTTON_PINMUX, 0x01B0A0U); - gpio_pin_config_t button_config = { kGPIO_DigitalInput, 0, kGPIO_IntRisingEdge, }; - GPIO_PinInit(BUTTON_PORT, BUTTON_PIN, &button_config); - // UART - IOMUXC_SetPinMux( UART_TX_PINMUX, 0U); - IOMUXC_SetPinMux( UART_RX_PINMUX, 0U); - IOMUXC_SetPinConfig( UART_TX_PINMUX, 0x10B0u); - IOMUXC_SetPinConfig( UART_RX_PINMUX, 0x10B0u); - lpuart_config_t uart_config; LPUART_GetDefaultConfig(&uart_config); uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE; uart_config.enableTx = true; uart_config.enableRx = true; - uint32_t freq; - if (CLOCK_GetMux(kCLOCK_UartMux) == 0) /* PLL3 div6 80M */ - { - freq = (CLOCK_GetPllFreq(kCLOCK_PllUsb1) / 6U) / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U); - } - else - { - freq = CLOCK_GetOscFreq() / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U); - } - - if ( kStatus_Success != LPUART_Init(UART_PORT, &uart_config, freq) ) { + if ( kStatus_Success != LPUART_Init(UART_PORT, &uart_config, UART_CLK_ROOT) ) { // failed to init uart, probably baudrate is not supported // TU_BREAKPOINT(); } //------------- USB -------------// // Note: RT105x RT106x and later have dual USB controllers. - - // Clock - CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usbphy480M, 480000000U); - CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M, 480000000U); - -#ifdef USBPHY1 - init_usb_phy(USBPHY1); -#else - init_usb_phy(USBPHY); -#endif - + init_usb_phy(0); // USB0 #ifdef USBPHY2 - // USB1 - CLOCK_EnableUsbhs1PhyPllClock(kCLOCK_Usbphy480M, 480000000U); - CLOCK_EnableUsbhs1Clock(kCLOCK_Usb480M, 480000000U); - init_usb_phy(USBPHY2); + init_usb_phy(1); // USB1 #endif } //--------------------------------------------------------------------+ // USB Interrupt Handler //--------------------------------------------------------------------+ -void USB_OTG1_IRQHandler(void) -{ +void USB_OTG1_IRQHandler(void) { #if PORT_SUPPORT_DEVICE(0) - tud_int_handler(0); + tud_int_handler(0); #endif #if PORT_SUPPORT_HOST(0) - tuh_int_handler(0); + tuh_int_handler(0, true); #endif } -void USB_OTG2_IRQHandler(void) -{ +void USB_OTG2_IRQHandler(void) { #if PORT_SUPPORT_DEVICE(1) - tud_int_handler(1); + tud_int_handler(1); #endif #if PORT_SUPPORT_HOST(1) - tuh_int_handler(1); + tuh_int_handler(1, true); #endif } @@ -207,35 +178,29 @@ void USB_OTG2_IRQHandler(void) // Board porting API //--------------------------------------------------------------------+ -void board_led_write(bool state) -{ - GPIO_PinWrite(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +void board_led_write(bool state) { + GPIO_PinWrite(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } -uint32_t board_button_read(void) -{ - // active low +uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_PORT, BUTTON_PIN); } -int board_uart_read(uint8_t* buf, int len) -{ +int board_uart_read(uint8_t* buf, int len) { int count = 0; - while( count < len ) - { + while (count < len) { uint8_t const rx_count = LPUART_GetRxFifoCount(UART_PORT); - if (!rx_count) - { + 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); + status_flags &= (kLPUART_RxOverrunFlag | kLPUART_ParityErrorFlag | kLPUART_FramingErrorFlag | + kLPUART_NoiseErrorFlag); LPUART_ClearStatusFlags(UART_PORT, status_flags); break; } - for(int i=0; iDHCSR */ \ + 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 4 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<C1 = ((MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(frdiv)); +} + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ +void BOARD_InitBootClocks(void) +{ +} + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockRUN +outputs: +- {id: Bus_clock.outFreq, value: 60 MHz} +- {id: CLKOUT.outFreq, value: 40 MHz} +- {id: Core_clock.outFreq, value: 120 MHz, locked: true, accuracy: '0.001'} +- {id: ENET1588TSCLK.outFreq, value: 50 MHz} +- {id: Flash_clock.outFreq, value: 24 MHz} +- {id: FlexBus_clock.outFreq, value: 40 MHz} +- {id: LPO_clock.outFreq, value: 1 kHz} +- {id: MCGFFCLK.outFreq, value: 1.5625 MHz} +- {id: MCGIRCLK.outFreq, value: 2 MHz} +- {id: OSCERCLK.outFreq, value: 50 MHz} +- {id: PLLFLLCLK.outFreq, value: 120 MHz} +- {id: RMIICLK.outFreq, value: 50 MHz} +- {id: SDHCCLK.outFreq, value: 50 MHz} +- {id: System_clock.outFreq, value: 120 MHz} +- {id: TRACECLKIN.outFreq, value: 120 MHz} +- {id: USB48MCLK.outFreq, value: 48 MHz} +settings: +- {id: MCGMode, value: PEE} +- {id: CLKOUTConfig, value: 'yes'} +- {id: ENETTimeSrcConfig, value: 'yes'} +- {id: MCG.FRDIV.scale, value: '32'} +- {id: MCG.IRCS.sel, value: MCG.FCRDIV} +- {id: MCG.IREFS.sel, value: MCG.FRDIV} +- {id: MCG.PLLS.sel, value: MCG.PLL} +- {id: MCG.PRDIV.scale, value: '15'} +- {id: MCG.VDIV.scale, value: '36'} +- {id: MCG_C1_IRCLKEN_CFG, value: Enabled} +- {id: MCG_C2_RANGE0_CFG, value: Very_high} +- {id: MCG_C2_RANGE0_FRDIV_CFG, value: Very_high} +- {id: OSC_CR_ERCLKEN_CFG, value: Enabled} +- {id: RMIISrcConfig, value: 'yes'} +- {id: RTCCLKOUTConfig, value: 'yes'} +- {id: RTC_CR_OSCE_CFG, value: Enabled} +- {id: RTC_CR_OSC_CAP_LOAD_CFG, value: SC10PF} +- {id: SDHCClkConfig, value: 'yes'} +- {id: SIM.OSC32KSEL.sel, value: RTC.RTC32KCLK} +- {id: SIM.OUTDIV2.scale, value: '2'} +- {id: SIM.OUTDIV3.scale, value: '3'} +- {id: SIM.OUTDIV4.scale, value: '5'} +- {id: SIM.PLLFLLSEL.sel, value: MCG.MCGPLLCLK} +- {id: SIM.RTCCLKOUTSEL.sel, value: RTC.RTC32KCLK} +- {id: SIM.SDHCSRCSEL.sel, value: OSC.OSCERCLK} +- {id: SIM.TIMESRCSEL.sel, value: OSC.OSCERCLK} +- {id: SIM.USBDIV.scale, value: '5'} +- {id: SIM.USBFRAC.scale, value: '2'} +- {id: SIM.USBSRCSEL.sel, value: SIM.USBDIV} +- {id: TraceClkConfig, value: 'yes'} +- {id: USBClkConfig, value: 'yes'} +sources: +- {id: OSC.OSC.outFreq, value: 50 MHz, enabled: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockRUN configuration + ******************************************************************************/ +const mcg_config_t mcgConfig_BOARD_BootClockRUN = + { + .mcgMode = kMCG_ModePEE, /* PEE - PLL Engaged External */ + .irclkEnableMode = kMCG_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */ + .ircs = kMCG_IrcFast, /* Fast internal reference clock selected */ + .fcrdiv = 0x1U, /* Fast IRC divider: divided by 2 */ + .frdiv = 0x0U, /* FLL reference clock divider: divided by 32 */ + .drs = kMCG_DrsLow, /* Low frequency range */ + .dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25% */ + .oscsel = kMCG_OscselOsc, /* Selects System Oscillator (OSCCLK) */ + .pll0Config = + { + .enableMode = MCG_PLL_DISABLE, /* MCGPLLCLK disabled */ + .prdiv = 0xeU, /* PLL Reference divider: divided by 15 */ + .vdiv = 0xcU, /* VCO divider: multiplied by 36 */ + }, + }; +const sim_clock_config_t simConfig_BOARD_BootClockRUN = + { + .pllFllSel = SIM_PLLFLLSEL_MCGPLLCLK_CLK, /* PLLFLL select: MCGPLLCLK clock */ + .er32kSrc = SIM_OSC32KSEL_RTC32KCLK_CLK, /* OSC32KSEL select: RTC32KCLK clock (32.768kHz) */ + .clkdiv1 = 0x1240000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV2: /2, OUTDIV3: /3, OUTDIV4: /5 */ + }; +const osc_config_t oscConfig_BOARD_BootClockRUN = + { + .freq = 50000000U, /* Oscillator frequency: 50000000Hz */ + .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ + .workMode = kOSC_ModeExt, /* Use external clock */ + .oscerConfig = + { + .enableMode = kOSC_ErClkEnable, /* Enable external reference clock, disable external reference clock in STOP mode */ + } + }; + +/******************************************************************************* + * Code for BOARD_BootClockRUN configuration + ******************************************************************************/ +void BOARD_BootClockRUN(void) +{ + /* Set the system clock dividers in SIM to safe value. */ + CLOCK_SetSimSafeDivs(); + /* Initializes OSC0 according to board configuration. */ + CLOCK_InitOsc0(&oscConfig_BOARD_BootClockRUN); + CLOCK_SetXtal0Freq(oscConfig_BOARD_BootClockRUN.freq); + /* Configure the Internal Reference clock (MCGIRCLK). */ + CLOCK_SetInternalRefClkConfig(mcgConfig_BOARD_BootClockRUN.irclkEnableMode, + mcgConfig_BOARD_BootClockRUN.ircs, + mcgConfig_BOARD_BootClockRUN.fcrdiv); + /* Configure FLL external reference divider (FRDIV). */ + CLOCK_CONFIG_SetFllExtRefDiv(mcgConfig_BOARD_BootClockRUN.frdiv); + /* Set MCG to PEE mode. */ + CLOCK_BootToPeeMode(mcgConfig_BOARD_BootClockRUN.oscsel, + kMCG_PllClkSelPll0, + &mcgConfig_BOARD_BootClockRUN.pll0Config); + /* Set the clock configuration in SIM module. */ + CLOCK_SetSimConfig(&simConfig_BOARD_BootClockRUN); + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; + /* Enable USB FS clock. */ + CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcPll0, SIM_USB_CLK_120000000HZ); + /* Set enet timestamp clock source. */ + CLOCK_SetEnetTime0Clock(SIM_ENET_1588T_CLK_SEL_OSCERCLK_CLK); + /* Set RMII clock source. */ + CLOCK_SetRmii0Clock(SIM_ENET_RMII_CLK_SEL_EXTAL_CLK); + /* Set SDHC clock source. */ + CLOCK_SetSdhc0Clock(SIM_SDHC_CLK_SEL_OSCERCLK_CLK); + /* Set CLKOUT source. */ + CLOCK_SetClkOutClock(SIM_CLKOUT_SEL_FLEXBUS_CLK); + /* Set debug trace clock source. */ + CLOCK_SetTraceClock(SIM_TRACE_CLK_SEL_CORE_SYSTEM_CLK); +} + +/******************************************************************************* + ********************* Configuration BOARD_BootClockVLPR *********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockVLPR +outputs: +- {id: Bus_clock.outFreq, value: 4 MHz} +- {id: Core_clock.outFreq, value: 4 MHz, locked: true, accuracy: '0.001'} +- {id: Flash_clock.outFreq, value: 800 kHz} +- {id: FlexBus_clock.outFreq, value: 4 MHz} +- {id: LPO_clock.outFreq, value: 1 kHz} +- {id: System_clock.outFreq, value: 4 MHz} +settings: +- {id: MCGMode, value: BLPI} +- {id: powerMode, value: VLPR} +- {id: MCG.CLKS.sel, value: MCG.IRCS} +- {id: MCG.FCRDIV.scale, value: '1'} +- {id: MCG.FRDIV.scale, value: '32'} +- {id: MCG.IRCS.sel, value: MCG.FCRDIV} +- {id: MCG_C2_RANGE0_CFG, value: Very_high} +- {id: MCG_C2_RANGE0_FRDIV_CFG, value: Very_high} +- {id: RTC_CR_OSCE_CFG, value: Enabled} +- {id: RTC_CR_OSC_CAP_LOAD_CFG, value: SC10PF} +- {id: SIM.OSC32KSEL.sel, value: RTC.RTC32KCLK} +- {id: SIM.OUTDIV3.scale, value: '1'} +- {id: SIM.OUTDIV4.scale, value: '5'} +- {id: SIM.PLLFLLSEL.sel, value: IRC48M.IRC48MCLK} +- {id: SIM.RTCCLKOUTSEL.sel, value: RTC.RTC32KCLK} +sources: +- {id: OSC.OSC.outFreq, value: 50 MHz} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockVLPR configuration + ******************************************************************************/ +const mcg_config_t mcgConfig_BOARD_BootClockVLPR = + { + .mcgMode = kMCG_ModeBLPI, /* BLPI - Bypassed Low Power Internal */ + .irclkEnableMode = MCG_IRCLK_DISABLE, /* MCGIRCLK disabled */ + .ircs = kMCG_IrcFast, /* Fast internal reference clock selected */ + .fcrdiv = 0x0U, /* Fast IRC divider: divided by 1 */ + .frdiv = 0x0U, /* FLL reference clock divider: divided by 32 */ + .drs = kMCG_DrsLow, /* Low frequency range */ + .dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25% */ + .oscsel = kMCG_OscselOsc, /* Selects System Oscillator (OSCCLK) */ + .pll0Config = + { + .enableMode = MCG_PLL_DISABLE, /* MCGPLLCLK disabled */ + .prdiv = 0x0U, /* PLL Reference divider: divided by 1 */ + .vdiv = 0x0U, /* VCO divider: multiplied by 24 */ + }, + }; +const sim_clock_config_t simConfig_BOARD_BootClockVLPR = + { + .pllFllSel = SIM_PLLFLLSEL_IRC48MCLK_CLK, /* PLLFLL select: IRC48MCLK clock */ + .er32kSrc = SIM_OSC32KSEL_RTC32KCLK_CLK, /* OSC32KSEL select: RTC32KCLK clock (32.768kHz) */ + .clkdiv1 = 0x40000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV2: /1, OUTDIV3: /1, OUTDIV4: /5 */ + }; +const osc_config_t oscConfig_BOARD_BootClockVLPR = + { + .freq = 0U, /* Oscillator frequency: 0Hz */ + .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ + .workMode = kOSC_ModeExt, /* Use external clock */ + .oscerConfig = + { + .enableMode = OSC_ER_CLK_DISABLE, /* Disable external reference clock */ + } + }; + +/******************************************************************************* + * Code for BOARD_BootClockVLPR configuration + ******************************************************************************/ +void BOARD_BootClockVLPR(void) +{ + /* Set the system clock dividers in SIM to safe value. */ + CLOCK_SetSimSafeDivs(); + /* Set MCG to BLPI mode. */ + CLOCK_BootToBlpiMode(mcgConfig_BOARD_BootClockVLPR.fcrdiv, + mcgConfig_BOARD_BootClockVLPR.ircs, + mcgConfig_BOARD_BootClockVLPR.irclkEnableMode); + /* Set the clock configuration in SIM module. */ + CLOCK_SetSimConfig(&simConfig_BOARD_BootClockVLPR); + /* Set VLPR power mode. */ + SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); +#if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI) + SMC_SetPowerModeVlpr(SMC, false); +#else + SMC_SetPowerModeVlpr(SMC); +#endif + while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateVlpr) + { + } + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKVLPR_CORE_CLOCK; +} diff --git a/hw/bsp/kinetis_k/boards/frdm_k64f/board/clock_config.h b/hw/bsp/kinetis_k/boards/frdm_k64f/board/clock_config.h new file mode 100644 index 000000000..88b141834 --- /dev/null +++ b/hw/bsp/kinetis_k/boards/frdm_k64f/board/clock_config.h @@ -0,0 +1,104 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 50000000U /*!< Board xtal0 frequency in Hz */ + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockRUN configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 120000000U /*!< Core clock frequency: 120000000Hz */ + +/*! @brief MCG set for BOARD_BootClockRUN configuration. + */ +extern const mcg_config_t mcgConfig_BOARD_BootClockRUN; +/*! @brief SIM module set for BOARD_BootClockRUN configuration. + */ +extern const sim_clock_config_t simConfig_BOARD_BootClockRUN; +/*! @brief OSC set for BOARD_BootClockRUN configuration. + */ +extern const osc_config_t oscConfig_BOARD_BootClockRUN; + +/******************************************************************************* + * API for BOARD_BootClockRUN configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************* Configuration BOARD_BootClockVLPR *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockVLPR configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKVLPR_CORE_CLOCK 4000000U /*!< Core clock frequency: 4000000Hz */ + +/*! @brief MCG set for BOARD_BootClockVLPR configuration. + */ +extern const mcg_config_t mcgConfig_BOARD_BootClockVLPR; +/*! @brief SIM module set for BOARD_BootClockVLPR configuration. + */ +extern const sim_clock_config_t simConfig_BOARD_BootClockVLPR; +/*! @brief OSC set for BOARD_BootClockVLPR configuration. + */ +extern const osc_config_t oscConfig_BOARD_BootClockVLPR; + +/******************************************************************************* + * API for BOARD_BootClockVLPR configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockVLPR(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ diff --git a/hw/bsp/kinetis_k/boards/frdm_k64f/board/pin_mux.c b/hw/bsp/kinetis_k/boards/frdm_k64f/board/pin_mux.c new file mode 100644 index 000000000..f4c245eef --- /dev/null +++ b/hw/bsp/kinetis_k/boards/frdm_k64f/board/pin_mux.c @@ -0,0 +1,852 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Pins v14.0 +processor: MK64FN1M0xxx12 +package_id: MK64FN1M0VLL12 +mcu_data: ksdk2_0 +processor_version: 14.0.0 +board: FRDM-K64F + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +#include "fsl_common.h" +#include "fsl_port.h" +#include "fsl_gpio.h" +#include "pin_mux.h" + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitBootPins + * Description : Calls initialization functions. + * + * END ****************************************************************************************************************/ +void BOARD_InitBootPins(void) +{ + BOARD_InitButtons(); + BOARD_InitLEDs(); + BOARD_InitDEBUG_UART(); +} + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitPins: +- options: {callFromInitBoot: 'false', prefix: BOARD_, coreID: core0, enableClock: 'true'} +- pin_list: [] + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitPins(void) +{ +} + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitButtons: +- options: {callFromInitBoot: 'true', prefix: BOARD_, coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '78', peripheral: GPIOC, signal: 'GPIO, 6', pin_signal: CMP0_IN0/PTC6/LLWU_P10/SPI0_SOUT/PDB0_EXTRG/I2S0_RX_BCLK/FB_AD9/I2S0_MCLK, identifier: SW2, + direction: INPUT, slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: up, pull_enable: enable, passive_filter: disable} + - {pin_num: '38', peripheral: GPIOA, signal: 'GPIO, 4', pin_signal: PTA4/LLWU_P3/FTM0_CH1/NMI_b/EZP_CS_b, direction: INPUT, slew_rate: fast, open_drain: disable, + drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitButtons + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitButtons(void) +{ + /* Port A Clock Gate Control: Clock enabled */ + CLOCK_EnableClock(kCLOCK_PortA); + /* Port C Clock Gate Control: Clock enabled */ + CLOCK_EnableClock(kCLOCK_PortC); + + gpio_pin_config_t SW3_config = { + .pinDirection = kGPIO_DigitalInput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PTA4 (pin 38) */ + GPIO_PinInit(BOARD_SW3_GPIO, BOARD_SW3_PIN, &SW3_config); + + gpio_pin_config_t SW2_config = { + .pinDirection = kGPIO_DigitalInput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PTC6 (pin 78) */ + GPIO_PinInit(BOARD_SW2_GPIO, BOARD_SW2_PIN, &SW2_config); + + const port_pin_config_t SW3 = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as PTA4 */ + kPORT_MuxAsGpio, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTA4 (pin 38) is configured as PTA4 */ + PORT_SetPinConfig(BOARD_SW3_PORT, BOARD_SW3_PIN, &SW3); + + const port_pin_config_t SW2 = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as PTC6 */ + kPORT_MuxAsGpio, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTC6 (pin 78) is configured as PTC6 */ + PORT_SetPinConfig(BOARD_SW2_PORT, BOARD_SW2_PIN, &SW2); +} + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitLEDs: +- options: {callFromInitBoot: 'true', prefix: BOARD_, coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '67', peripheral: GPIOB, signal: 'GPIO, 21', pin_signal: PTB21/SPI2_SCK/FB_AD30/CMP1_OUT, direction: OUTPUT, gpio_init_state: 'true', slew_rate: slow, + open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} + - {pin_num: '68', peripheral: GPIOB, signal: 'GPIO, 22', pin_signal: PTB22/SPI2_SOUT/FB_AD29/CMP2_OUT, direction: OUTPUT, gpio_init_state: 'true', slew_rate: slow, + open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} + - {pin_num: '33', peripheral: GPIOE, signal: 'GPIO, 26', pin_signal: PTE26/ENET_1588_CLKIN/UART4_CTS_b/RTC_CLKOUT/USB_CLKIN, direction: OUTPUT, gpio_init_state: 'true', + slew_rate: slow, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitLEDs + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitLEDs(void) +{ + /* Port B Clock Gate Control: Clock enabled */ + CLOCK_EnableClock(kCLOCK_PortB); + /* Port E Clock Gate Control: Clock enabled */ + CLOCK_EnableClock(kCLOCK_PortE); + + gpio_pin_config_t LED_BLUE_config = { + .pinDirection = kGPIO_DigitalOutput, + .outputLogic = 1U + }; + /* Initialize GPIO functionality on pin PTB21 (pin 67) */ + GPIO_PinInit(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_PIN, &LED_BLUE_config); + + gpio_pin_config_t LED_RED_config = { + .pinDirection = kGPIO_DigitalOutput, + .outputLogic = 1U + }; + /* Initialize GPIO functionality on pin PTB22 (pin 68) */ + GPIO_PinInit(BOARD_LED_RED_GPIO, BOARD_LED_RED_PIN, &LED_RED_config); + + gpio_pin_config_t LED_GREEN_config = { + .pinDirection = kGPIO_DigitalOutput, + .outputLogic = 1U + }; + /* Initialize GPIO functionality on pin PTE26 (pin 33) */ + GPIO_PinInit(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_PIN, &LED_GREEN_config); + + const port_pin_config_t LED_BLUE = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Slow slew rate is configured */ + kPORT_SlowSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as PTB21 */ + kPORT_MuxAsGpio, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTB21 (pin 67) is configured as PTB21 */ + PORT_SetPinConfig(BOARD_LED_BLUE_PORT, BOARD_LED_BLUE_PIN, &LED_BLUE); + + const port_pin_config_t LED_RED = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Slow slew rate is configured */ + kPORT_SlowSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as PTB22 */ + kPORT_MuxAsGpio, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTB22 (pin 68) is configured as PTB22 */ + PORT_SetPinConfig(BOARD_LED_RED_PORT, BOARD_LED_RED_PIN, &LED_RED); + + const port_pin_config_t LED_GREEN = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Slow slew rate is configured */ + kPORT_SlowSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as PTE26 */ + kPORT_MuxAsGpio, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTE26 (pin 33) is configured as PTE26 */ + PORT_SetPinConfig(BOARD_LED_GREEN_PORT, BOARD_LED_GREEN_PIN, &LED_GREEN); +} + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitDEBUG_UART: +- options: {callFromInitBoot: 'true', prefix: BOARD_, coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '63', peripheral: UART0, signal: TX, pin_signal: PTB17/SPI1_SIN/UART0_TX/FTM_CLKIN1/FB_AD16/EWM_OUT_b, direction: OUTPUT, slew_rate: fast, open_drain: disable, + drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} + - {pin_num: '62', peripheral: UART0, signal: RX, pin_signal: PTB16/SPI1_SOUT/UART0_RX/FTM_CLKIN0/FB_AD17/EWM_IN, slew_rate: fast, open_drain: disable, drive_strength: low, + pull_select: down, pull_enable: disable, passive_filter: disable} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitDEBUG_UART + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitDEBUG_UART(void) +{ + /* Port B Clock Gate Control: Clock enabled */ + CLOCK_EnableClock(kCLOCK_PortB); + + const port_pin_config_t DEBUG_UART_RX = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as UART0_RX */ + kPORT_MuxAlt3, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTB16 (pin 62) is configured as UART0_RX */ + PORT_SetPinConfig(BOARD_DEBUG_UART_RX_PORT, BOARD_DEBUG_UART_RX_PIN, &DEBUG_UART_RX); + + const port_pin_config_t DEBUG_UART_TX = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as UART0_TX */ + kPORT_MuxAlt3, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTB17 (pin 63) is configured as UART0_TX */ + PORT_SetPinConfig(BOARD_DEBUG_UART_TX_PORT, BOARD_DEBUG_UART_TX_PIN, &DEBUG_UART_TX); + + SIM->SOPT5 = ((SIM->SOPT5 & + /* Mask bits to zero which are setting */ + (~(SIM_SOPT5_UART0TXSRC_MASK))) + + /* UART 0 transmit data source select: UART0_TX pin. */ + | SIM_SOPT5_UART0TXSRC(SOPT5_UART0TXSRC_UART_TX)); +} + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitOSC: +- options: {callFromInitBoot: 'false', prefix: BOARD_, coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '50', peripheral: OSC, signal: EXTAL0, pin_signal: EXTAL0/PTA18/FTM0_FLT2/FTM_CLKIN0, identifier: EXTAL0, slew_rate: no_init, open_drain: no_init, drive_strength: no_init, + pull_select: no_init, pull_enable: no_init, passive_filter: no_init} + - {pin_num: '29', peripheral: RTC, signal: EXTAL32, pin_signal: EXTAL32} + - {pin_num: '28', peripheral: RTC, signal: XTAL32, pin_signal: XTAL32} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitOSC + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitOSC(void) +{ + /* Port A Clock Gate Control: Clock enabled */ + CLOCK_EnableClock(kCLOCK_PortA); + + /* PORTA18 (pin 50) is configured as EXTAL0 */ + PORT_SetPinMux(BOARD_EXTAL0_PORT, BOARD_EXTAL0_PIN, kPORT_PinDisabledOrAnalog); +} + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitACCEL: +- options: {callFromInitBoot: 'false', prefix: BOARD_, coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '32', peripheral: I2C0, signal: SDA, pin_signal: ADC0_SE18/PTE25/UART4_RX/I2C0_SDA/EWM_IN, slew_rate: fast, open_drain: enable, drive_strength: low, + pull_select: up, pull_enable: enable, passive_filter: disable} + - {pin_num: '31', peripheral: I2C0, signal: SCL, pin_signal: ADC0_SE17/PTE24/UART4_TX/I2C0_SCL/EWM_OUT_b, slew_rate: fast, open_drain: enable, drive_strength: low, + pull_select: up, pull_enable: enable, passive_filter: disable} + - {pin_num: '78', peripheral: GPIOC, signal: 'GPIO, 6', pin_signal: CMP0_IN0/PTC6/LLWU_P10/SPI0_SOUT/PDB0_EXTRG/I2S0_RX_BCLK/FB_AD9/I2S0_MCLK, identifier: ACCEL_INT1, + direction: INPUT, slew_rate: fast, open_drain: enable, drive_strength: low, pull_select: up, pull_enable: enable, passive_filter: disable} + - {pin_num: '85', peripheral: GPIOC, signal: 'GPIO, 13', pin_signal: PTC13/UART4_CTS_b/FB_AD26, direction: INPUT, slew_rate: fast, open_drain: enable, drive_strength: low, + pull_select: up, pull_enable: enable, passive_filter: disable} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitACCEL + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitACCEL(void) +{ + /* Port C Clock Gate Control: Clock enabled */ + CLOCK_EnableClock(kCLOCK_PortC); + /* Port E Clock Gate Control: Clock enabled */ + CLOCK_EnableClock(kCLOCK_PortE); + + gpio_pin_config_t ACCEL_INT1_config = { + .pinDirection = kGPIO_DigitalInput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PTC6 (pin 78) */ + GPIO_PinInit(BOARD_ACCEL_INT1_GPIO, BOARD_ACCEL_INT1_PIN, &ACCEL_INT1_config); + + gpio_pin_config_t ACCEL_INT2_config = { + .pinDirection = kGPIO_DigitalInput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PTC13 (pin 85) */ + GPIO_PinInit(BOARD_ACCEL_INT2_GPIO, BOARD_ACCEL_INT2_PIN, &ACCEL_INT2_config); + + const port_pin_config_t ACCEL_INT2 = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is enabled */ + kPORT_OpenDrainEnable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as PTC13 */ + kPORT_MuxAsGpio, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTC13 (pin 85) is configured as PTC13 */ + PORT_SetPinConfig(BOARD_ACCEL_INT2_PORT, BOARD_ACCEL_INT2_PIN, &ACCEL_INT2); + + const port_pin_config_t ACCEL_INT1 = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is enabled */ + kPORT_OpenDrainEnable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as PTC6 */ + kPORT_MuxAsGpio, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTC6 (pin 78) is configured as PTC6 */ + PORT_SetPinConfig(BOARD_ACCEL_INT1_PORT, BOARD_ACCEL_INT1_PIN, &ACCEL_INT1); + + const port_pin_config_t ACCEL_SCL = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is enabled */ + kPORT_OpenDrainEnable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as I2C0_SCL */ + kPORT_MuxAlt5, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTE24 (pin 31) is configured as I2C0_SCL */ + PORT_SetPinConfig(BOARD_ACCEL_SCL_PORT, BOARD_ACCEL_SCL_PIN, &ACCEL_SCL); + + const port_pin_config_t ACCEL_SDA = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is enabled */ + kPORT_OpenDrainEnable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as I2C0_SDA */ + kPORT_MuxAlt5, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTE25 (pin 32) is configured as I2C0_SDA */ + PORT_SetPinConfig(BOARD_ACCEL_SDA_PORT, BOARD_ACCEL_SDA_PIN, &ACCEL_SDA); +} + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitENET: +- options: {callFromInitBoot: 'false', prefix: BOARD_, coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '54', peripheral: ENET, signal: RMII_MDC, pin_signal: ADC0_SE9/ADC1_SE9/PTB1/I2C0_SDA/FTM1_CH1/RMII0_MDC/MII0_MDC/FTM1_QD_PHB, slew_rate: fast, open_drain: disable, + drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} + - {pin_num: '53', peripheral: ENET, signal: RMII_MDIO, pin_signal: ADC0_SE8/ADC1_SE8/PTB0/LLWU_P5/I2C0_SCL/FTM1_CH0/RMII0_MDIO/MII0_MDIO/FTM1_QD_PHA, slew_rate: fast, + open_drain: enable, drive_strength: low, pull_select: up, pull_enable: enable, passive_filter: disable} + - {pin_num: '43', peripheral: ENET, signal: RMII_RXD0, pin_signal: CMP2_IN1/PTA13/LLWU_P4/CAN0_RX/FTM1_CH1/RMII0_RXD0/MII0_RXD0/I2C2_SDA/I2S0_TX_FS/FTM1_QD_PHB, + slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} + - {pin_num: '42', peripheral: ENET, signal: RMII_RXD1, pin_signal: CMP2_IN0/PTA12/CAN0_TX/FTM1_CH0/RMII0_RXD1/MII0_RXD1/I2C2_SCL/I2S0_TXD0/FTM1_QD_PHA, slew_rate: fast, + open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} + - {pin_num: '39', peripheral: ENET, signal: RMII_RXER, pin_signal: PTA5/USB_CLKIN/FTM0_CH2/RMII0_RXER/MII0_RXER/CMP2_OUT/I2S0_TX_BCLK/JTAG_TRST_b, slew_rate: fast, + open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} + - {pin_num: '46', peripheral: ENET, signal: RMII_TXD0, pin_signal: PTA16/SPI0_SOUT/UART0_CTS_b/UART0_COL_b/RMII0_TXD0/MII0_TXD0/I2S0_RX_FS/I2S0_RXD1, slew_rate: fast, + open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} + - {pin_num: '47', peripheral: ENET, signal: RMII_TXD1, pin_signal: ADC1_SE17/PTA17/SPI0_SIN/UART0_RTS_b/RMII0_TXD1/MII0_TXD1/I2S0_MCLK, slew_rate: fast, open_drain: disable, + drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} + - {pin_num: '45', peripheral: ENET, signal: RMII_TXEN, pin_signal: PTA15/SPI0_SCK/UART0_RX/RMII0_TXEN/MII0_TXEN/I2S0_RXD0, slew_rate: fast, open_drain: disable, + drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} + - {pin_num: '44', peripheral: ENET, signal: RMII_CRS_DV, pin_signal: PTA14/SPI0_PCS0/UART0_TX/RMII0_CRS_DV/MII0_RXDV/I2C2_SCL/I2S0_RX_BCLK/I2S0_TXD1, slew_rate: fast, + open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} + - {pin_num: '50', peripheral: ENET, signal: RMII_CLKIN, pin_signal: EXTAL0/PTA18/FTM0_FLT2/FTM_CLKIN0, identifier: RMII_RXCLK, slew_rate: fast, open_drain: disable, + drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitENET + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitENET(void) +{ + /* Port A Clock Gate Control: Clock enabled */ + CLOCK_EnableClock(kCLOCK_PortA); + /* Port B Clock Gate Control: Clock enabled */ + CLOCK_EnableClock(kCLOCK_PortB); + + const port_pin_config_t RMII0_RXD1 = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as RMII0_RXD1 */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTA12 (pin 42) is configured as RMII0_RXD1 */ + PORT_SetPinConfig(BOARD_RMII0_RXD1_PORT, BOARD_RMII0_RXD1_PIN, &RMII0_RXD1); + + const port_pin_config_t RMII0_RXD0 = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as RMII0_RXD0 */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTA13 (pin 43) is configured as RMII0_RXD0 */ + PORT_SetPinConfig(BOARD_RMII0_RXD0_PORT, BOARD_RMII0_RXD0_PIN, &RMII0_RXD0); + + const port_pin_config_t RMII0_CRS_DV = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as RMII0_CRS_DV */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTA14 (pin 44) is configured as RMII0_CRS_DV */ + PORT_SetPinConfig(BOARD_RMII0_CRS_DV_PORT, BOARD_RMII0_CRS_DV_PIN, &RMII0_CRS_DV); + + const port_pin_config_t RMII0_TXEN = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as RMII0_TXEN */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTA15 (pin 45) is configured as RMII0_TXEN */ + PORT_SetPinConfig(BOARD_RMII0_TXEN_PORT, BOARD_RMII0_TXEN_PIN, &RMII0_TXEN); + + const port_pin_config_t RMII0_TXD0 = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as RMII0_TXD0 */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTA16 (pin 46) is configured as RMII0_TXD0 */ + PORT_SetPinConfig(BOARD_RMII0_TXD0_PORT, BOARD_RMII0_TXD0_PIN, &RMII0_TXD0); + + const port_pin_config_t RMII0_TXD1 = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as RMII0_TXD1 */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTA17 (pin 47) is configured as RMII0_TXD1 */ + PORT_SetPinConfig(BOARD_RMII0_TXD1_PORT, BOARD_RMII0_TXD1_PIN, &RMII0_TXD1); + + const port_pin_config_t RMII_RXCLK = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as EXTAL0 */ + kPORT_PinDisabledOrAnalog, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTA18 (pin 50) is configured as EXTAL0 */ + PORT_SetPinConfig(BOARD_RMII_RXCLK_PORT, BOARD_RMII_RXCLK_PIN, &RMII_RXCLK); + + const port_pin_config_t RMII0_RXER = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as RMII0_RXER */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTA5 (pin 39) is configured as RMII0_RXER */ + PORT_SetPinConfig(BOARD_RMII0_RXER_PORT, BOARD_RMII0_RXER_PIN, &RMII0_RXER); + + const port_pin_config_t RMII0_MDIO = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is enabled */ + kPORT_OpenDrainEnable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as RMII0_MDIO */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTB0 (pin 53) is configured as RMII0_MDIO */ + PORT_SetPinConfig(BOARD_RMII0_MDIO_PORT, BOARD_RMII0_MDIO_PIN, &RMII0_MDIO); + + const port_pin_config_t RMII0_MDC = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as RMII0_MDC */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTB1 (pin 54) is configured as RMII0_MDC */ + PORT_SetPinConfig(BOARD_RMII0_MDC_PORT, BOARD_RMII0_MDC_PIN, &RMII0_MDC); + + SIM->SOPT2 = ((SIM->SOPT2 & + /* Mask bits to zero which are setting */ + (~(SIM_SOPT2_RMIISRC_MASK))) + + /* RMII clock source select: EXTAL clock. */ + | SIM_SOPT2_RMIISRC(SOPT2_RMIISRC_EXTAL)); +} + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitSDHC: +- options: {callFromInitBoot: 'false', prefix: BOARD_, coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '1', peripheral: SDHC, signal: 'DATA, 1', pin_signal: ADC1_SE4a/PTE0/SPI1_PCS1/UART1_TX/SDHC0_D1/TRACE_CLKOUT/I2C1_SDA/RTC_CLKOUT, slew_rate: fast, + open_drain: disable, drive_strength: high, pull_select: up, pull_enable: enable, passive_filter: disable} + - {pin_num: '2', peripheral: SDHC, signal: 'DATA, 0', pin_signal: ADC1_SE5a/PTE1/LLWU_P0/SPI1_SOUT/UART1_RX/SDHC0_D0/TRACE_D3/I2C1_SCL/SPI1_SIN, slew_rate: fast, + open_drain: disable, drive_strength: high, pull_select: up, pull_enable: enable, passive_filter: disable} + - {pin_num: '3', peripheral: SDHC, signal: DCLK, pin_signal: ADC0_DP2/ADC1_SE6a/PTE2/LLWU_P1/SPI1_SCK/UART1_CTS_b/SDHC0_DCLK/TRACE_D2, slew_rate: fast, open_drain: disable, + drive_strength: high, pull_select: up, pull_enable: enable, passive_filter: disable} + - {pin_num: '4', peripheral: SDHC, signal: CMD, pin_signal: ADC0_DM2/ADC1_SE7a/PTE3/SPI1_SIN/UART1_RTS_b/SDHC0_CMD/TRACE_D1/SPI1_SOUT, slew_rate: fast, open_drain: disable, + drive_strength: high, pull_select: up, pull_enable: enable, passive_filter: disable} + - {pin_num: '5', peripheral: SDHC, signal: 'DATA, 3', pin_signal: PTE4/LLWU_P2/SPI1_PCS0/UART3_TX/SDHC0_D3/TRACE_D0, slew_rate: fast, open_drain: disable, drive_strength: high, + pull_select: up, pull_enable: enable, passive_filter: disable} + - {pin_num: '6', peripheral: SDHC, signal: 'DATA, 2', pin_signal: PTE5/SPI1_PCS2/UART3_RX/SDHC0_D2/FTM3_CH0, slew_rate: fast, open_drain: disable, drive_strength: high, + pull_select: up, pull_enable: enable, passive_filter: disable} + - {pin_num: '7', peripheral: GPIOE, signal: 'GPIO, 6', pin_signal: PTE6/SPI1_PCS3/UART3_CTS_b/I2S0_MCLK/FTM3_CH1/USB_SOF_OUT, direction: INPUT, slew_rate: slow, + open_drain: disable, drive_strength: low, pull_select: down, pull_enable: enable, passive_filter: disable} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitSDHC + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitSDHC(void) +{ + /* Port E Clock Gate Control: Clock enabled */ + CLOCK_EnableClock(kCLOCK_PortE); + + gpio_pin_config_t SDHC_CD_config = { + .pinDirection = kGPIO_DigitalInput, + .outputLogic = 0U + }; + /* Initialize GPIO functionality on pin PTE6 (pin 7) */ + GPIO_PinInit(BOARD_SDHC_CD_GPIO, BOARD_SDHC_CD_PIN, &SDHC_CD_config); + + const port_pin_config_t SDHC0_D1 = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* High drive strength is configured */ + kPORT_HighDriveStrength, + /* Pin is configured as SDHC0_D1 */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTE0 (pin 1) is configured as SDHC0_D1 */ + PORT_SetPinConfig(BOARD_SDHC0_D1_PORT, BOARD_SDHC0_D1_PIN, &SDHC0_D1); + + const port_pin_config_t SDHC0_D0 = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* High drive strength is configured */ + kPORT_HighDriveStrength, + /* Pin is configured as SDHC0_D0 */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTE1 (pin 2) is configured as SDHC0_D0 */ + PORT_SetPinConfig(BOARD_SDHC0_D0_PORT, BOARD_SDHC0_D0_PIN, &SDHC0_D0); + + const port_pin_config_t SDHC0_DCLK = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* High drive strength is configured */ + kPORT_HighDriveStrength, + /* Pin is configured as SDHC0_DCLK */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTE2 (pin 3) is configured as SDHC0_DCLK */ + PORT_SetPinConfig(BOARD_SDHC0_DCLK_PORT, BOARD_SDHC0_DCLK_PIN, &SDHC0_DCLK); + + const port_pin_config_t SDHC0_CMD = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* High drive strength is configured */ + kPORT_HighDriveStrength, + /* Pin is configured as SDHC0_CMD */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTE3 (pin 4) is configured as SDHC0_CMD */ + PORT_SetPinConfig(BOARD_SDHC0_CMD_PORT, BOARD_SDHC0_CMD_PIN, &SDHC0_CMD); + + const port_pin_config_t SDHC0_D3 = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* High drive strength is configured */ + kPORT_HighDriveStrength, + /* Pin is configured as SDHC0_D3 */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTE4 (pin 5) is configured as SDHC0_D3 */ + PORT_SetPinConfig(BOARD_SDHC0_D3_PORT, BOARD_SDHC0_D3_PIN, &SDHC0_D3); + + const port_pin_config_t SDHC0_D2 = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* High drive strength is configured */ + kPORT_HighDriveStrength, + /* Pin is configured as SDHC0_D2 */ + kPORT_MuxAlt4, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTE5 (pin 6) is configured as SDHC0_D2 */ + PORT_SetPinConfig(BOARD_SDHC0_D2_PORT, BOARD_SDHC0_D2_PIN, &SDHC0_D2); + + const port_pin_config_t SDHC_CD = {/* Internal pull-down resistor is enabled */ + kPORT_PullDown, + /* Slow slew rate is configured */ + kPORT_SlowSlewRate, + /* Passive filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as PTE6 */ + kPORT_MuxAsGpio, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORTE6 (pin 7) is configured as PTE6 */ + PORT_SetPinConfig(BOARD_SDHC_CD_PORT, BOARD_SDHC_CD_PIN, &SDHC_CD); +} + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitUSB: +- options: {callFromInitBoot: 'false', prefix: BOARD_, coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '10', peripheral: USB0, signal: DP, pin_signal: USB0_DP} + - {pin_num: '11', peripheral: USB0, signal: DM, pin_signal: USB0_DM} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitUSB + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitUSB(void) +{ +} +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/kinetis_k/boards/frdm_k64f/board/pin_mux.h b/hw/bsp/kinetis_k/boards/frdm_k64f/board/pin_mux.h new file mode 100644 index 000000000..6d64832ba --- /dev/null +++ b/hw/bsp/kinetis_k/boards/frdm_k64f/board/pin_mux.h @@ -0,0 +1,645 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _PIN_MUX_H_ +#define _PIN_MUX_H_ + +/*********************************************************************************************************************** + * Definitions + **********************************************************************************************************************/ + +/*! @brief Direction type */ +typedef enum _pin_mux_direction +{ + kPIN_MUX_DirectionInput = 0U, /* Input direction */ + kPIN_MUX_DirectionOutput = 1U, /* Output direction */ + kPIN_MUX_DirectionInputOrOutput = 2U /* Input or output direction */ +} pin_mux_direction_t; + +/*! + * @addtogroup pin_mux + * @{ + */ + +/*********************************************************************************************************************** + * API + **********************************************************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Calls initialization functions. + * + */ +void BOARD_InitBootPins(void); + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitPins(void); + +/*! @name PORTC6 (number 78), U8[11]/SW2 + @{ */ +/* Routed pin properties */ +#define BOARD_SW2_PERIPHERAL GPIOC /*!<@brief Peripheral name */ +#define BOARD_SW2_SIGNAL GPIO /*!<@brief Signal name */ +#define BOARD_SW2_CHANNEL 6 /*!<@brief Signal channel */ +#define BOARD_SW2_PIN_NAME PTC6 /*!<@brief Routed pin name */ +#define BOARD_SW2_LABEL "U8[11]/SW2" /*!<@brief Label */ +#define BOARD_SW2_NAME "SW2" /*!<@brief Identifier */ +#define BOARD_SW2_DIRECTION kPIN_MUX_DirectionInput /*!<@brief Direction */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_SW2_GPIO GPIOC /*!<@brief GPIO peripheral base pointer */ +#define BOARD_SW2_GPIO_PIN 6U /*!<@brief GPIO pin number */ +#define BOARD_SW2_GPIO_PIN_MASK (1U << 6U) /*!<@brief GPIO pin mask */ + +/* Symbols to be used with PORT driver */ +#define BOARD_SW2_PORT PORTC /*!<@brief PORT peripheral base pointer */ +#define BOARD_SW2_PIN 6U /*!<@brief PORT pin number */ +#define BOARD_SW2_PIN_MASK (1U << 6U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTA4 (number 38), SW3 + @{ */ +/* Routed pin properties */ +#define BOARD_SW3_PERIPHERAL GPIOA /*!<@brief Peripheral name */ +#define BOARD_SW3_SIGNAL GPIO /*!<@brief Signal name */ +#define BOARD_SW3_CHANNEL 4 /*!<@brief Signal channel */ +#define BOARD_SW3_PIN_NAME PTA4 /*!<@brief Routed pin name */ +#define BOARD_SW3_LABEL "SW3" /*!<@brief Label */ +#define BOARD_SW3_NAME "SW3" /*!<@brief Identifier */ +#define BOARD_SW3_DIRECTION kPIN_MUX_DirectionInput /*!<@brief Direction */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_SW3_GPIO GPIOA /*!<@brief GPIO peripheral base pointer */ +#define BOARD_SW3_GPIO_PIN 4U /*!<@brief GPIO pin number */ +#define BOARD_SW3_GPIO_PIN_MASK (1U << 4U) /*!<@brief GPIO pin mask */ + +/* Symbols to be used with PORT driver */ +#define BOARD_SW3_PORT PORTA /*!<@brief PORT peripheral base pointer */ +#define BOARD_SW3_PIN 4U /*!<@brief PORT pin number */ +#define BOARD_SW3_PIN_MASK (1U << 4U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitButtons(void); + +/*! @name PORTB21 (number 67), D12[3]/LEDRGB_BLUE + @{ */ +/* Routed pin properties */ +#define BOARD_LED_BLUE_PERIPHERAL GPIOB /*!<@brief Peripheral name */ +#define BOARD_LED_BLUE_SIGNAL GPIO /*!<@brief Signal name */ +#define BOARD_LED_BLUE_CHANNEL 21 /*!<@brief Signal channel */ +#define BOARD_LED_BLUE_PIN_NAME PTB21 /*!<@brief Routed pin name */ +#define BOARD_LED_BLUE_LABEL "D12[3]/LEDRGB_BLUE" /*!<@brief Label */ +#define BOARD_LED_BLUE_NAME "LED_BLUE" /*!<@brief Identifier */ +#define BOARD_LED_BLUE_DIRECTION kPIN_MUX_DirectionOutput /*!<@brief Direction */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_LED_BLUE_GPIO GPIOB /*!<@brief GPIO peripheral base pointer */ +#define BOARD_LED_BLUE_GPIO_PIN 21U /*!<@brief GPIO pin number */ +#define BOARD_LED_BLUE_GPIO_PIN_MASK (1U << 21U) /*!<@brief GPIO pin mask */ + +/* Symbols to be used with PORT driver */ +#define BOARD_LED_BLUE_PORT PORTB /*!<@brief PORT peripheral base pointer */ +#define BOARD_LED_BLUE_PIN 21U /*!<@brief PORT pin number */ +#define BOARD_LED_BLUE_PIN_MASK (1U << 21U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTB22 (number 68), D12[1]/LEDRGB_RED + @{ */ +/* Routed pin properties */ +#define BOARD_LED_RED_PERIPHERAL GPIOB /*!<@brief Peripheral name */ +#define BOARD_LED_RED_SIGNAL GPIO /*!<@brief Signal name */ +#define BOARD_LED_RED_CHANNEL 22 /*!<@brief Signal channel */ +#define BOARD_LED_RED_PIN_NAME PTB22 /*!<@brief Routed pin name */ +#define BOARD_LED_RED_LABEL "D12[1]/LEDRGB_RED" /*!<@brief Label */ +#define BOARD_LED_RED_NAME "LED_RED" /*!<@brief Identifier */ +#define BOARD_LED_RED_DIRECTION kPIN_MUX_DirectionOutput /*!<@brief Direction */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_LED_RED_GPIO GPIOB /*!<@brief GPIO peripheral base pointer */ +#define BOARD_LED_RED_GPIO_PIN 22U /*!<@brief GPIO pin number */ +#define BOARD_LED_RED_GPIO_PIN_MASK (1U << 22U) /*!<@brief GPIO pin mask */ + +/* Symbols to be used with PORT driver */ +#define BOARD_LED_RED_PORT PORTB /*!<@brief PORT peripheral base pointer */ +#define BOARD_LED_RED_PIN 22U /*!<@brief PORT pin number */ +#define BOARD_LED_RED_PIN_MASK (1U << 22U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTE26 (number 33), J2[1]/D12[4]/LEDRGB_GREEN + @{ */ +/* Routed pin properties */ +#define BOARD_LED_GREEN_PERIPHERAL GPIOE /*!<@brief Peripheral name */ +#define BOARD_LED_GREEN_SIGNAL GPIO /*!<@brief Signal name */ +#define BOARD_LED_GREEN_CHANNEL 26 /*!<@brief Signal channel */ +#define BOARD_LED_GREEN_PIN_NAME PTE26 /*!<@brief Routed pin name */ +#define BOARD_LED_GREEN_LABEL "J2[1]/D12[4]/LEDRGB_GREEN" /*!<@brief Label */ +#define BOARD_LED_GREEN_NAME "LED_GREEN" /*!<@brief Identifier */ +#define BOARD_LED_GREEN_DIRECTION kPIN_MUX_DirectionOutput /*!<@brief Direction */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_LED_GREEN_GPIO GPIOE /*!<@brief GPIO peripheral base pointer */ +#define BOARD_LED_GREEN_GPIO_PIN 26U /*!<@brief GPIO pin number */ +#define BOARD_LED_GREEN_GPIO_PIN_MASK (1U << 26U) /*!<@brief GPIO pin mask */ + +/* Symbols to be used with PORT driver */ +#define BOARD_LED_GREEN_PORT PORTE /*!<@brief PORT peripheral base pointer */ +#define BOARD_LED_GREEN_PIN 26U /*!<@brief PORT pin number */ +#define BOARD_LED_GREEN_PIN_MASK (1U << 26U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitLEDs(void); + +#define SOPT5_UART0TXSRC_UART_TX 0x00u /*!<@brief UART 0 transmit data source select: UART0_TX pin */ + +/*! @name PORTB17 (number 63), U10[1]/UART0_TX + @{ */ +/* Routed pin properties */ +#define BOARD_DEBUG_UART_TX_PERIPHERAL UART0 /*!<@brief Peripheral name */ +#define BOARD_DEBUG_UART_TX_SIGNAL TX /*!<@brief Signal name */ +#define BOARD_DEBUG_UART_TX_PIN_NAME UART0_TX /*!<@brief Routed pin name */ +#define BOARD_DEBUG_UART_TX_LABEL "U10[1]/UART0_TX" /*!<@brief Label */ +#define BOARD_DEBUG_UART_TX_NAME "DEBUG_UART_TX" /*!<@brief Identifier */ +#define BOARD_DEBUG_UART_TX_DIRECTION kPIN_MUX_DirectionOutput /*!<@brief Direction */ + +/* Symbols to be used with PORT driver */ +#define BOARD_DEBUG_UART_TX_PORT PORTB /*!<@brief PORT peripheral base pointer */ +#define BOARD_DEBUG_UART_TX_PIN 17U /*!<@brief PORT pin number */ +#define BOARD_DEBUG_UART_TX_PIN_MASK (1U << 17U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTB16 (number 62), U7[4]/UART0_RX + @{ */ +/* Routed pin properties */ +#define BOARD_DEBUG_UART_RX_PERIPHERAL UART0 /*!<@brief Peripheral name */ +#define BOARD_DEBUG_UART_RX_SIGNAL RX /*!<@brief Signal name */ +#define BOARD_DEBUG_UART_RX_PIN_NAME UART0_RX /*!<@brief Routed pin name */ +#define BOARD_DEBUG_UART_RX_LABEL "U7[4]/UART0_RX" /*!<@brief Label */ +#define BOARD_DEBUG_UART_RX_NAME "DEBUG_UART_RX" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_DEBUG_UART_RX_PORT PORTB /*!<@brief PORT peripheral base pointer */ +#define BOARD_DEBUG_UART_RX_PIN 16U /*!<@brief PORT pin number */ +#define BOARD_DEBUG_UART_RX_PIN_MASK (1U << 16U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitDEBUG_UART(void); + +/*! @name PORTA18 (number 50), U13[16]/RMII_RXCLK + @{ */ +/* Routed pin properties */ +#define BOARD_EXTAL0_PERIPHERAL OSC /*!<@brief Peripheral name */ +#define BOARD_EXTAL0_SIGNAL EXTAL0 /*!<@brief Signal name */ +#define BOARD_EXTAL0_PIN_NAME EXTAL0 /*!<@brief Routed pin name */ +#define BOARD_EXTAL0_LABEL "U13[16]/RMII_RXCLK" /*!<@brief Label */ +#define BOARD_EXTAL0_NAME "EXTAL0" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_EXTAL0_PORT PORTA /*!<@brief PORT peripheral base pointer */ +#define BOARD_EXTAL0_PIN 18U /*!<@brief PORT pin number */ +#define BOARD_EXTAL0_PIN_MASK (1U << 18U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name EXTAL32 (number 29), Y3[2]/EXTAL32_RTC + @{ */ +/* Routed pin properties */ +#define BOARD_ETAL32K_PERIPHERAL RTC /*!<@brief Peripheral name */ +#define BOARD_ETAL32K_SIGNAL EXTAL32 /*!<@brief Signal name */ +#define BOARD_ETAL32K_PIN_NAME EXTAL32 /*!<@brief Routed pin name */ +#define BOARD_ETAL32K_LABEL "Y3[2]/EXTAL32_RTC" /*!<@brief Label */ +#define BOARD_ETAL32K_NAME "ETAL32K" /*!<@brief Identifier */ + /* @} */ + +/*! @name XTAL32 (number 28), Y3[1]/XTAL32_RTC + @{ */ +/* Routed pin properties */ +#define BOARD_XTAL32K_PERIPHERAL RTC /*!<@brief Peripheral name */ +#define BOARD_XTAL32K_SIGNAL XTAL32 /*!<@brief Signal name */ +#define BOARD_XTAL32K_PIN_NAME XTAL32 /*!<@brief Routed pin name */ +#define BOARD_XTAL32K_LABEL "Y3[1]/XTAL32_RTC" /*!<@brief Label */ +#define BOARD_XTAL32K_NAME "XTAL32K" /*!<@brief Identifier */ + /* @} */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitOSC(void); + +/*! @name PORTE25 (number 32), J2[18]/U8[6]/I2C0_SDA + @{ */ +/* Routed pin properties */ +#define BOARD_ACCEL_SDA_PERIPHERAL I2C0 /*!<@brief Peripheral name */ +#define BOARD_ACCEL_SDA_SIGNAL SDA /*!<@brief Signal name */ +#define BOARD_ACCEL_SDA_PIN_NAME I2C0_SDA /*!<@brief Routed pin name */ +#define BOARD_ACCEL_SDA_LABEL "J2[18]/U8[6]/I2C0_SDA" /*!<@brief Label */ +#define BOARD_ACCEL_SDA_NAME "ACCEL_SDA" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_ACCEL_SDA_PORT PORTE /*!<@brief PORT peripheral base pointer */ +#define BOARD_ACCEL_SDA_PIN 25U /*!<@brief PORT pin number */ +#define BOARD_ACCEL_SDA_PIN_MASK (1U << 25U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTE24 (number 31), J2[20]/U8[4]/I2C0_SCL + @{ */ +/* Routed pin properties */ +#define BOARD_ACCEL_SCL_PERIPHERAL I2C0 /*!<@brief Peripheral name */ +#define BOARD_ACCEL_SCL_SIGNAL SCL /*!<@brief Signal name */ +#define BOARD_ACCEL_SCL_PIN_NAME I2C0_SCL /*!<@brief Routed pin name */ +#define BOARD_ACCEL_SCL_LABEL "J2[20]/U8[4]/I2C0_SCL" /*!<@brief Label */ +#define BOARD_ACCEL_SCL_NAME "ACCEL_SCL" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_ACCEL_SCL_PORT PORTE /*!<@brief PORT peripheral base pointer */ +#define BOARD_ACCEL_SCL_PIN 24U /*!<@brief PORT pin number */ +#define BOARD_ACCEL_SCL_PIN_MASK (1U << 24U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTC6 (number 78), U8[11]/SW2 + @{ */ +/* Routed pin properties */ +#define BOARD_ACCEL_INT1_PERIPHERAL GPIOC /*!<@brief Peripheral name */ +#define BOARD_ACCEL_INT1_SIGNAL GPIO /*!<@brief Signal name */ +#define BOARD_ACCEL_INT1_CHANNEL 6 /*!<@brief Signal channel */ +#define BOARD_ACCEL_INT1_PIN_NAME PTC6 /*!<@brief Routed pin name */ +#define BOARD_ACCEL_INT1_LABEL "U8[11]/SW2" /*!<@brief Label */ +#define BOARD_ACCEL_INT1_NAME "ACCEL_INT1" /*!<@brief Identifier */ +#define BOARD_ACCEL_INT1_DIRECTION kPIN_MUX_DirectionInput /*!<@brief Direction */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_ACCEL_INT1_GPIO GPIOC /*!<@brief GPIO peripheral base pointer */ +#define BOARD_ACCEL_INT1_GPIO_PIN 6U /*!<@brief GPIO pin number */ +#define BOARD_ACCEL_INT1_GPIO_PIN_MASK (1U << 6U) /*!<@brief GPIO pin mask */ + +/* Symbols to be used with PORT driver */ +#define BOARD_ACCEL_INT1_PORT PORTC /*!<@brief PORT peripheral base pointer */ +#define BOARD_ACCEL_INT1_PIN 6U /*!<@brief PORT pin number */ +#define BOARD_ACCEL_INT1_PIN_MASK (1U << 6U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTC13 (number 85), U8[9] + @{ */ +/* Routed pin properties */ +#define BOARD_ACCEL_INT2_PERIPHERAL GPIOC /*!<@brief Peripheral name */ +#define BOARD_ACCEL_INT2_SIGNAL GPIO /*!<@brief Signal name */ +#define BOARD_ACCEL_INT2_CHANNEL 13 /*!<@brief Signal channel */ +#define BOARD_ACCEL_INT2_PIN_NAME PTC13 /*!<@brief Routed pin name */ +#define BOARD_ACCEL_INT2_LABEL "U8[9]" /*!<@brief Label */ +#define BOARD_ACCEL_INT2_NAME "ACCEL_INT2" /*!<@brief Identifier */ +#define BOARD_ACCEL_INT2_DIRECTION kPIN_MUX_DirectionInput /*!<@brief Direction */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_ACCEL_INT2_GPIO GPIOC /*!<@brief GPIO peripheral base pointer */ +#define BOARD_ACCEL_INT2_GPIO_PIN 13U /*!<@brief GPIO pin number */ +#define BOARD_ACCEL_INT2_GPIO_PIN_MASK (1U << 13U) /*!<@brief GPIO pin mask */ + +/* Symbols to be used with PORT driver */ +#define BOARD_ACCEL_INT2_PORT PORTC /*!<@brief PORT peripheral base pointer */ +#define BOARD_ACCEL_INT2_PIN 13U /*!<@brief PORT pin number */ +#define BOARD_ACCEL_INT2_PIN_MASK (1U << 13U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitACCEL(void); + +#define SOPT2_RMIISRC_EXTAL 0x00u /*!<@brief RMII clock source select: EXTAL clock */ + +/*! @name PORTB1 (number 54), U13[11]/RMII0_MDC + @{ */ +/* Routed pin properties */ +#define BOARD_RMII0_MDC_PERIPHERAL ENET /*!<@brief Peripheral name */ +#define BOARD_RMII0_MDC_SIGNAL RMII_MDC /*!<@brief Signal name */ +#define BOARD_RMII0_MDC_PIN_NAME RMII0_MDC /*!<@brief Routed pin name */ +#define BOARD_RMII0_MDC_LABEL "U13[11]/RMII0_MDC" /*!<@brief Label */ +#define BOARD_RMII0_MDC_NAME "RMII0_MDC" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_RMII0_MDC_PORT PORTB /*!<@brief PORT peripheral base pointer */ +#define BOARD_RMII0_MDC_PIN 1U /*!<@brief PORT pin number */ +#define BOARD_RMII0_MDC_PIN_MASK (1U << 1U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTB0 (number 53), U13[10]/RMII0_MDIO + @{ */ +/* Routed pin properties */ +#define BOARD_RMII0_MDIO_PERIPHERAL ENET /*!<@brief Peripheral name */ +#define BOARD_RMII0_MDIO_SIGNAL RMII_MDIO /*!<@brief Signal name */ +#define BOARD_RMII0_MDIO_PIN_NAME RMII0_MDIO /*!<@brief Routed pin name */ +#define BOARD_RMII0_MDIO_LABEL "U13[10]/RMII0_MDIO" /*!<@brief Label */ +#define BOARD_RMII0_MDIO_NAME "RMII0_MDIO" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_RMII0_MDIO_PORT PORTB /*!<@brief PORT peripheral base pointer */ +#define BOARD_RMII0_MDIO_PIN 0U /*!<@brief PORT pin number */ +#define BOARD_RMII0_MDIO_PIN_MASK (1U << 0U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTA13 (number 43), U13[13]/RMII0_RXD_0 + @{ */ +/* Routed pin properties */ +#define BOARD_RMII0_RXD0_PERIPHERAL ENET /*!<@brief Peripheral name */ +#define BOARD_RMII0_RXD0_SIGNAL RMII_RXD0 /*!<@brief Signal name */ +#define BOARD_RMII0_RXD0_PIN_NAME RMII0_RXD0 /*!<@brief Routed pin name */ +#define BOARD_RMII0_RXD0_LABEL "U13[13]/RMII0_RXD_0" /*!<@brief Label */ +#define BOARD_RMII0_RXD0_NAME "RMII0_RXD0" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_RMII0_RXD0_PORT PORTA /*!<@brief PORT peripheral base pointer */ +#define BOARD_RMII0_RXD0_PIN 13U /*!<@brief PORT pin number */ +#define BOARD_RMII0_RXD0_PIN_MASK (1U << 13U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTA12 (number 42), U13[12]/RMII0_RXD_1 + @{ */ +/* Routed pin properties */ +#define BOARD_RMII0_RXD1_PERIPHERAL ENET /*!<@brief Peripheral name */ +#define BOARD_RMII0_RXD1_SIGNAL RMII_RXD1 /*!<@brief Signal name */ +#define BOARD_RMII0_RXD1_PIN_NAME RMII0_RXD1 /*!<@brief Routed pin name */ +#define BOARD_RMII0_RXD1_LABEL "U13[12]/RMII0_RXD_1" /*!<@brief Label */ +#define BOARD_RMII0_RXD1_NAME "RMII0_RXD1" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_RMII0_RXD1_PORT PORTA /*!<@brief PORT peripheral base pointer */ +#define BOARD_RMII0_RXD1_PIN 12U /*!<@brief PORT pin number */ +#define BOARD_RMII0_RXD1_PIN_MASK (1U << 12U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTA5 (number 39), U13[17]/RMII0_RXER + @{ */ +/* Routed pin properties */ +#define BOARD_RMII0_RXER_PERIPHERAL ENET /*!<@brief Peripheral name */ +#define BOARD_RMII0_RXER_SIGNAL RMII_RXER /*!<@brief Signal name */ +#define BOARD_RMII0_RXER_PIN_NAME RMII0_RXER /*!<@brief Routed pin name */ +#define BOARD_RMII0_RXER_LABEL "U13[17]/RMII0_RXER" /*!<@brief Label */ +#define BOARD_RMII0_RXER_NAME "RMII0_RXER" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_RMII0_RXER_PORT PORTA /*!<@brief PORT peripheral base pointer */ +#define BOARD_RMII0_RXER_PIN 5U /*!<@brief PORT pin number */ +#define BOARD_RMII0_RXER_PIN_MASK (1U << 5U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTA16 (number 46), U13[20]/RMII0_TXD0 + @{ */ +/* Routed pin properties */ +#define BOARD_RMII0_TXD0_PERIPHERAL ENET /*!<@brief Peripheral name */ +#define BOARD_RMII0_TXD0_SIGNAL RMII_TXD0 /*!<@brief Signal name */ +#define BOARD_RMII0_TXD0_PIN_NAME RMII0_TXD0 /*!<@brief Routed pin name */ +#define BOARD_RMII0_TXD0_LABEL "U13[20]/RMII0_TXD0" /*!<@brief Label */ +#define BOARD_RMII0_TXD0_NAME "RMII0_TXD0" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_RMII0_TXD0_PORT PORTA /*!<@brief PORT peripheral base pointer */ +#define BOARD_RMII0_TXD0_PIN 16U /*!<@brief PORT pin number */ +#define BOARD_RMII0_TXD0_PIN_MASK (1U << 16U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTA17 (number 47), U13[21]/RMII0_TXD1 + @{ */ +/* Routed pin properties */ +#define BOARD_RMII0_TXD1_PERIPHERAL ENET /*!<@brief Peripheral name */ +#define BOARD_RMII0_TXD1_SIGNAL RMII_TXD1 /*!<@brief Signal name */ +#define BOARD_RMII0_TXD1_PIN_NAME RMII0_TXD1 /*!<@brief Routed pin name */ +#define BOARD_RMII0_TXD1_LABEL "U13[21]/RMII0_TXD1" /*!<@brief Label */ +#define BOARD_RMII0_TXD1_NAME "RMII0_TXD1" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_RMII0_TXD1_PORT PORTA /*!<@brief PORT peripheral base pointer */ +#define BOARD_RMII0_TXD1_PIN 17U /*!<@brief PORT pin number */ +#define BOARD_RMII0_TXD1_PIN_MASK (1U << 17U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTA15 (number 45), U13[19]/RMII0_TXEN + @{ */ +/* Routed pin properties */ +#define BOARD_RMII0_TXEN_PERIPHERAL ENET /*!<@brief Peripheral name */ +#define BOARD_RMII0_TXEN_SIGNAL RMII_TXEN /*!<@brief Signal name */ +#define BOARD_RMII0_TXEN_PIN_NAME RMII0_TXEN /*!<@brief Routed pin name */ +#define BOARD_RMII0_TXEN_LABEL "U13[19]/RMII0_TXEN" /*!<@brief Label */ +#define BOARD_RMII0_TXEN_NAME "RMII0_TXEN" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_RMII0_TXEN_PORT PORTA /*!<@brief PORT peripheral base pointer */ +#define BOARD_RMII0_TXEN_PIN 15U /*!<@brief PORT pin number */ +#define BOARD_RMII0_TXEN_PIN_MASK (1U << 15U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTA14 (number 44), U13[15]/RMII0_CRS_DV + @{ */ +/* Routed pin properties */ +#define BOARD_RMII0_CRS_DV_PERIPHERAL ENET /*!<@brief Peripheral name */ +#define BOARD_RMII0_CRS_DV_SIGNAL RMII_CRS_DV /*!<@brief Signal name */ +#define BOARD_RMII0_CRS_DV_PIN_NAME RMII0_CRS_DV /*!<@brief Routed pin name */ +#define BOARD_RMII0_CRS_DV_LABEL "U13[15]/RMII0_CRS_DV" /*!<@brief Label */ +#define BOARD_RMII0_CRS_DV_NAME "RMII0_CRS_DV" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_RMII0_CRS_DV_PORT PORTA /*!<@brief PORT peripheral base pointer */ +#define BOARD_RMII0_CRS_DV_PIN 14U /*!<@brief PORT pin number */ +#define BOARD_RMII0_CRS_DV_PIN_MASK (1U << 14U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTA18 (number 50), U13[16]/RMII_RXCLK + @{ */ +/* Routed pin properties */ +#define BOARD_RMII_RXCLK_PERIPHERAL ENET /*!<@brief Peripheral name */ +#define BOARD_RMII_RXCLK_SIGNAL RMII_CLKIN /*!<@brief Signal name */ +#define BOARD_RMII_RXCLK_PIN_NAME EXTAL0 /*!<@brief Routed pin name */ +#define BOARD_RMII_RXCLK_LABEL "U13[16]/RMII_RXCLK" /*!<@brief Label */ +#define BOARD_RMII_RXCLK_NAME "RMII_RXCLK" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_RMII_RXCLK_PORT PORTA /*!<@brief PORT peripheral base pointer */ +#define BOARD_RMII_RXCLK_PIN 18U /*!<@brief PORT pin number */ +#define BOARD_RMII_RXCLK_PIN_MASK (1U << 18U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitENET(void); + +/*! @name PORTE0 (number 1), J15[P8]/SDHC0_D1 + @{ */ +/* Routed pin properties */ +#define BOARD_SDHC0_D1_PERIPHERAL SDHC /*!<@brief Peripheral name */ +#define BOARD_SDHC0_D1_SIGNAL DATA /*!<@brief Signal name */ +#define BOARD_SDHC0_D1_CHANNEL 1 /*!<@brief Signal channel */ +#define BOARD_SDHC0_D1_PIN_NAME SDHC0_D1 /*!<@brief Routed pin name */ +#define BOARD_SDHC0_D1_LABEL "J15[P8]/SDHC0_D1" /*!<@brief Label */ +#define BOARD_SDHC0_D1_NAME "SDHC0_D1" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_SDHC0_D1_PORT PORTE /*!<@brief PORT peripheral base pointer */ +#define BOARD_SDHC0_D1_PIN 0U /*!<@brief PORT pin number */ +#define BOARD_SDHC0_D1_PIN_MASK (1U << 0U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTE1 (number 2), J15[P7]/SDHC0_D0 + @{ */ +/* Routed pin properties */ +#define BOARD_SDHC0_D0_PERIPHERAL SDHC /*!<@brief Peripheral name */ +#define BOARD_SDHC0_D0_SIGNAL DATA /*!<@brief Signal name */ +#define BOARD_SDHC0_D0_CHANNEL 0 /*!<@brief Signal channel */ +#define BOARD_SDHC0_D0_PIN_NAME SDHC0_D0 /*!<@brief Routed pin name */ +#define BOARD_SDHC0_D0_LABEL "J15[P7]/SDHC0_D0" /*!<@brief Label */ +#define BOARD_SDHC0_D0_NAME "SDHC0_D0" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_SDHC0_D0_PORT PORTE /*!<@brief PORT peripheral base pointer */ +#define BOARD_SDHC0_D0_PIN 1U /*!<@brief PORT pin number */ +#define BOARD_SDHC0_D0_PIN_MASK (1U << 1U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTE2 (number 3), J15[P5]/SDHC0_DCLK + @{ */ +/* Routed pin properties */ +#define BOARD_SDHC0_DCLK_PERIPHERAL SDHC /*!<@brief Peripheral name */ +#define BOARD_SDHC0_DCLK_SIGNAL DCLK /*!<@brief Signal name */ +#define BOARD_SDHC0_DCLK_PIN_NAME SDHC0_DCLK /*!<@brief Routed pin name */ +#define BOARD_SDHC0_DCLK_LABEL "J15[P5]/SDHC0_DCLK" /*!<@brief Label */ +#define BOARD_SDHC0_DCLK_NAME "SDHC0_DCLK" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_SDHC0_DCLK_PORT PORTE /*!<@brief PORT peripheral base pointer */ +#define BOARD_SDHC0_DCLK_PIN 2U /*!<@brief PORT pin number */ +#define BOARD_SDHC0_DCLK_PIN_MASK (1U << 2U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTE3 (number 4), J15[P3]/SDHC0_CMD + @{ */ +/* Routed pin properties */ +#define BOARD_SDHC0_CMD_PERIPHERAL SDHC /*!<@brief Peripheral name */ +#define BOARD_SDHC0_CMD_SIGNAL CMD /*!<@brief Signal name */ +#define BOARD_SDHC0_CMD_PIN_NAME SDHC0_CMD /*!<@brief Routed pin name */ +#define BOARD_SDHC0_CMD_LABEL "J15[P3]/SDHC0_CMD" /*!<@brief Label */ +#define BOARD_SDHC0_CMD_NAME "SDHC0_CMD" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_SDHC0_CMD_PORT PORTE /*!<@brief PORT peripheral base pointer */ +#define BOARD_SDHC0_CMD_PIN 3U /*!<@brief PORT pin number */ +#define BOARD_SDHC0_CMD_PIN_MASK (1U << 3U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTE4 (number 5), J15[P2]/SDHC0_D3 + @{ */ +/* Routed pin properties */ +#define BOARD_SDHC0_D3_PERIPHERAL SDHC /*!<@brief Peripheral name */ +#define BOARD_SDHC0_D3_SIGNAL DATA /*!<@brief Signal name */ +#define BOARD_SDHC0_D3_CHANNEL 3 /*!<@brief Signal channel */ +#define BOARD_SDHC0_D3_PIN_NAME SDHC0_D3 /*!<@brief Routed pin name */ +#define BOARD_SDHC0_D3_LABEL "J15[P2]/SDHC0_D3" /*!<@brief Label */ +#define BOARD_SDHC0_D3_NAME "SDHC0_D3" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_SDHC0_D3_PORT PORTE /*!<@brief PORT peripheral base pointer */ +#define BOARD_SDHC0_D3_PIN 4U /*!<@brief PORT pin number */ +#define BOARD_SDHC0_D3_PIN_MASK (1U << 4U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTE5 (number 6), J15[P1]/SDHC0_D2 + @{ */ +/* Routed pin properties */ +#define BOARD_SDHC0_D2_PERIPHERAL SDHC /*!<@brief Peripheral name */ +#define BOARD_SDHC0_D2_SIGNAL DATA /*!<@brief Signal name */ +#define BOARD_SDHC0_D2_CHANNEL 2 /*!<@brief Signal channel */ +#define BOARD_SDHC0_D2_PIN_NAME SDHC0_D2 /*!<@brief Routed pin name */ +#define BOARD_SDHC0_D2_LABEL "J15[P1]/SDHC0_D2" /*!<@brief Label */ +#define BOARD_SDHC0_D2_NAME "SDHC0_D2" /*!<@brief Identifier */ + +/* Symbols to be used with PORT driver */ +#define BOARD_SDHC0_D2_PORT PORTE /*!<@brief PORT peripheral base pointer */ +#define BOARD_SDHC0_D2_PIN 5U /*!<@brief PORT pin number */ +#define BOARD_SDHC0_D2_PIN_MASK (1U << 5U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! @name PORTE6 (number 7), J15[G1]/SD_CARD_DETECT + @{ */ +/* Routed pin properties */ +#define BOARD_SDHC_CD_PERIPHERAL GPIOE /*!<@brief Peripheral name */ +#define BOARD_SDHC_CD_SIGNAL GPIO /*!<@brief Signal name */ +#define BOARD_SDHC_CD_CHANNEL 6 /*!<@brief Signal channel */ +#define BOARD_SDHC_CD_PIN_NAME PTE6 /*!<@brief Routed pin name */ +#define BOARD_SDHC_CD_LABEL "J15[G1]/SD_CARD_DETECT" /*!<@brief Label */ +#define BOARD_SDHC_CD_NAME "SDHC_CD" /*!<@brief Identifier */ +#define BOARD_SDHC_CD_DIRECTION kPIN_MUX_DirectionInput /*!<@brief Direction */ + +/* Symbols to be used with GPIO driver */ +#define BOARD_SDHC_CD_GPIO GPIOE /*!<@brief GPIO peripheral base pointer */ +#define BOARD_SDHC_CD_GPIO_PIN 6U /*!<@brief GPIO pin number */ +#define BOARD_SDHC_CD_GPIO_PIN_MASK (1U << 6U) /*!<@brief GPIO pin mask */ + +/* Symbols to be used with PORT driver */ +#define BOARD_SDHC_CD_PORT PORTE /*!<@brief PORT peripheral base pointer */ +#define BOARD_SDHC_CD_PIN 6U /*!<@brief PORT pin number */ +#define BOARD_SDHC_CD_PIN_MASK (1U << 6U) /*!<@brief PORT pin mask */ + /* @} */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitSDHC(void); + +/*! @name USB0_DP (number 10), J22[3]/K64_MICRO_USB_DP + @{ */ +/* Routed pin properties */ +#define BOARD_USB_DP_PERIPHERAL USB0 /*!<@brief Peripheral name */ +#define BOARD_USB_DP_SIGNAL DP /*!<@brief Signal name */ +#define BOARD_USB_DP_PIN_NAME USB0_DP /*!<@brief Routed pin name */ +#define BOARD_USB_DP_LABEL "J22[3]/K64_MICRO_USB_DP" /*!<@brief Label */ +#define BOARD_USB_DP_NAME "USB_DP" /*!<@brief Identifier */ + /* @} */ + +/*! @name USB0_DM (number 11), J22[2]/K64_MICRO_USB_DN + @{ */ +/* Routed pin properties */ +#define BOARD_USB_DM_PERIPHERAL USB0 /*!<@brief Peripheral name */ +#define BOARD_USB_DM_SIGNAL DM /*!<@brief Signal name */ +#define BOARD_USB_DM_PIN_NAME USB0_DM /*!<@brief Routed pin name */ +#define BOARD_USB_DM_LABEL "J22[2]/K64_MICRO_USB_DN" /*!<@brief Label */ +#define BOARD_USB_DM_NAME "USB_DM" /*!<@brief Identifier */ + /* @} */ + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitUSB(void); + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif /* _PIN_MUX_H_ */ + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/kinetis_k/boards/frdm_k64f/frdm_k64f.mex b/hw/bsp/kinetis_k/boards/frdm_k64f/frdm_k64f.mex new file mode 100644 index 000000000..4a8c77f95 --- /dev/null +++ b/hw/bsp/kinetis_k/boards/frdm_k64f/frdm_k64f.mex @@ -0,0 +1,950 @@ + + + + MK64FN1M0xxx12 + MK64FN1M0VLL12 + FRDM-K64F + E1 + ksdk2_0 + + + + + + + true + true + false + true + false + + + + + + + + + 14.0.0 + + + + Configures pin routing and optionally pin electrical features. + + false + BOARD_ + core0 + true + + + + + true + + + + + + + Configures pin routing and optionally pin electrical features. + + true + BOARD_ + core0 + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. + + true + BOARD_ + core0 + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. + + true + BOARD_ + core0 + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. + + false + BOARD_ + core0 + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. + + false + BOARD_ + core0 + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. + + false + BOARD_ + core0 + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. + + false + BOARD_ + core0 + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Configures pin routing and optionally pin electrical features. + + false + BOARD_ + core0 + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + + 14.0.0 + + + + + + + + + true + + + + + INPUT + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + 0.0.0 + + + + + + + + true + + + + + 2.8.0 + + + + + + + + + + + + + + + + 14.0.0 + + + + + + + + + true + + + + + true + + + + + true + + + + + 0 + + + + + true + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.0.0 + + + + + + + diff --git a/hw/bsp/kinetis_k/boards/teensy_35/board.cmake b/hw/bsp/kinetis_k/boards/teensy_35/board.cmake new file mode 100644 index 000000000..bd253d996 --- /dev/null +++ b/hw/bsp/kinetis_k/boards/teensy_35/board.cmake @@ -0,0 +1,17 @@ +set(MCU_VARIANT MK64F12) + +set(JLINK_DEVICE MK64FX512xxx12) +set(TEENSY_MCU TEENSY35) +set(PYOCD_TARGET k64f) + +set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/MK64FX512xxx12_flash.ld) + +function(update_board TARGET) + target_sources(${TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/board/pin_mux.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/board/clock_config.c + ) + target_compile_definitions(${TARGET} PUBLIC + CPU_MK64FX512VMD12 + ) +endfunction() diff --git a/hw/bsp/kinetis_k/boards/teensy_35/board.h b/hw/bsp/kinetis_k/boards/teensy_35/board.h new file mode 100644 index 000000000..f8173447a --- /dev/null +++ b/hw/bsp/kinetis_k/boards/teensy_35/board.h @@ -0,0 +1,48 @@ +/* + * 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. + */ + +#ifndef BOARD_H +#define BOARD_H + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ +// LED +#define LED_PORT GPIOC +#define LED_PIN 5 +#define LED_STATE_ON 1 + +// Button + +// UART +//#define UART_PORT UART0 +//#define UART_PIN_CLOCK kCLOCK_PortA +//#define UART_PIN_PORT PORTA +//#define UART_PIN_RX 1u +//#define UART_PIN_TX 2u +//#define UART_PIN_FUNCTION kPORT_MuxAlt2 +//#define SOPT5_UART0RXSRC_UART_RX 0x00u /*!< UART0 receive data source select: UART0_RX pin */ +//#define SOPT5_UART0TXSRC_UART_TX 0x00u /*!< UART0 transmit data source select: UART0_TX pin */ + +#endif diff --git a/hw/bsp/kinetis_k/boards/teensy_35/board.mk b/hw/bsp/kinetis_k/boards/teensy_35/board.mk new file mode 100644 index 000000000..2c4f87c25 --- /dev/null +++ b/hw/bsp/kinetis_k/boards/teensy_35/board.mk @@ -0,0 +1,23 @@ +MCU_VARIANT = MK64F12 + +CFLAGS += \ + -DCPU_MK64FX512VMD12 \ + +# mcu driver cause following warnings +CFLAGS += -Wno-error=unused-parameter -Wno-error=format -Wno-error=redundant-decls + +SRC_C += \ + $(BOARD_PATH)/board/clock_config.c \ + $(BOARD_PATH)/board/pin_mux.c \ + +LD_FILE = ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/MK64FX512xxx12_flash.ld + +# For flash-jlink target +JLINK_DEVICE = MK64FX512xxx12 + +# For flash-pyocd target +PYOCD_TARGET = k64f + +# flash by using teensy_loader_cli https://github.com/PaulStoffregen/teensy_loader_cli +flash: $(BUILD)/$(PROJECT).hex + teensy_loader_cli --mcu=TEENSY35 -v -w $< diff --git a/hw/bsp/kinetis_k/boards/teensy_35/board/clock_config.c b/hw/bsp/kinetis_k/boards/teensy_35/board/clock_config.c new file mode 100644 index 000000000..b69d10ccb --- /dev/null +++ b/hw/bsp/kinetis_k/boards/teensy_35/board/clock_config.c @@ -0,0 +1,186 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ +/* + * How to setup clock using clock driver functions: + * + * 1. CLOCK_SetSimSafeDivs, to make sure core clock, bus clock, flexbus clock + * and flash clock are in allowed range during clock mode switch. + * + * 2. Call CLOCK_Osc0Init to setup OSC clock, if it is used in target mode. + * + * 3. Set MCG configuration, MCG includes three parts: FLL clock, PLL clock and + * internal reference clock(MCGIRCLK). Follow the steps to setup: + * + * 1). Call CLOCK_BootToXxxMode to set MCG to target mode. + * + * 2). If target mode is FBI/BLPI/PBI mode, the MCGIRCLK has been configured + * correctly. For other modes, need to call CLOCK_SetInternalRefClkConfig + * explicitly to setup MCGIRCLK. + * + * 3). Don't need to configure FLL explicitly, because if target mode is FLL + * mode, then FLL has been configured by the function CLOCK_BootToXxxMode, + * if the target mode is not FLL mode, the FLL is disabled. + * + * 4). If target mode is PEE/PBE/PEI/PBI mode, then the related PLL has been + * setup by CLOCK_BootToXxxMode. In FBE/FBI/FEE/FBE mode, the PLL could + * be enabled independently, call CLOCK_EnablePll0 explicitly in this case. + * + * 4. Call CLOCK_SetSimConfig to set the clock configuration in SIM. + */ + +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Clocks v11.0 +processor: MK64FX512xxx12 +package_id: MK64FX512VLQ12 +mcu_data: ksdk2_0 +processor_version: 13.0.1 + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +#include "clock_config.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define MCG_IRCLK_DISABLE 0U /*!< MCGIRCLK disabled */ +#define OSC_CAP0P 0U /*!< Oscillator 0pF capacitor load */ +#define OSC_ER_CLK_DISABLE 0U /*!< Disable external reference clock */ +#define SIM_OSC32KSEL_OSC32KCLK_CLK 0U /*!< OSC32KSEL select: OSC32KCLK clock */ +#define SIM_PLLFLLSEL_MCGPLLCLK_CLK 1U /*!< PLLFLL select: MCGPLLCLK clock */ +#define SIM_USB_CLK_120000000HZ 120000000U /*!< Input SIM frequency for USB: 120000000Hz */ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ +/*FUNCTION********************************************************************** + * + * Function Name : CLOCK_CONFIG_SetFllExtRefDiv + * Description : Configure FLL external reference divider (FRDIV). + * Param frdiv : The value to set FRDIV. + * + *END**************************************************************************/ +static void CLOCK_CONFIG_SetFllExtRefDiv(uint8_t frdiv) +{ + MCG->C1 = ((MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(frdiv)); +} + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ +void BOARD_InitBootClocks(void) +{ + BOARD_BootClockRUN(); +} + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockRUN +called_from_default_init: true +outputs: +- {id: Bus_clock.outFreq, value: 60 MHz} +- {id: Core_clock.outFreq, value: 120 MHz} +- {id: Flash_clock.outFreq, value: 24 MHz} +- {id: FlexBus_clock.outFreq, value: 40 MHz} +- {id: LPO_clock.outFreq, value: 1 kHz} +- {id: MCGFFCLK.outFreq, value: 500 kHz} +- {id: PLLFLLCLK.outFreq, value: 120 MHz} +- {id: System_clock.outFreq, value: 120 MHz} +- {id: USB48MCLK.outFreq, value: 48 MHz} +settings: +- {id: MCGMode, value: PEE} +- {id: MCG.FRDIV.scale, value: '32'} +- {id: MCG.IREFS.sel, value: MCG.FRDIV} +- {id: MCG.PLLS.sel, value: MCG.PLL} +- {id: MCG.PRDIV.scale, value: '4'} +- {id: MCG.VDIV.scale, value: '30'} +- {id: MCG_C2_RANGE0_CFG, value: Very_high} +- {id: MCG_C2_RANGE0_FRDIV_CFG, value: Very_high} +- {id: MCG_C5_PLLCLKEN0_CFG, value: Enabled} +- {id: RTC_CR_CLKO_CFG, value: Disabled} +- {id: RTC_CR_OSC_CAP_LOAD_CFG, value: SC10PF} +- {id: SIM.OUTDIV2.scale, value: '2'} +- {id: SIM.OUTDIV3.scale, value: '3'} +- {id: SIM.OUTDIV4.scale, value: '5'} +- {id: SIM.PLLFLLSEL.sel, value: MCG.MCGPLLCLK} +- {id: SIM.USBDIV.scale, value: '5'} +- {id: SIM.USBFRAC.scale, value: '2'} +- {id: SIM.USBSRCSEL.sel, value: SIM.USBDIV} +- {id: USBClkConfig, value: 'yes'} +sources: +- {id: OSC.OSC.outFreq, value: 16 MHz, enabled: true} +- {id: RTC.RTC32kHz.outFreq, value: 32.768 kHz, enabled: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockRUN configuration + ******************************************************************************/ +const mcg_config_t mcgConfig_BOARD_BootClockRUN = + { + .mcgMode = kMCG_ModePEE, /* PEE - PLL Engaged External */ + .irclkEnableMode = MCG_IRCLK_DISABLE, /* MCGIRCLK disabled */ + .ircs = kMCG_IrcSlow, /* Slow internal reference clock selected */ + .fcrdiv = 0x1U, /* Fast IRC divider: divided by 2 */ + .frdiv = 0x0U, /* FLL reference clock divider: divided by 32 */ + .drs = kMCG_DrsLow, /* Low frequency range */ + .dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25% */ + .oscsel = kMCG_OscselOsc, /* Selects System Oscillator (OSCCLK) */ + .pll0Config = + { + .enableMode = kMCG_PllEnableIndependent,/* MCGPLLCLK enabled independent of MCG clock mode, MCGPLLCLK disabled in STOP mode */ + .prdiv = 0x3U, /* PLL Reference divider: divided by 4 */ + .vdiv = 0x6U, /* VCO divider: multiplied by 30 */ + }, + }; +const sim_clock_config_t simConfig_BOARD_BootClockRUN = + { + .pllFllSel = SIM_PLLFLLSEL_MCGPLLCLK_CLK, /* PLLFLL select: MCGPLLCLK clock */ + .er32kSrc = SIM_OSC32KSEL_OSC32KCLK_CLK, /* OSC32KSEL select: OSC32KCLK clock */ + .clkdiv1 = 0x1240000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV2: /2, OUTDIV3: /3, OUTDIV4: /5 */ + }; +const osc_config_t oscConfig_BOARD_BootClockRUN = + { + .freq = 16000000U, /* Oscillator frequency: 16000000Hz */ + .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ + .workMode = kOSC_ModeExt, /* Use external clock */ + .oscerConfig = + { + .enableMode = OSC_ER_CLK_DISABLE, /* Disable external reference clock */ + } + }; + +/******************************************************************************* + * Code for BOARD_BootClockRUN configuration + ******************************************************************************/ +void BOARD_BootClockRUN(void) +{ + /* Set the system clock dividers in SIM to safe value. */ + CLOCK_SetSimSafeDivs(); + /* Initializes OSC0 according to board configuration. */ + CLOCK_InitOsc0(&oscConfig_BOARD_BootClockRUN); + CLOCK_SetXtal0Freq(oscConfig_BOARD_BootClockRUN.freq); + /* Configure FLL external reference divider (FRDIV). */ + CLOCK_CONFIG_SetFllExtRefDiv(mcgConfig_BOARD_BootClockRUN.frdiv); + /* Set MCG to PEE mode. */ + CLOCK_BootToPeeMode(mcgConfig_BOARD_BootClockRUN.oscsel, + kMCG_PllClkSelPll0, + &mcgConfig_BOARD_BootClockRUN.pll0Config); + /* Set the clock configuration in SIM module. */ + CLOCK_SetSimConfig(&simConfig_BOARD_BootClockRUN); + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; + /* Enable USB FS clock. */ + CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcPll0, SIM_USB_CLK_120000000HZ); +} diff --git a/hw/bsp/kinetis_k/boards/teensy_35/board/clock_config.h b/hw/bsp/kinetis_k/boards/teensy_35/board/clock_config.h new file mode 100644 index 000000000..8601da9c2 --- /dev/null +++ b/hw/bsp/kinetis_k/boards/teensy_35/board/clock_config.h @@ -0,0 +1,69 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 16000000U /*!< Board xtal0 frequency in Hz */ + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockRUN configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 120000000U /*!< Core clock frequency: 120000000Hz */ + +/*! @brief MCG set for BOARD_BootClockRUN configuration. + */ +extern const mcg_config_t mcgConfig_BOARD_BootClockRUN; +/*! @brief SIM module set for BOARD_BootClockRUN configuration. + */ +extern const sim_clock_config_t simConfig_BOARD_BootClockRUN; +/*! @brief OSC set for BOARD_BootClockRUN configuration. + */ +extern const osc_config_t oscConfig_BOARD_BootClockRUN; + +/******************************************************************************* + * API for BOARD_BootClockRUN configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ diff --git a/hw/bsp/kinetis_k/boards/teensy_35/board/pin_mux.c b/hw/bsp/kinetis_k/boards/teensy_35/board/pin_mux.c new file mode 100644 index 000000000..d2c51e5c6 --- /dev/null +++ b/hw/bsp/kinetis_k/boards/teensy_35/board/pin_mux.c @@ -0,0 +1,61 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Pins v13.1 +processor: MK64FX512xxx12 +package_id: MK64FX512VLQ12 +mcu_data: ksdk2_0 +processor_version: 13.0.1 + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +#include "fsl_common.h" +#include "fsl_port.h" +#include "pin_mux.h" + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitBootPins + * Description : Calls initialization functions. + * + * END ****************************************************************************************************************/ +void BOARD_InitBootPins(void) +{ + BOARD_InitPins(); +} + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitPins: +- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} +- pin_list: + - {pin_num: '110', peripheral: GPIOC, signal: 'GPIO, 5', pin_signal: PTC5/LLWU_P9/SPI0_SCK/LPTMR0_ALT2/I2S0_RXD0/FB_AD10/CMP0_OUT/FTM0_CH2} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitPins(void) +{ + /* Port C Clock Gate Control: Clock enabled */ + CLOCK_EnableClock(kCLOCK_PortC); + + /* PORTC5 (pin 110) is configured as PTC5 */ + PORT_SetPinMux(PORTC, 5U, kPORT_MuxAsGpio); +} +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/kinetis_k/boards/teensy_35/board/pin_mux.h b/hw/bsp/kinetis_k/boards/teensy_35/board/pin_mux.h new file mode 100644 index 000000000..598ae8e9f --- /dev/null +++ b/hw/bsp/kinetis_k/boards/teensy_35/board/pin_mux.h @@ -0,0 +1,45 @@ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _PIN_MUX_H_ +#define _PIN_MUX_H_ + +/*! + * @addtogroup pin_mux + * @{ + */ + +/*********************************************************************************************************************** + * API + **********************************************************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Calls initialization functions. + * + */ +void BOARD_InitBootPins(void); + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitPins(void); + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif /* _PIN_MUX_H_ */ + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/kinetis_k/boards/teensy_35/teensy_35.mex b/hw/bsp/kinetis_k/boards/teensy_35/teensy_35.mex new file mode 100644 index 000000000..52a087026 --- /dev/null +++ b/hw/bsp/kinetis_k/boards/teensy_35/teensy_35.mex @@ -0,0 +1,184 @@ + + + + MK64FX512xxx12 + MK64FX512VLQ12 + ksdk2_0 + + + + + + + true + false + false + true + false + + + + + + + + + 13.0.1 + + + + Configures pin routing and optionally pin electrical features. + + true + core0 + true + + + + + true + + + + + true + + + + + + + + + + + + + + + + 13.0.1 + + + + + + + + + true + + + + + INPUT + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + N/A + + + + + + + 13.0.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + N/A + + + + diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/frdm_k32l2b.c b/hw/bsp/kinetis_k/family.c similarity index 51% rename from hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/frdm_k32l2b.c rename to hw/bsp/kinetis_k/family.c index 3f99b0cbd..30dfe6d76 100644 --- a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/frdm_k32l2b.c +++ b/hw/bsp/kinetis_k/family.c @@ -21,65 +21,37 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. */ #include "bsp/board_api.h" #include "board.h" +#include "fsl_device_registers.h" #include "fsl_gpio.h" #include "fsl_port.h" #include "fsl_clock.h" -#include "fsl_lpuart.h" +#include "fsl_uart.h" +#include "fsl_sysmpu.h" -#include "clock_config.h" +#include "board/clock_config.h" +#include "board/pin_mux.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ -void USB0_IRQHandler(void) -{ +void USB0_IRQHandler(void) { +#if CFG_TUH_ENABLED + tuh_int_handler(0); +#endif +#if CFG_TUD_ENABLED tud_int_handler(0); +#endif } -void board_init(void) -{ - /* Enable port clocks for UART/LED/Button pins */ - CLOCK_EnableClock(UART_PIN_CLOCK); - CLOCK_EnableClock(LED_PIN_CLOCK); - CLOCK_EnableClock(BUTTON_PIN_CLOCK); - - gpio_pin_config_t led_config = { kGPIO_DigitalOutput, 0 }; - GPIO_PinInit(LED_GPIO, LED_PIN, &led_config); - PORT_SetPinMux(LED_PORT, LED_PIN, kPORT_MuxAsGpio); - - gpio_pin_config_t button_config = { kGPIO_DigitalInput, 0 }; - GPIO_PinInit(BUTTON_GPIO, BUTTON_PIN, &button_config); - const port_pin_config_t BUTTON_CFG = { - kPORT_PullUp, - kPORT_FastSlewRate, - kPORT_PassiveFilterDisable, - kPORT_LowDriveStrength, - kPORT_MuxAsGpio - }; - PORT_SetPinConfig(BUTTON_PORT, BUTTON_PIN, &BUTTON_CFG); - - /* PORTA1 (pin 23) is configured as LPUART0_RX */ - PORT_SetPinMux(PORTA, 1U, kPORT_MuxAlt2); - /* PORTA2 (pin 24) is configured as LPUART0_TX */ - PORT_SetPinMux(PORTA, 2U, kPORT_MuxAlt2); - - SIM->SOPT5 = ((SIM->SOPT5 & - /* Mask bits to zero which are setting */ - (~(SIM_SOPT5_LPUART0TXSRC_MASK | SIM_SOPT5_LPUART0RXSRC_MASK))) - /* LPUART0 Transmit Data Source Select: LPUART0_TX pin. */ - | SIM_SOPT5_LPUART0TXSRC(SOPT5_LPUART0TXSRC_LPUART_TX) - /* LPUART0 Receive Data Source Select: LPUART_RX pin. */ - | SIM_SOPT5_LPUART0RXSRC(SOPT5_LPUART0RXSRC_LPUART_RX)); - +void board_init(void) { + BOARD_InitBootPins(); BOARD_BootClockRUN(); SystemCoreClockUpdate(); - CLOCK_SetLpuart0Clock(1); + SYSMPU_Enable(SYSMPU, 0); #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer @@ -89,52 +61,102 @@ void board_init(void) NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #endif - lpuart_config_t uart_config; - LPUART_GetDefaultConfig(&uart_config); - uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE; - uart_config.enableTx = true; - uart_config.enableRx = true; - LPUART_Init(UART_PORT, &uart_config, CLOCK_GetFreq(kCLOCK_McgIrc48MClk)); + // LED + gpio_pin_config_t led_config = { kGPIO_DigitalOutput, 0 }; + GPIO_PinInit(LED_PORT, LED_PIN, &led_config); + board_led_write(false); + +#if defined(BUTTON_PORT) && defined(BUTTON_PIN) + gpio_pin_config_t button_config = { kGPIO_DigitalInput, 0 }; + GPIO_PinInit(BUTTON_PORT, BUTTON_PIN, &button_config); +#endif + +#ifdef UART_DEV + const uart_config_t uart_config = { + .baudRate_Bps = 115200UL, + .parityMode = kUART_ParityDisabled, + .stopBitCount = kUART_OneStopBit, + .txFifoWatermark = 0U, + .rxFifoWatermark = 1U, + .idleType = kUART_IdleTypeStartBit, + .enableTx = true, + .enableRx = true + }; + UART_Init(UART_DEV, &uart_config, UART_CLOCK); +#endif // USB - CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcIrc48M, 48000000U); + // USB clock is configured in BOARD_BootClockRUN() } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ -void board_led_write(bool state) -{ - GPIO_PinWrite(LED_GPIO, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +void board_led_write(bool state) { + GPIO_PinWrite(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } -uint32_t board_button_read(void) -{ - return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_GPIO, BUTTON_PIN); +uint32_t board_button_read(void) { +#if defined(BUTTON_PORT) && defined(BUTTON_PIN) + return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_PORT, BUTTON_PIN); +#else + return 0; +#endif } -int board_uart_read(uint8_t* buf, int len) -{ - LPUART_ReadBlocking(UART_PORT, buf, len); - return len; -} - -int board_uart_write(void const * buf, int len) -{ - LPUART_WriteBlocking(UART_PORT, (uint8_t const*) buf, len); +int board_uart_read(uint8_t *buf, int len) { + (void) buf; + (void) len; +#ifdef UART_DEV + // Read blocking will block until there is data +// UART_ReadBlocking(UART_DEV, buf, len); +// return len; + return 0; +#else + return 0; +#endif +} + +int board_uart_write(void const *buf, int len) { + (void) buf; + (void) len; + +#ifdef UART_DEV + UART_WriteBlocking(UART_DEV, (uint8_t const*) buf, len); return len; +#else + return 0; +#endif } #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 + + +#ifndef __ICCARM__ +// Implement _start() since we use linker flag '-nostartfiles'. +// Requires defined __STARTUP_CLEAR_BSS, +extern int main(void); +TU_ATTR_UNUSED void _start(void) { + // called by startup code + main(); + while (1) {} +} + +#ifdef __clang__ +void _exit (int __status) { + while (1) {} +} +#endif + +#endif diff --git a/hw/bsp/kinetis_k/family.cmake b/hw/bsp/kinetis_k/family.cmake new file mode 100644 index 000000000..771754ebd --- /dev/null +++ b/hw/bsp/kinetis_k/family.cmake @@ -0,0 +1,117 @@ +include_guard() + +if (NOT BOARD) + message(FATAL_ERROR "BOARD not specified") +endif () + +set(SDK_DIR ${TOP}/hw/mcu/nxp/mcux-sdk) +set(CMSIS_DIR ${TOP}/lib/CMSIS_5) + +# 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}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS KINETIS_K 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 () + + # LD_FILE and STARTUP_FILE can be defined in board.cmake + set(LD_FILE_Clang ${LD_FILE_GNU}) + set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_VARIANT}.S) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ${SDK_DIR}/drivers/gpio/fsl_gpio.c + ${SDK_DIR}/drivers/uart/fsl_uart.c + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c + ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_VARIANT}.c + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + __STARTUP_CLEAR_BSS + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMSIS_DIR}/CMSIS/Core/Include + ${SDK_DIR}/devices/${MCU_VARIANT} + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers + ${SDK_DIR}/drivers/common + ${SDK_DIR}/drivers/gpio + ${SDK_DIR}/drivers/port + ${SDK_DIR}/drivers/smc + ${SDK_DIR}/drivers/sysmpu + ${SDK_DIR}/drivers/uart + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + --specs=nosys.specs --specs=nano.specs + -nostartfiles + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + ) + 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_KINETIS_K ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/chipidea/ci_fs/dcd_ci_fs.c + ${TOP}/src/portable/nxp/khci/hcd_khci.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}) + + if (DEFINED TEENSY_MCU) + family_add_bin_hex(${TARGET}) + family_flash_teensy(${TARGET}) + endif () +endfunction() diff --git a/hw/bsp/kinetis_k/family.mk b/hw/bsp/kinetis_k/family.mk new file mode 100644 index 000000000..844ce332e --- /dev/null +++ b/hw/bsp/kinetis_k/family.mk @@ -0,0 +1,38 @@ +SDK_DIR = hw/mcu/nxp/mcux-sdk +DEPS_SUBMODULES += $(SDK_DIR) lib/CMSIS_5 + +MCU_DIR = $(SDK_DIR)/devices/${MCU_VARIANT} +include $(TOP)/$(BOARD_PATH)/board.mk +CPU_CORE ?= cortex-m4 + +CFLAGS += \ + -D__STARTUP_CLEAR_BSS \ + -DCFG_TUSB_MCU=OPT_MCU_KINETIS_K \ + +LDFLAGS += \ + -nostartfiles \ + --specs=nosys.specs --specs=nano.specs \ + -Wl,--defsym,__stack_size__=0x400 \ + -Wl,--defsym,__heap_size__=0 + +SRC_C += \ + src/portable/nxp/khci/dcd_khci.c \ + src/portable/nxp/khci/hcd_khci.c \ + $(MCU_DIR)/system_${MCU_VARIANT}.c \ + $(MCU_DIR)/drivers/fsl_clock.c \ + $(SDK_DIR)/drivers/gpio/fsl_gpio.c \ + $(SDK_DIR)/drivers/uart/fsl_uart.c \ + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + $(TOP)/$(MCU_DIR) \ + $(TOP)/$(MCU_DIR)/drivers \ + $(TOP)/$(SDK_DIR)/drivers/common \ + $(TOP)/$(SDK_DIR)/drivers/gpio \ + $(TOP)/$(SDK_DIR)/drivers/port \ + $(TOP)/$(SDK_DIR)/drivers/smc \ + $(TOP)/$(SDK_DIR)/drivers/sysmpu \ + $(TOP)/$(SDK_DIR)/drivers/uart \ + +SRC_S += ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_VARIANT}.S diff --git a/hw/bsp/kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..e6604d360 --- /dev/null +++ b/hw/bsp/kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,169 @@ +/* + * 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 "fsl_device_registers.h" +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#if defined(__ARM_FP) && __ARM_FP >= 4 + #define configENABLE_FPU 1 +#else + #define configENABLE_FPU 0 +#endif +#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 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* 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 2 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<CLKOUTCNFG = SCG_CLKOUTCNFG_CLKOUTSEL(setting); +} + +/*FUNCTION********************************************************************** + * + * Function Name : CLOCK_CONFIG_FircSafeConfig + * Description : This function is used to safely configure FIRC clock. + * In default out of reset, the CPU is clocked from FIRC(IRC48M). + * Before setting FIRC, change to use SIRC as system clock, + * then configure FIRC. After FIRC is set, change back to use FIRC + * in case SIRC need to be configured. + * Param fircConfig : FIRC configuration. + * + *END**************************************************************************/ +static void CLOCK_CONFIG_FircSafeConfig(const scg_firc_config_t *fircConfig) +{ + scg_sys_clk_config_t curConfig; + const scg_sirc_config_t scgSircConfig = {.enableMode = kSCG_SircEnable, + .div1 = kSCG_AsyncClkDisable, + .div3 = kSCG_AsyncClkDivBy2, + .range = kSCG_SircRangeHigh}; + scg_sys_clk_config_t sysClkSafeConfigSource = { + .divSlow = kSCG_SysClkDivBy4, /* Slow clock divider */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved1 = 0, + .reserved2 = 0, + .reserved3 = 0, +#endif + .divCore = kSCG_SysClkDivBy1, /* Core clock divider */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved4 = 0, +#endif + .src = kSCG_SysClkSrcSirc, /* System clock source */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved5 = 0, +#endif + }; + /* Init Sirc. */ + CLOCK_InitSirc(&scgSircConfig); + /* Change to use SIRC as system clock source to prepare to change FIRCCFG register. */ + CLOCK_SetRunModeSysClkConfig(&sysClkSafeConfigSource); + /* Wait for clock source switch finished. */ + do + { + CLOCK_GetCurSysClkConfig(&curConfig); + } while (curConfig.src != sysClkSafeConfigSource.src); + + /* Init Firc. */ + CLOCK_InitFirc(fircConfig); + /* Change back to use FIRC as system clock source in order to configure SIRC if needed. */ + sysClkSafeConfigSource.src = kSCG_SysClkSrcFirc; + CLOCK_SetRunModeSysClkConfig(&sysClkSafeConfigSource); + /* Wait for clock source switch finished. */ + do + { + CLOCK_GetCurSysClkConfig(&curConfig); + } while (curConfig.src != sysClkSafeConfigSource.src); +} + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ +void BOARD_InitBootClocks(void) +{ + BOARD_BootClockRUN(); +} + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockRUN +called_from_default_init: true +outputs: +- {id: Core_clock.outFreq, value: 48 MHz} +- {id: FIRCDIV1_CLK.outFreq, value: 48 MHz} +- {id: FIRCDIV3_CLK.outFreq, value: 48 MHz} +- {id: LPO_clock.outFreq, value: 1 kHz} +- {id: OSC32KCLK.outFreq, value: 32.768 kHz} +- {id: SIRCDIV3_CLK.outFreq, value: 4 MHz} +- {id: SIRC_CLK.outFreq, value: 8 MHz} +- {id: SOSCDIV3_CLK.outFreq, value: 32.768 kHz} +- {id: SOSCER_CLK.outFreq, value: 32.768 kHz} +- {id: SOSC_CLK.outFreq, value: 32.768 kHz} +- {id: Slow_clock.outFreq, value: 24 MHz} +- {id: System_clock.outFreq, value: 48 MHz} +settings: +- {id: SCG.FIRCDIV1.scale, value: '1', locked: true} +- {id: SCG.FIRCDIV3.scale, value: '1', locked: true} +- {id: SCG.SIRCDIV3.scale, value: '2', locked: true} +- {id: SCG.SOSCDIV3.scale, value: '1', locked: true} +- {id: SCG_SOSCCFG_OSC_MODE_CFG, value: ModeOscLowPower} +- {id: SCG_SOSCCSR_SOSCEN_CFG, value: Enabled} +- {id: SCG_SOSCCSR_SOSCERCLKEN_CFG, value: Enabled} +sources: +- {id: SCG.SOSC.outFreq, value: 32.768 kHz, enabled: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockRUN configuration + ******************************************************************************/ +const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockRUN = + { + .divSlow = kSCG_SysClkDivBy2, /* Slow Clock Divider: divided by 2 */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved1 = 0, + .reserved2 = 0, + .reserved3 = 0, +#endif + .divCore = kSCG_SysClkDivBy1, /* Core Clock Divider: divided by 1 */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved4 = 0, +#endif + .src = kSCG_SysClkSrcFirc, /* Fast IRC is selected as System Clock Source */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved5 = 0, +#endif + }; +const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockRUN = + { + .freq = 32768U, /* System Oscillator frequency: 32768Hz */ + .enableMode = kSCG_SysOscEnable | kSCG_SysOscEnableErClk,/* Enable System OSC clock, Enable OSCERCLK */ + .monitorMode = kSCG_SysOscMonitorDisable, /* Monitor disabled */ + .div1 = kSCG_AsyncClkDisable, /* System OSC Clock Divider 1: Clock output is disabled */ + .div3 = kSCG_AsyncClkDivBy1, /* System OSC Clock Divider 3: divided by 1 */ + .capLoad = SCG_SYS_OSC_CAP_0P, /* Oscillator capacity load: 0pF */ + .workMode = kSCG_SysOscModeOscLowPower, /* Oscillator low power */ + }; +const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockRUN = + { + .enableMode = kSCG_SircEnable | kSCG_SircEnableInLowPower,/* Enable SIRC clock, Enable SIRC in low power mode */ + .div1 = kSCG_AsyncClkDisable, /* Slow IRC Clock Divider 1: Clock output is disabled */ + .div3 = kSCG_AsyncClkDivBy2, /* Slow IRC Clock Divider 3: divided by 2 */ + .range = kSCG_SircRangeHigh, /* Slow IRC high range clock (8 MHz) */ + }; +const scg_firc_config_t g_scgFircConfig_BOARD_BootClockRUN = + { + .enableMode = kSCG_FircEnable, /* Enable FIRC clock */ + .div1 = kSCG_AsyncClkDivBy1, /* Fast IRC Clock Divider 1: divided by 1 */ + .div3 = kSCG_AsyncClkDivBy1, /* Fast IRC Clock Divider 3: divided by 1 */ + .range = kSCG_FircRange48M, /* Fast IRC is trimmed to 48MHz */ + .trimConfig = NULL, /* Fast IRC Trim disabled */ + }; +const scg_spll_config_t g_scgSysPllConfig_BOARD_BootClockRUN = + { + .enableMode = SCG_SPLL_DISABLE, /* System PLL disabled */ + .monitorMode = kSCG_SysPllMonitorDisable, /* Monitor disabled */ + .div1 = kSCG_AsyncClkDisable, /* System PLL Clock Divider 1: Clock output is disabled */ + .div3 = kSCG_AsyncClkDisable, /* System PLL Clock Divider 3: Clock output is disabled */ + .src = kSCG_SysPllSrcSysOsc, /* System PLL clock source is System OSC */ + .prediv = 0, /* Divided by 1 */ + .mult = 0, /* Multiply Factor is 16 */ + }; +/******************************************************************************* + * Code for BOARD_BootClockRUN configuration + ******************************************************************************/ +void BOARD_BootClockRUN(void) +{ + scg_sys_clk_config_t curConfig; + + /* Init SOSC according to board configuration. */ + CLOCK_InitSysOsc(&g_scgSysOscConfig_BOARD_BootClockRUN); + /* Set the XTAL0 frequency based on board settings. */ + CLOCK_SetXtal0Freq(g_scgSysOscConfig_BOARD_BootClockRUN.freq); + /* Init FIRC. */ + CLOCK_CONFIG_FircSafeConfig(&g_scgFircConfig_BOARD_BootClockRUN); + /* Init SIRC. */ + CLOCK_InitSirc(&g_scgSircConfig_BOARD_BootClockRUN); + /* Set SCG to FIRC mode. */ + CLOCK_SetRunModeSysClkConfig(&g_sysClkConfig_BOARD_BootClockRUN); + /* Wait for clock source switch finished. */ + do + { + CLOCK_GetCurSysClkConfig(&curConfig); + } while (curConfig.src != g_sysClkConfig_BOARD_BootClockRUN.src); + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; +} + +/******************************************************************************* + ********************* Configuration BOARD_BootClockHSRUN ********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockHSRUN +outputs: +- {id: CLKOUT.outFreq, value: 8 MHz} +- {id: Core_clock.outFreq, value: 96 MHz, locked: true, accuracy: '0.001'} +- {id: FIRCDIV1_CLK.outFreq, value: 48 MHz} +- {id: FIRCDIV3_CLK.outFreq, value: 48 MHz} +- {id: LPO_clock.outFreq, value: 1 kHz} +- {id: OSC32KCLK.outFreq, value: 32.768 kHz} +- {id: PLLDIV1_CLK.outFreq, value: 96 MHz} +- {id: PLLDIV3_CLK.outFreq, value: 96 MHz} +- {id: SIRCDIV1_CLK.outFreq, value: 8 MHz} +- {id: SIRCDIV3_CLK.outFreq, value: 8 MHz} +- {id: SIRC_CLK.outFreq, value: 8 MHz} +- {id: SOSCDIV1_CLK.outFreq, value: 32.768 kHz} +- {id: SOSCDIV3_CLK.outFreq, value: 32.768 kHz} +- {id: SOSCER_CLK.outFreq, value: 32.768 kHz} +- {id: SOSC_CLK.outFreq, value: 32.768 kHz} +- {id: Slow_clock.outFreq, value: 24 MHz, locked: true, accuracy: '0.001'} +- {id: System_clock.outFreq, value: 96 MHz} +settings: +- {id: SCGMode, value: SPLL} +- {id: powerMode, value: HSRUN} +- {id: CLKOUTConfig, value: 'yes'} +- {id: SCG.DIVSLOW.scale, value: '4'} +- {id: SCG.FIRCDIV1.scale, value: '1', locked: true} +- {id: SCG.FIRCDIV3.scale, value: '1', locked: true} +- {id: SCG.PREDIV.scale, value: '4'} +- {id: SCG.SCSSEL.sel, value: SCG.SPLL_DIV2_CLK} +- {id: SCG.SIRCDIV1.scale, value: '1', locked: true} +- {id: SCG.SIRCDIV3.scale, value: '1', locked: true} +- {id: SCG.SOSCDIV1.scale, value: '1', locked: true} +- {id: SCG.SOSCDIV3.scale, value: '1', locked: true} +- {id: SCG.SPLLDIV1.scale, value: '1', locked: true} +- {id: SCG.SPLLDIV3.scale, value: '1', locked: true} +- {id: SCG.SPLLSRCSEL.sel, value: SCG.FIRC} +- {id: SCG_SOSCCFG_OSC_MODE_CFG, value: ModeOscLowPower} +- {id: SCG_SOSCCSR_SOSCEN_CFG, value: Enabled} +- {id: SCG_SOSCCSR_SOSCERCLKEN_CFG, value: Enabled} +- {id: SCG_SPLLCSR_SPLLEN_CFG, value: Enabled} +sources: +- {id: SCG.SOSC.outFreq, value: 32.768 kHz, enabled: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockHSRUN configuration + ******************************************************************************/ +const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockHSRUN = + { + .divSlow = kSCG_SysClkDivBy4, /* Slow Clock Divider: divided by 4 */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved1 = 0, + .reserved2 = 0, + .reserved3 = 0, +#endif + .divCore = kSCG_SysClkDivBy1, /* Core Clock Divider: divided by 1 */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved4 = 0, +#endif + .src = kSCG_SysClkSrcSysPll, /* System PLL is selected as System Clock Source */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved5 = 0, +#endif + }; +const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockHSRUN = + { + .freq = 32768U, /* System Oscillator frequency: 32768Hz */ + .enableMode = kSCG_SysOscEnable | kSCG_SysOscEnableErClk,/* Enable System OSC clock, Enable OSCERCLK */ + .monitorMode = kSCG_SysOscMonitorDisable, /* Monitor disabled */ + .div1 = kSCG_AsyncClkDivBy1, /* System OSC Clock Divider 1: divided by 1 */ + .div3 = kSCG_AsyncClkDivBy1, /* System OSC Clock Divider 3: divided by 1 */ + .capLoad = SCG_SYS_OSC_CAP_0P, /* Oscillator capacity load: 0pF */ + .workMode = kSCG_SysOscModeOscLowPower, /* Oscillator low power */ + }; +const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockHSRUN = + { + .enableMode = kSCG_SircEnable | kSCG_SircEnableInLowPower,/* Enable SIRC clock, Enable SIRC in low power mode */ + .div1 = kSCG_AsyncClkDivBy1, /* Slow IRC Clock Divider 1: divided by 1 */ + .div3 = kSCG_AsyncClkDivBy1, /* Slow IRC Clock Divider 3: divided by 1 */ + .range = kSCG_SircRangeHigh, /* Slow IRC high range clock (8 MHz) */ + }; +const scg_firc_config_t g_scgFircConfig_BOARD_BootClockHSRUN = + { + .enableMode = kSCG_FircEnable, /* Enable FIRC clock */ + .div1 = kSCG_AsyncClkDivBy1, /* Fast IRC Clock Divider 1: divided by 1 */ + .div3 = kSCG_AsyncClkDivBy1, /* Fast IRC Clock Divider 3: divided by 1 */ + .range = kSCG_FircRange48M, /* Fast IRC is trimmed to 48MHz */ + .trimConfig = NULL, /* Fast IRC Trim disabled */ + }; +const scg_spll_config_t g_scgSysPllConfig_BOARD_BootClockHSRUN = + { + .enableMode = kSCG_SysPllEnable, /* Enable SPLL clock */ + .monitorMode = kSCG_SysPllMonitorDisable, /* Monitor disabled */ + .div1 = kSCG_AsyncClkDivBy1, /* System PLL Clock Divider 1: divided by 1 */ + .div3 = kSCG_AsyncClkDivBy1, /* System PLL Clock Divider 3: divided by 1 */ + .src = kSCG_SysPllSrcFirc, /* System PLL clock source is Fast IRC */ + .prediv = 3, /* Divided by 4 */ + .mult = 0, /* Multiply Factor is 16 */ + }; +/******************************************************************************* + * Code for BOARD_BootClockHSRUN configuration + ******************************************************************************/ +void BOARD_BootClockHSRUN(void) +{ + scg_sys_clk_config_t curConfig; + + /* Init SOSC according to board configuration. */ + CLOCK_InitSysOsc(&g_scgSysOscConfig_BOARD_BootClockHSRUN); + /* Set the XTAL0 frequency based on board settings. */ + CLOCK_SetXtal0Freq(g_scgSysOscConfig_BOARD_BootClockHSRUN.freq); + /* Init FIRC. */ + CLOCK_CONFIG_FircSafeConfig(&g_scgFircConfig_BOARD_BootClockHSRUN); + /* Init SIRC. */ + CLOCK_InitSirc(&g_scgSircConfig_BOARD_BootClockHSRUN); + /* Init SysPll. */ + CLOCK_InitSysPll(&g_scgSysPllConfig_BOARD_BootClockHSRUN); + /* Set HSRUN power mode. */ + SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); + SMC_SetPowerModeHsrun(SMC); + while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateHsrun) + { + } + + /* Set SCG to SPLL mode. */ + CLOCK_SetHsrunModeSysClkConfig(&g_sysClkConfig_BOARD_BootClockHSRUN); + /* Wait for clock source switch finished. */ + do + { + CLOCK_GetCurSysClkConfig(&curConfig); + } while (curConfig.src != g_sysClkConfig_BOARD_BootClockHSRUN.src); + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKHSRUN_CORE_CLOCK; + /* Set SCG CLKOUT selection. */ + CLOCK_CONFIG_SetScgOutSel(SCG_CLKOUTCNFG_SIRC); +} + +/******************************************************************************* + ********************* Configuration BOARD_BootClockVLPR *********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockVLPR +outputs: +- {id: Core_clock.outFreq, value: 8 MHz, locked: true, accuracy: '0.001'} +- {id: LPO_clock.outFreq, value: 1 kHz} +- {id: SIRC_CLK.outFreq, value: 8 MHz} +- {id: Slow_clock.outFreq, value: 1 MHz, locked: true, accuracy: '0.001'} +- {id: System_clock.outFreq, value: 8 MHz} +settings: +- {id: SCGMode, value: SIRC} +- {id: powerMode, value: VLPR} +- {id: SCG.DIVSLOW.scale, value: '8'} +- {id: SCG.SCSSEL.sel, value: SCG.SIRC} +- {id: SCG_FIRCCSR_FIRCLPEN_CFG, value: Enabled} +sources: +- {id: SCG.SOSC.outFreq, value: 32.768 kHz, enabled: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockVLPR configuration + ******************************************************************************/ +const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockVLPR = + { + .divSlow = kSCG_SysClkDivBy8, /* Slow Clock Divider: divided by 8 */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved1 = 0, + .reserved2 = 0, + .reserved3 = 0, +#endif + .divCore = kSCG_SysClkDivBy1, /* Core Clock Divider: divided by 1 */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved4 = 0, +#endif + .src = kSCG_SysClkSrcSirc, /* Slow IRC is selected as System Clock Source */ +#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) + .reserved5 = 0, +#endif + }; +const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockVLPR = + { + .freq = 0U, /* System Oscillator frequency: 0Hz */ + .enableMode = SCG_SOSC_DISABLE, /* System OSC disabled */ + .monitorMode = kSCG_SysOscMonitorDisable, /* Monitor disabled */ + .div1 = kSCG_AsyncClkDisable, /* System OSC Clock Divider 1: Clock output is disabled */ + .div3 = kSCG_AsyncClkDisable, /* System OSC Clock Divider 3: Clock output is disabled */ + .capLoad = SCG_SYS_OSC_CAP_0P, /* Oscillator capacity load: 0pF */ + .workMode = kSCG_SysOscModeExt, /* Use external clock */ + }; +const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockVLPR = + { + .enableMode = kSCG_SircEnable | kSCG_SircEnableInLowPower,/* Enable SIRC clock, Enable SIRC in low power mode */ + .div1 = kSCG_AsyncClkDisable, /* Slow IRC Clock Divider 1: Clock output is disabled */ + .div3 = kSCG_AsyncClkDisable, /* Slow IRC Clock Divider 3: Clock output is disabled */ + .range = kSCG_SircRangeHigh, /* Slow IRC high range clock (8 MHz) */ + }; +const scg_firc_config_t g_scgFircConfig_BOARD_BootClockVLPR = + { + .enableMode = kSCG_FircEnable | kSCG_FircEnableInLowPower,/* Enable FIRC clock, Enable FIRC in low power mode */ + .div1 = kSCG_AsyncClkDisable, /* Fast IRC Clock Divider 1: Clock output is disabled */ + .div3 = kSCG_AsyncClkDisable, /* Fast IRC Clock Divider 3: Clock output is disabled */ + .range = kSCG_FircRange48M, /* Fast IRC is trimmed to 48MHz */ + .trimConfig = NULL, /* Fast IRC Trim disabled */ + }; +const scg_spll_config_t g_scgSysPllConfig_BOARD_BootClockVLPR = + { + .enableMode = SCG_SPLL_DISABLE, /* System PLL disabled */ + .monitorMode = kSCG_SysPllMonitorDisable, /* Monitor disabled */ + .div1 = kSCG_AsyncClkDisable, /* System PLL Clock Divider 1: Clock output is disabled */ + .div3 = kSCG_AsyncClkDisable, /* System PLL Clock Divider 3: Clock output is disabled */ + .src = kSCG_SysPllSrcSysOsc, /* System PLL clock source is System OSC */ + .prediv = 0, /* Divided by 1 */ + .mult = 0, /* Multiply Factor is 16 */ + }; +/******************************************************************************* + * Code for BOARD_BootClockVLPR configuration + ******************************************************************************/ +void BOARD_BootClockVLPR(void) +{ + /* Init FIRC. */ + CLOCK_CONFIG_FircSafeConfig(&g_scgFircConfig_BOARD_BootClockVLPR); + /* Init SIRC. */ + CLOCK_InitSirc(&g_scgSircConfig_BOARD_BootClockVLPR); + /* Allow SMC all power modes. */ + SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); + /* Set VLPR power mode. */ + SMC_SetPowerModeVlpr(SMC); + while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateVlpr) + { + } + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKVLPR_CORE_CLOCK; +} diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.h b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.h new file mode 100644 index 000000000..c01d5e03c --- /dev/null +++ b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.h @@ -0,0 +1,164 @@ +/* + * Copyright 2019 ,2021 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 32768U /*!< Board xtal0 frequency in Hz */ + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockRUN configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ + +/*! @brief SCG set for BOARD_BootClockRUN configuration. + */ +extern const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockRUN; +/*! @brief System OSC set for BOARD_BootClockRUN configuration. + */ +extern const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockRUN; +/*! @brief SIRC set for BOARD_BootClockRUN configuration. + */ +extern const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockRUN; +/*! @brief FIRC set for BOARD_BootClockRUN configuration. + */ +extern const scg_firc_config_t g_scgFircConfigBOARD_BootClockRUN; +extern const scg_spll_config_t g_scgSysPllConfigBOARD_BootClockRUN; +/*! @brief Low Power FLL set for BOARD_BootClockRUN configuration. + */ + +/******************************************************************************* + * API for BOARD_BootClockRUN configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************* Configuration BOARD_BootClockHSRUN ********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockHSRUN configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKHSRUN_CORE_CLOCK 96000000U /*!< Core clock frequency: 96000000Hz */ + +/*! @brief SCG set for BOARD_BootClockHSRUN configuration. + */ +extern const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockHSRUN; +/*! @brief System OSC set for BOARD_BootClockHSRUN configuration. + */ +extern const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockHSRUN; +/*! @brief SIRC set for BOARD_BootClockHSRUN configuration. + */ +extern const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockHSRUN; +/*! @brief FIRC set for BOARD_BootClockHSRUN configuration. + */ +extern const scg_firc_config_t g_scgFircConfigBOARD_BootClockHSRUN; +extern const scg_spll_config_t g_scgSysPllConfigBOARD_BootClockHSRUN; +/*! @brief Low Power FLL set for BOARD_BootClockHSRUN configuration. + */ + +/******************************************************************************* + * API for BOARD_BootClockHSRUN configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockHSRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************* Configuration BOARD_BootClockVLPR *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockVLPR configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKVLPR_CORE_CLOCK 8000000U /*!< Core clock frequency: 8000000Hz */ + +/*! @brief SCG set for BOARD_BootClockVLPR configuration. + */ +extern const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockVLPR; +/*! @brief System OSC set for BOARD_BootClockVLPR configuration. + */ +extern const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockVLPR; +/*! @brief SIRC set for BOARD_BootClockVLPR configuration. + */ +extern const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockVLPR; +/*! @brief FIRC set for BOARD_BootClockVLPR configuration. + */ +extern const scg_firc_config_t g_scgFircConfigBOARD_BootClockVLPR; +extern const scg_spll_config_t g_scgSysPllConfigBOARD_BootClockVLPR; +/*! @brief Low Power FLL set for BOARD_BootClockVLPR configuration. + */ + +/******************************************************************************* + * API for BOARD_BootClockVLPR configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockVLPR(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.cmake b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.cmake new file mode 100644 index 000000000..2ec2acace --- /dev/null +++ b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.cmake @@ -0,0 +1,15 @@ +set(MCU_VARIANT K32L2B31A) + +set(JLINK_DEVICE K32L2B31xxxxA) +set(PYOCD_TARGET K32L2B) + +set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/K32L2B31xxxxA_flash.ld) + +function(update_board TARGET) + target_sources(${TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clock_config.c + ) + target_compile_definitions(${TARGET} PUBLIC + CPU_K32L2B31VLH0A + ) +endfunction() diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.h b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.h index 8d21fdcd4..790d6fcb0 100644 --- a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.h +++ b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.h @@ -30,6 +30,8 @@ #include "fsl_device_registers.h" +#define USB_CLOCK_SOURCE kCLOCK_UsbSrcIrc48M + // LED #define LED_PIN_CLOCK kCLOCK_PortD #define LED_GPIO GPIOD @@ -52,5 +54,25 @@ #define UART_PIN_TX 2u #define SOPT5_LPUART0RXSRC_LPUART_RX 0x00u /*!<@brief LPUART0 Receive Data Source Select: LPUART_RX pin */ #define SOPT5_LPUART0TXSRC_LPUART_TX 0x00u /*!<@brief LPUART0 Transmit Data Source Select: LPUART0_TX pin */ +#define UART_CLOCK_SOURCE_HZ CLOCK_GetFreq(kCLOCK_McgIrc48MClk) + +static inline void BOARD_InitBootPins(void) { + /* PORTA1 (pin 23) is configured as LPUART0_RX */ + PORT_SetPinMux(PORTA, 1U, kPORT_MuxAlt2); + /* PORTA2 (pin 24) is configured as LPUART0_TX */ + PORT_SetPinMux(PORTA, 2U, kPORT_MuxAlt2); + + SIM->SOPT5 = ((SIM->SOPT5 & + /* Mask bits to zero which are setting */ + (~(SIM_SOPT5_LPUART0TXSRC_MASK | SIM_SOPT5_LPUART0RXSRC_MASK))) + /* LPUART0 Transmit Data Source Select: LPUART0_TX pin. */ + | SIM_SOPT5_LPUART0TXSRC(SOPT5_LPUART0TXSRC_LPUART_TX) + /* LPUART0 Receive Data Source Select: LPUART_RX pin. */ + | SIM_SOPT5_LPUART0RXSRC(SOPT5_LPUART0RXSRC_LPUART_RX)); + + BOARD_BootClockRUN(); + SystemCoreClockUpdate(); + CLOCK_SetLpuart0Clock(1); +} #endif /* BOARD_H_ */ diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.mk b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.mk index 82456b721..9cf36c500 100644 --- a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.mk +++ b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.mk @@ -8,9 +8,6 @@ CFLAGS += -Wno-error=unused-parameter -Wno-error=redundant-decls # All source paths should be relative to the top level. LD_FILE = $(MCU_DIR)/gcc/K32L2B31xxxxA_flash.ld -SRC_C += \ - $(MCU_DIR)/project_template/clock_config.c \ - # For flash-jlink target JLINK_DEVICE = K32L2B31xxxxA diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.c b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.c new file mode 100644 index 000000000..86eb42ef8 --- /dev/null +++ b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.c @@ -0,0 +1,220 @@ +/* + * Copyright 2019 ,2021 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ +/* + * How to setup clock using clock driver functions: + * + * 1. CLOCK_SetSimSafeDivs, to make sure core clock, bus clock, flexbus clock + * and flash clock are in allowed range during clock mode switch. + * + * 2. Call CLOCK_Osc0Init to setup OSC clock, if it is used in target mode. + * + * 3. Call CLOCK_SetMcgliteConfig to set MCG_Lite configuration. + * + * 4. Call CLOCK_SetSimConfig to set the clock configuration in SIM. + */ + +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Clocks v7.0 +processor: K32L2B31xxxxA +package_id: K32L2B31VLH0A +mcu_data: ksdk2_0 +processor_version: 9.0.0 +board: FRDM-K32L2B + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +#include "fsl_smc.h" +#include "clock_config.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define OSC_CAP0P 0U /*!< Oscillator 0pF capacitor load */ +#define OSC_ER_CLK_DISABLE 0U /*!< Disable external reference clock */ +#define SIM_OSC32KSEL_OSC32KCLK_CLK 0U /*!< OSC32KSEL select: OSC32KCLK clock */ + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* System clock frequency. */ +//extern uint32_t SystemCoreClock; + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ +void BOARD_InitBootClocks(void) +{ + BOARD_BootClockRUN(); +} + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockRUN +called_from_default_init: true +outputs: +- {id: Bus_clock.outFreq, value: 24 MHz} +- {id: Core_clock.outFreq, value: 48 MHz} +- {id: Flash_clock.outFreq, value: 24 MHz} +- {id: LPO_clock.outFreq, value: 1 kHz} +- {id: MCGIRCLK.outFreq, value: 8 MHz} +- {id: MCGPCLK.outFreq, value: 48 MHz} +- {id: System_clock.outFreq, value: 48 MHz} +settings: +- {id: MCGMode, value: HIRC} +- {id: MCG.CLKS.sel, value: MCG.HIRC} +- {id: MCG_C2_OSC_MODE_CFG, value: ModeOscLowPower} +- {id: MCG_C2_RANGE0_CFG, value: Very_high} +- {id: MCG_MC_HIRCEN_CFG, value: Enabled} +- {id: OSC0_CR_ERCLKEN_CFG, value: Enabled} +- {id: OSC_CR_ERCLKEN_CFG, value: Enabled} +- {id: SIM.CLKOUTSEL.sel, value: MCG.MCGPCLK} +- {id: SIM.COPCLKSEL.sel, value: OSC.OSCERCLK} +- {id: SIM.FLEXIOSRCSEL.sel, value: MCG.MCGPCLK} +- {id: SIM.LPUART0SRCSEL.sel, value: MCG.MCGPCLK} +- {id: SIM.LPUART1SRCSEL.sel, value: MCG.MCGPCLK} +- {id: SIM.RTCCLKOUTSEL.sel, value: OSC.OSCERCLK} +- {id: SIM.TPMSRCSEL.sel, value: MCG.MCGPCLK} +- {id: SIM.USBSRCSEL.sel, value: MCG.MCGPCLK} +sources: +- {id: MCG.HIRC.outFreq, value: 48 MHz} +- {id: OSC.OSC.outFreq, value: 32 MHz} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockRUN configuration + ******************************************************************************/ +const mcglite_config_t mcgliteConfig_BOARD_BootClockRUN = + { + .outSrc = kMCGLITE_ClkSrcHirc, /* MCGOUTCLK source is HIRC */ + .irclkEnableMode = kMCGLITE_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */ + .ircs = kMCGLITE_Lirc8M, /* Slow internal reference (LIRC) 8 MHz clock selected */ + .fcrdiv = kMCGLITE_LircDivBy1, /* Low-frequency Internal Reference Clock Divider: divided by 1 */ + .lircDiv2 = kMCGLITE_LircDivBy1, /* Second Low-frequency Internal Reference Clock Divider: divided by 1 */ + .hircEnableInNotHircMode = true, /* HIRC source is enabled */ + }; +const sim_clock_config_t simConfig_BOARD_BootClockRUN = + { + .er32kSrc = SIM_OSC32KSEL_OSC32KCLK_CLK, /* OSC32KSEL select: OSC32KCLK clock */ + .clkdiv1 = 0x10000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV4: /2 */ + }; +const osc_config_t oscConfig_BOARD_BootClockRUN = + { + .freq = 0U, /* Oscillator frequency: 0Hz */ + .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ + .workMode = kOSC_ModeOscLowPower, /* Oscillator low power */ + .oscerConfig = + { + .enableMode = kOSC_ErClkEnable, /* Enable external reference clock, disable external reference clock in STOP mode */ + } + }; + +/******************************************************************************* + * Code for BOARD_BootClockRUN configuration + ******************************************************************************/ +void BOARD_BootClockRUN(void) +{ + /* Set the system clock dividers in SIM to safe value. */ + CLOCK_SetSimSafeDivs(); + /* Set MCG to HIRC mode. */ + CLOCK_SetMcgliteConfig(&mcgliteConfig_BOARD_BootClockRUN); + /* Set the clock configuration in SIM module. */ + CLOCK_SetSimConfig(&simConfig_BOARD_BootClockRUN); + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; +} + +/******************************************************************************* + ********************* Configuration BOARD_BootClockVLPR *********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockVLPR +outputs: +- {id: Bus_clock.outFreq, value: 1 MHz} +- {id: Core_clock.outFreq, value: 2 MHz} +- {id: Flash_clock.outFreq, value: 1 MHz} +- {id: LPO_clock.outFreq, value: 1 kHz} +- {id: MCGIRCLK.outFreq, value: 2 MHz} +- {id: System_clock.outFreq, value: 2 MHz} +settings: +- {id: MCGMode, value: LIRC2M} +- {id: powerMode, value: VLPR} +- {id: MCG_C2_OSC_MODE_CFG, value: ModeOscLowPower} +- {id: RTCCLKOUTConfig, value: 'yes'} +- {id: SIM.OUTDIV4.scale, value: '2', locked: true} +- {id: SIM.RTCCLKOUTSEL.sel, value: OSC.OSCERCLK} +sources: +- {id: MCG.LIRC.outFreq, value: 2 MHz} +- {id: OSC.OSC.outFreq, value: 32.768 kHz} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockVLPR configuration + ******************************************************************************/ +const mcglite_config_t mcgliteConfig_BOARD_BootClockVLPR = + { + .outSrc = kMCGLITE_ClkSrcLirc, /* MCGOUTCLK source is LIRC */ + .irclkEnableMode = kMCGLITE_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */ + .ircs = kMCGLITE_Lirc2M, /* Slow internal reference (LIRC) 2 MHz clock selected */ + .fcrdiv = kMCGLITE_LircDivBy1, /* Low-frequency Internal Reference Clock Divider: divided by 1 */ + .lircDiv2 = kMCGLITE_LircDivBy1, /* Second Low-frequency Internal Reference Clock Divider: divided by 1 */ + .hircEnableInNotHircMode = false, /* HIRC source is not enabled */ + }; +const sim_clock_config_t simConfig_BOARD_BootClockVLPR = + { + .er32kSrc = SIM_OSC32KSEL_OSC32KCLK_CLK, /* OSC32KSEL select: OSC32KCLK clock */ + .clkdiv1 = 0x10000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV4: /2 */ + }; +const osc_config_t oscConfig_BOARD_BootClockVLPR = + { + .freq = 0U, /* Oscillator frequency: 0Hz */ + .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ + .workMode = kOSC_ModeOscLowPower, /* Oscillator low power */ + .oscerConfig = + { + .enableMode = OSC_ER_CLK_DISABLE, /* Disable external reference clock */ + } + }; + +/******************************************************************************* + * Code for BOARD_BootClockVLPR configuration + ******************************************************************************/ +void BOARD_BootClockVLPR(void) +{ + /* Set the system clock dividers in SIM to safe value. */ + CLOCK_SetSimSafeDivs(); + /* Set MCG to LIRC2M mode. */ + CLOCK_SetMcgliteConfig(&mcgliteConfig_BOARD_BootClockVLPR); + /* Set the clock configuration in SIM module. */ + CLOCK_SetSimConfig(&simConfig_BOARD_BootClockVLPR); + /* Set VLPR power mode. */ + SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); +#if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI) + SMC_SetPowerModeVlpr(SMC, false); +#else + SMC_SetPowerModeVlpr(SMC); +#endif + while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateVlpr) + { + } + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKVLPR_CORE_CLOCK; +} diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.h b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.h new file mode 100644 index 000000000..37328e7d8 --- /dev/null +++ b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.h @@ -0,0 +1,110 @@ +/* + * Copyright 2019 ,2021 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockRUN configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ + +/*! @brief MCG lite set for BOARD_BootClockRUN configuration. + */ +extern const mcglite_config_t mcgliteConfig_BOARD_BootClockRUN; +/*! @brief SIM module set for BOARD_BootClockRUN configuration. + */ +extern const sim_clock_config_t simConfig_BOARD_BootClockRUN; +/*! @brief OSC set for BOARD_BootClockRUN configuration. + */ +extern const osc_config_t oscConfig_BOARD_BootClockRUN; + +/******************************************************************************* + * API for BOARD_BootClockRUN configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************* Configuration BOARD_BootClockVLPR *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockVLPR configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKVLPR_CORE_CLOCK 2000000U /*!< Core clock frequency: 2000000Hz */ + +/*! @brief MCG lite set for BOARD_BootClockVLPR configuration. + */ +extern const mcglite_config_t mcgliteConfig_BOARD_BootClockVLPR; +/*! @brief SIM module set for BOARD_BootClockVLPR configuration. + */ +extern const sim_clock_config_t simConfig_BOARD_BootClockVLPR; +/*! @brief OSC set for BOARD_BootClockVLPR configuration. + */ +extern const osc_config_t oscConfig_BOARD_BootClockVLPR; + +/******************************************************************************* + * API for BOARD_BootClockVLPR configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockVLPR(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ diff --git a/hw/bsp/kinetis_k32l2/boards/kuiic/board.cmake b/hw/bsp/kinetis_k32l2/boards/kuiic/board.cmake new file mode 100644 index 000000000..cf14000ac --- /dev/null +++ b/hw/bsp/kinetis_k32l2/boards/kuiic/board.cmake @@ -0,0 +1,15 @@ +set(MCU_VARIANT K32L2B31A) + +set(JLINK_DEVICE K32L2B31xxxxA) +set(PYOCD_TARGET K32L2B) + +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/kuiic.ld) + +function(update_board TARGET) + target_sources(${TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clock_config.c + ) + target_compile_definitions(${TARGET} PUBLIC + CPU_K32L2B31VLH0A + ) +endfunction() diff --git a/hw/bsp/kinetis_k32l2/boards/kuiic/board.h b/hw/bsp/kinetis_k32l2/boards/kuiic/board.h index 1e2d4f18b..ec3702376 100644 --- a/hw/bsp/kinetis_k32l2/boards/kuiic/board.h +++ b/hw/bsp/kinetis_k32l2/boards/kuiic/board.h @@ -30,6 +30,8 @@ #include "fsl_device_registers.h" +#define USB_CLOCK_SOURCE kCLOCK_UsbSrcIrc48M + // LED #define LED_PIN_CLOCK kCLOCK_PortA #define LED_GPIO GPIOA @@ -42,4 +44,22 @@ #define UART_PIN_RX 3u #define UART_PIN_TX 0u +#define UART_CLOCK_SOURCE_HZ CLOCK_GetFreq(kCLOCK_McgIrc48MClk) + +static inline void BOARD_InitBootPins(void) { + /* PORTC3 is configured as LPUART0_RX */ + PORT_SetPinMux(PORTC, 3U, kPORT_MuxAlt3); + /* PORTA2 (pin 24) is configured as LPUART0_TX */ + PORT_SetPinMux(PORTE, 0U, kPORT_MuxAlt3); + + SIM->SOPT5 = ((SIM->SOPT5 & + /* Mask bits to zero which are setting */ + (~(SIM_SOPT5_LPUART1TXSRC_MASK | SIM_SOPT5_LPUART1RXSRC_MASK))) + /* LPUART0 Transmit Data Source Select: LPUART0_TX pin. */ + | SIM_SOPT5_LPUART1TXSRC(SOPT5_LPUART1TXSRC_LPUART_TX) + /* LPUART0 Receive Data Source Select: LPUART_RX pin. */ + | SIM_SOPT5_LPUART1RXSRC(SOPT5_LPUART1RXSRC_LPUART_RX)); + CLOCK_SetLpuart1Clock(1); +} + #endif /* BOARD_H_ */ diff --git a/hw/bsp/kinetis_k32l2/boards/kuiic/board.mk b/hw/bsp/kinetis_k32l2/boards/kuiic/board.mk index fc5bdeec8..2bc5b1e34 100644 --- a/hw/bsp/kinetis_k32l2/boards/kuiic/board.mk +++ b/hw/bsp/kinetis_k32l2/boards/kuiic/board.mk @@ -6,7 +6,7 @@ CFLAGS += -DCPU_K32L2B31VLH0A CFLAGS += -Wno-error=unused-parameter -Wno-error=redundant-decls # All source paths should be relative to the top level. -LD_FILE = $(BOARD_PATH)/K32L2B31xxxxA_flash.ld +LD_FILE = $(BOARD_PATH)/kuiic.ld # For flash-jlink target JLINK_DEVICE = K32L2B31xxxxA diff --git a/hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.c b/hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.c new file mode 100644 index 000000000..c1a6d1a8d --- /dev/null +++ b/hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.c @@ -0,0 +1,39 @@ +#include "clock_config.h" +#include "fsl_clock.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* System clock frequency. */ +// extern uint32_t SystemCoreClock; + +/******************************************************************************* + * Variables for BOARD_BootClockRUN configuration + ******************************************************************************/ +const mcglite_config_t mcgliteConfig_BOARD_BootClockRUN = { + .outSrc = kMCGLITE_ClkSrcHirc, /* MCGOUTCLK source is HIRC */ + .irclkEnableMode = kMCGLITE_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */ + .ircs = kMCGLITE_Lirc8M, /* Slow internal reference (LIRC) 8 MHz clock selected */ + .fcrdiv = kMCGLITE_LircDivBy1, /* Low-frequency Internal Reference Clock Divider: divided by 1 */ + .lircDiv2 = kMCGLITE_LircDivBy1, /* Second Low-frequency Internal Reference Clock Divider: divided by 1 */ + .hircEnableInNotHircMode = true, /* HIRC source is enabled */ +}; +const sim_clock_config_t simConfig_BOARD_BootClockRUN = { + .er32kSrc = SIM_OSC32KSEL_LPO_CLK, /* OSC32KSEL select: LPO clock */ + .clkdiv1 = 0x10000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV4: /2 */ +}; + +/******************************************************************************* + * Code for BOARD_BootClockRUN configuration + ******************************************************************************/ +void BOARD_BootClockRUN(void) +{ + /* Set the system clock dividers in SIM to safe value. */ + CLOCK_SetSimSafeDivs(); + /* Set MCG to HIRC mode. */ + CLOCK_SetMcgliteConfig(&mcgliteConfig_BOARD_BootClockRUN); + /* Set the clock configuration in SIM module. */ + CLOCK_SetSimConfig(&simConfig_BOARD_BootClockRUN); + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; +} diff --git a/hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.h b/hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.h new file mode 100644 index 000000000..920cad98f --- /dev/null +++ b/hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.h @@ -0,0 +1,14 @@ +#ifndef CLOCK_CONFIG_H +#define CLOCK_CONFIG_H + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define SIM_OSC32KSEL_LPO_CLK 3U /*!< OSC32KSEL select: LPO clock */ +#define SOPT5_LPUART1RXSRC_LPUART_RX 0x00u /*!<@brief LPUART1 Receive Data Source Select: LPUART_RX pin */ +#define SOPT5_LPUART1TXSRC_LPUART_TX 0x00u /*!<@brief LPUART1 Transmit Data Source Select: LPUART_TX pin */ +#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ + +void BOARD_BootClockRUN(void); + +#endif diff --git a/hw/bsp/kinetis_k32l2/boards/kuiic/kuiic.c b/hw/bsp/kinetis_k32l2/boards/kuiic/kuiic.c deleted file mode 100644 index b83d5c820..000000000 --- a/hw/bsp/kinetis_k32l2/boards/kuiic/kuiic.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2018, hathach (tinyusb.org) - * Copyright (c) 2020, Koji Kitayama - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#include "bsp/board_api.h" -#include "board.h" -#include "fsl_smc.h" -#include "fsl_gpio.h" -#include "fsl_port.h" -#include "fsl_clock.h" -#include "fsl_lpuart.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ -#define SIM_OSC32KSEL_LPO_CLK 3U /*!< OSC32KSEL select: LPO clock */ -#define SOPT5_LPUART1RXSRC_LPUART_RX 0x00u /*!<@brief LPUART1 Receive Data Source Select: LPUART_RX pin */ -#define SOPT5_LPUART1TXSRC_LPUART_TX 0x00u /*!<@brief LPUART1 Transmit Data Source Select: LPUART_TX pin */ -#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ - -/******************************************************************************* - * Variables - ******************************************************************************/ -/* System clock frequency. */ -// extern uint32_t SystemCoreClock; - -/******************************************************************************* - * Variables for BOARD_BootClockRUN configuration - ******************************************************************************/ -const mcglite_config_t mcgliteConfig_BOARD_BootClockRUN = { - .outSrc = kMCGLITE_ClkSrcHirc, /* MCGOUTCLK source is HIRC */ - .irclkEnableMode = kMCGLITE_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */ - .ircs = kMCGLITE_Lirc8M, /* Slow internal reference (LIRC) 8 MHz clock selected */ - .fcrdiv = kMCGLITE_LircDivBy1, /* Low-frequency Internal Reference Clock Divider: divided by 1 */ - .lircDiv2 = kMCGLITE_LircDivBy1, /* Second Low-frequency Internal Reference Clock Divider: divided by 1 */ - .hircEnableInNotHircMode = true, /* HIRC source is enabled */ -}; -const sim_clock_config_t simConfig_BOARD_BootClockRUN = { - .er32kSrc = SIM_OSC32KSEL_LPO_CLK, /* OSC32KSEL select: LPO clock */ - .clkdiv1 = 0x10000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV4: /2 */ -}; - -/******************************************************************************* - * Code for BOARD_BootClockRUN configuration - ******************************************************************************/ -void BOARD_BootClockRUN(void) -{ - /* Set the system clock dividers in SIM to safe value. */ - CLOCK_SetSimSafeDivs(); - /* Set MCG to HIRC mode. */ - CLOCK_SetMcgliteConfig(&mcgliteConfig_BOARD_BootClockRUN); - /* Set the clock configuration in SIM module. */ - CLOCK_SetSimConfig(&simConfig_BOARD_BootClockRUN); - /* Set SystemCoreClock variable. */ - SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; -} - - -//--------------------------------------------------------------------+ -// Forward USB interrupt events to TinyUSB IRQ Handler -//--------------------------------------------------------------------+ -void USB0_IRQHandler(void) -{ - tud_int_handler(0); -} - -void board_init(void) -{ - /* Enable port clocks for GPIO pins */ - CLOCK_EnableClock(kCLOCK_PortA); - CLOCK_EnableClock(kCLOCK_PortB); - CLOCK_EnableClock(kCLOCK_PortC); - CLOCK_EnableClock(kCLOCK_PortD); - CLOCK_EnableClock(kCLOCK_PortE); - - - gpio_pin_config_t led_config = { kGPIO_DigitalOutput, 1 }; - GPIO_PinInit(GPIOA, 1U, &led_config); - PORT_SetPinMux(PORTA, 1U, kPORT_MuxAsGpio); - led_config.outputLogic = 0; - GPIO_PinInit(GPIOA, 2U, &led_config); - PORT_SetPinMux(PORTA, 2U, kPORT_MuxAsGpio); - -#ifdef BUTTON_PIN - gpio_pin_config_t button_config = { kGPIO_DigitalInput, 0 }; - GPIO_PinInit(BUTTON_GPIO, BUTTON_PIN, &button_config); - const port_pin_config_t BUTTON_CFG = { - kPORT_PullUp, - kPORT_FastSlewRate, - kPORT_PassiveFilterDisable, - kPORT_LowDriveStrength, - kPORT_MuxAsGpio - }; - PORT_SetPinConfig(BUTTON_PORT, BUTTON_PIN, &BUTTON_CFG); -#endif - - /* PORTC3 is configured as LPUART0_RX */ - PORT_SetPinMux(PORTC, 3U, kPORT_MuxAlt3); - /* PORTA2 (pin 24) is configured as LPUART0_TX */ - PORT_SetPinMux(PORTE, 0U, kPORT_MuxAlt3); - - SIM->SOPT5 = ((SIM->SOPT5 & - /* Mask bits to zero which are setting */ - (~(SIM_SOPT5_LPUART1TXSRC_MASK | SIM_SOPT5_LPUART1RXSRC_MASK))) - /* LPUART0 Transmit Data Source Select: LPUART0_TX pin. */ - | SIM_SOPT5_LPUART1TXSRC(SOPT5_LPUART1TXSRC_LPUART_TX) - /* LPUART0 Receive Data Source Select: LPUART_RX pin. */ - | SIM_SOPT5_LPUART1RXSRC(SOPT5_LPUART1RXSRC_LPUART_RX)); - - BOARD_BootClockRUN(); - SystemCoreClockUpdate(); - CLOCK_SetLpuart1Clock(1); - -#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(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); -#endif - - lpuart_config_t uart_config; - LPUART_GetDefaultConfig(&uart_config); - uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE; - uart_config.enableTx = true; - uart_config.enableRx = true; - LPUART_Init(UART_PORT, &uart_config, CLOCK_GetFreq(kCLOCK_McgIrc48MClk)); - - // USB - CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcIrc48M, 48000000U); -} - -//--------------------------------------------------------------------+ -// Board porting API -//--------------------------------------------------------------------+ - -void board_led_write(bool state) -{ - if (state) { - LED_GPIO->PDDR |= GPIO_FIT_REG((1UL << LED_PIN)); - } else { - LED_GPIO->PDDR &= GPIO_FIT_REG(~(1UL << LED_PIN)); - } -// GPIO_PinWrite(GPIOA, 1, state ? LED_STATE_ON : (1-LED_STATE_ON) ); -// GPIO_PinWrite(GPIOA, 2, state ? (1-LED_STATE_ON) : LED_STATE_ON ); -} - -uint32_t board_button_read(void) -{ -#ifdef BUTTON_PIN - return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_GPIO, BUTTON_PIN); -#else - return 0; -#endif -} - -int board_uart_read(uint8_t* buf, int len) -{ - LPUART_ReadBlocking(UART_PORT, buf, len); - return len; -} - -int board_uart_write(void const * buf, int len) -{ - LPUART_WriteBlocking(UART_PORT, (uint8_t const*) buf, len); - return len; -} - -#if CFG_TUSB_OS == OPT_OS_NONE -volatile uint32_t system_ticks = 0; -void SysTick_Handler(void) -{ - system_ticks++; -} - -uint32_t board_millis(void) -{ - return system_ticks; -} -#endif diff --git a/hw/bsp/kinetis_k32l2/boards/kuiic/K32L2B31xxxxA_flash.ld b/hw/bsp/kinetis_k32l2/boards/kuiic/kuiic.ld similarity index 100% rename from hw/bsp/kinetis_k32l2/boards/kuiic/K32L2B31xxxxA_flash.ld rename to hw/bsp/kinetis_k32l2/boards/kuiic/kuiic.ld diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/frdm_k32l2a4s.c b/hw/bsp/kinetis_k32l2/family.c similarity index 60% rename from hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/frdm_k32l2a4s.c rename to hw/bsp/kinetis_k32l2/family.c index 39783b7e1..92f5ba6d3 100644 --- a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/frdm_k32l2a4s.c +++ b/hw/bsp/kinetis_k32l2/family.c @@ -25,77 +25,57 @@ * This file is part of the TinyUSB stack. */ -#include "bsp/board_api.h" -#include "board.h" #include "fsl_gpio.h" #include "fsl_port.h" #include "fsl_clock.h" #include "fsl_lpuart.h" #include "clock_config.h" +#include "bsp/board_api.h" +#include "board.h" + //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ -void USB0_IRQHandler(void) -{ +void USB0_IRQHandler(void) { tud_int_handler(0); } -void board_init(void) -{ - /* Enable port clocks for UART/LED/Button pins */ - CLOCK_EnableClock(UART_PIN_CLOCK); - CLOCK_EnableClock(LED_PIN_CLOCK); - CLOCK_EnableClock(BUTTON_PIN_CLOCK); +void board_init(void) { + /* Enable port clocks for GPIO pins */ + CLOCK_EnableClock(kCLOCK_PortA); + CLOCK_EnableClock(kCLOCK_PortB); + CLOCK_EnableClock(kCLOCK_PortC); + CLOCK_EnableClock(kCLOCK_PortD); + CLOCK_EnableClock(kCLOCK_PortE); - gpio_pin_config_t led_config = { kGPIO_DigitalOutput, 0 }; + BOARD_InitBootPins(); + BOARD_BootClockRUN(); + SystemCoreClockUpdate(); + + gpio_pin_config_t led_config = {kGPIO_DigitalOutput, 0}; GPIO_PinInit(LED_GPIO, LED_PIN, &led_config); PORT_SetPinMux(LED_PORT, LED_PIN, kPORT_MuxAsGpio); - gpio_pin_config_t button_config = { kGPIO_DigitalInput, 0 }; +#ifdef BUTTON_PIN + gpio_pin_config_t button_config = {kGPIO_DigitalInput, 0}; GPIO_PinInit(BUTTON_GPIO, BUTTON_PIN, &button_config); const port_pin_config_t BUTTON_CFG = { - kPORT_PullUp, - kPORT_FastSlewRate, - kPORT_PassiveFilterDisable, - kPORT_OpenDrainDisable, - kPORT_LowDriveStrength, - kPORT_MuxAsGpio, - kPORT_UnlockRegister + kPORT_PullUp, + kPORT_FastSlewRate, + kPORT_PassiveFilterDisable, +#if defined(FSL_FEATURE_PORT_HAS_OPEN_DRAIN) && FSL_FEATURE_PORT_HAS_OPEN_DRAIN + kPORT_OpenDrainDisable, +#endif + kPORT_LowDriveStrength, + kPORT_MuxAsGpio, +#if defined(FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK) && FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK + kPORT_UnlockRegister +#endif }; PORT_SetPinConfig(BUTTON_PORT, BUTTON_PIN, &BUTTON_CFG); - - /* - Enable LPUART0 clock and configure port pins. - FIR clock is being used so the USB examples work. - */ - PCC_LPUART0 = 0U; /* Clock must be off to set PCS */ - PCC_LPUART0 = PCC_CLKCFG_PCS( 3U ); /* Select the clock. 1:OSCCLK/Bus Clock, 2:Slow IRC, 3: Fast IRC, 6: System PLL */ - PCC_LPUART0 |= PCC_CLKCFG_CGC( 1U ); /* Enable LPUART */ - - /* PORTB16 (pin 62) is configured as LPUART0_RX */ - gpio_pin_config_t const lpuart_config_rx = { kGPIO_DigitalInput, 0 }; - GPIO_PinInit(UART_PIN_GPIO, UART_PIN_RX, &lpuart_config_rx); - const port_pin_config_t UART_CFG = { - kPORT_PullUp, - kPORT_FastSlewRate, - kPORT_PassiveFilterDisable, - kPORT_OpenDrainDisable, - kPORT_LowDriveStrength, - kPORT_MuxAsGpio, - kPORT_UnlockRegister - }; - PORT_SetPinConfig(UART_PIN_PORT, UART_PIN_RX, &UART_CFG); - PORT_SetPinMux( UART_PIN_PORT, UART_PIN_RX, kPORT_MuxAlt3); - - /* PORTB17 (pin 63) is configured as LPUART0_TX */ - gpio_pin_config_t const lpuart_config_tx = { kGPIO_DigitalOutput, 0 }; - GPIO_PinInit( UART_PIN_GPIO, UART_PIN_TX, &lpuart_config_tx); - PORT_SetPinMux( UART_PIN_PORT, UART_PIN_TX, kPORT_MuxAlt3); - - BOARD_BootClockRUN(); - SystemCoreClockUpdate(); +#endif #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer @@ -110,28 +90,29 @@ void board_init(void) uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE; uart_config.enableTx = true; uart_config.enableRx = true; - LPUART_Init(UART_PORT, &uart_config, CLOCK_GetFreq(kCLOCK_ScgFircClk)); + LPUART_Init(UART_PORT, &uart_config, UART_CLOCK_SOURCE_HZ); // USB - CLOCK_EnableUsbfs0Clock(kCLOCK_IpSrcFircAsync, 48000000U); + CLOCK_EnableUsbfs0Clock(USB_CLOCK_SOURCE, 48000000U); } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ -void board_led_write(bool state) -{ - GPIO_PinWrite(LED_GPIO, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +void board_led_write(bool state) { + GPIO_PinWrite(LED_GPIO, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { +#ifdef BUTTON_PIN return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_GPIO, BUTTON_PIN); +#else + return 0; +#endif } -int board_uart_read(uint8_t* buf, int len) -{ +int board_uart_read(uint8_t* buf, int len) { #if 0 /* Use this version if want the LED to blink during BOARD=board_test, without having to hit a key. @@ -151,21 +132,39 @@ int board_uart_read(uint8_t* buf, int len) #endif } -int board_uart_write(void const * buf, int len) -{ +int board_uart_write(void const* buf, int len) { LPUART_WriteBlocking(UART_PORT, (uint8_t const*) buf, len); return len; } #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 + +#ifndef __ICCARM__ +// Implement _start() since we use linker flag '-nostartfiles'. +// Requires defined __STARTUP_CLEAR_BSS, +extern int main(void); + +TU_ATTR_UNUSED void _start(void) { + // called by startup code + main(); + while (1) {} +} + +#ifdef __clang__ +void _exit (int __status) { + while (1) {} +} +#endif + #endif diff --git a/hw/bsp/kinetis_k32l2/family.cmake b/hw/bsp/kinetis_k32l2/family.cmake new file mode 100644 index 000000000..406ae99d3 --- /dev/null +++ b/hw/bsp/kinetis_k32l2/family.cmake @@ -0,0 +1,112 @@ +include_guard() + +set(SDK_DIR ${TOP}/hw/mcu/nxp/mcux-sdk) +set(CMSIS_DIR ${TOP}/lib/CMSIS_5) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR cortex-m0plus CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS KINETIS_K32L 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 () + + # LD_FILE and STARTUP_FILE can be defined in board.cmake + set(LD_FILE_Clang ${LD_FILE_GNU}) + set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_VARIANT}.S) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ${SDK_DIR}/drivers/gpio/fsl_gpio.c + ${SDK_DIR}/drivers/lpuart/fsl_lpuart.c + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c + ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_VARIANT}.c + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + __STARTUP_CLEAR_BSS + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMSIS_DIR}/CMSIS/Core/Include + ${SDK_DIR}/devices/${MCU_VARIANT} + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers + ${SDK_DIR}/drivers/common + ${SDK_DIR}/drivers/gpio + ${SDK_DIR}/drivers/lpuart + ${SDK_DIR}/drivers/port + ${SDK_DIR}/drivers/smc + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + --specs=nosys.specs --specs=nano.specs + -nostartfiles + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + ) + 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_KINETIS_K32L ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/nxp/khci/dcd_khci.c + ${TOP}/src/portable/nxp/khci/hcd_khci.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}) + + if (DEFINED TEENSY_MCU) + family_add_bin_hex(${TARGET}) + family_flash_teensy(${TARGET}) + endif () +endfunction() diff --git a/hw/bsp/kinetis_k32l2/family.mk b/hw/bsp/kinetis_k32l2/family.mk index 357485762..e18348d4d 100644 --- a/hw/bsp/kinetis_k32l2/family.mk +++ b/hw/bsp/kinetis_k32l2/family.mk @@ -1,6 +1,5 @@ UF2_FAMILY_ID = 0x7f83e793 SDK_DIR = hw/mcu/nxp/mcux-sdk -DEPS_SUBMODULES += $(SDK_DIR) lib/CMSIS_5 MCU_DIR = $(SDK_DIR)/devices/$(MCU) include $(TOP)/$(BOARD_PATH)/board.mk @@ -9,6 +8,10 @@ CPU_CORE ?= cortex-m0plus CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_KINETIS_K32L +LDFLAGS_GCC += \ + -nostartfiles \ + -specs=nosys.specs -specs=nano.specs + SRC_C += \ src/portable/nxp/khci/dcd_khci.c \ src/portable/nxp/khci/hcd_khci.c \ @@ -23,10 +26,10 @@ INC += \ $(TOP)/$(MCU_DIR) \ $(TOP)/$(MCU_DIR)/project_template \ $(TOP)/$(MCU_DIR)/drivers \ - $(TOP)/$(SDK_DIR)/drivers/smc \ $(TOP)/$(SDK_DIR)/drivers/common \ $(TOP)/$(SDK_DIR)/drivers/gpio \ - $(TOP)/$(SDK_DIR)/drivers/port \ $(TOP)/$(SDK_DIR)/drivers/lpuart \ + $(TOP)/$(SDK_DIR)/drivers/port \ + $(TOP)/$(SDK_DIR)/drivers/smc \ SRC_S += $(MCU_DIR)/gcc/startup_$(MCU).S diff --git a/hw/bsp/kinetis_kl/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/kinetis_kl/FreeRTOSConfig/FreeRTOSConfig.h index 2a2bce261..f2b3d649d 100644 --- a/hw/bsp/kinetis_kl/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/kinetis_kl/FreeRTOSConfig/FreeRTOSConfig.h @@ -73,14 +73,15 @@ #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 -#define configSUPPORT_STATIC_ALLOCATION 0 -#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 /* 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 +#define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 @@ -116,23 +117,6 @@ #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 diff --git a/hw/bsp/kinetis_kl/family.c b/hw/bsp/kinetis_kl/family.c index 3e9aa83a4..254a95176 100644 --- a/hw/bsp/kinetis_kl/family.c +++ b/hw/bsp/kinetis_kl/family.c @@ -39,7 +39,7 @@ void USB0_IRQHandler(void) { #if CFG_TUH_ENABLED - tuh_int_handler(0); + tuh_int_handler(0, true); #endif #if CFG_TUD_ENABLED tud_int_handler(0); @@ -141,3 +141,22 @@ uint32_t board_millis(void) return system_ticks; } #endif + + +#ifndef __ICCARM__ +// Implement _start() since we use linker flag '-nostartfiles'. +// Requires defined __STARTUP_CLEAR_BSS, +extern int main(void); +TU_ATTR_UNUSED void _start(void) { + // called by startup code + main(); + while (1) {} +} + +#ifdef __clang__ +void _exit (int __status) { + while (1) {} +} +#endif + +#endif diff --git a/hw/bsp/kinetis_kl/family.cmake b/hw/bsp/kinetis_kl/family.cmake index 793ef1783..85a913d54 100644 --- a/hw/bsp/kinetis_kl/family.cmake +++ b/hw/bsp/kinetis_kl/family.cmake @@ -12,7 +12,7 @@ include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_PROCESSOR cortex-m0plus CACHE INTERNAL "System Processor") -set(CMAKE_TOOLCHAIN_FILE ${TOP}/tools/cmake/toolchain/arm_${TOOLCHAIN}.cmake) +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS KINETIS_KL CACHE INTERNAL "") @@ -22,48 +22,52 @@ set(FAMILY_MCUS KINETIS_KL 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 - ${SDK_DIR}/drivers/gpio/fsl_gpio.c - ${SDK_DIR}/drivers/lpsci/fsl_lpsci.c - ${SDK_DIR}/drivers/uart/fsl_uart.c - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c - ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_VARIANT}.c - ) - target_compile_definitions(${BOARD_TARGET} PUBLIC - ) - target_include_directories(${BOARD_TARGET} PUBLIC - ${CMSIS_DIR}/CMSIS/Core/Include - ${SDK_DIR}/devices/${MCU_VARIANT} - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers - ${SDK_DIR}/drivers/common - ${SDK_DIR}/drivers/gpio - ${SDK_DIR}/drivers/lpsci - ${SDK_DIR}/drivers/port - ${SDK_DIR}/drivers/smc - ${SDK_DIR}/drivers/uart - ) + if (TARGET ${BOARD_TARGET}) + return() + endif () - update_board(${BOARD_TARGET}) + # LD_FILE and STARTUP_FILE can be defined in board.cmake + set(LD_FILE_Clang ${LD_FILE_GNU}) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) - # LD_FILE and STARTUP_FILE can be defined in board.cmake + add_library(${BOARD_TARGET} STATIC + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ${SDK_DIR}/drivers/gpio/fsl_gpio.c + ${SDK_DIR}/drivers/lpsci/fsl_lpsci.c + ${SDK_DIR}/drivers/uart/fsl_uart.c + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c + ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_VARIANT}.c + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + __STARTUP_CLEAR_BSS + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMSIS_DIR}/CMSIS/Core/Include + ${SDK_DIR}/devices/${MCU_VARIANT} + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers + ${SDK_DIR}/drivers/common + ${SDK_DIR}/drivers/gpio + ${SDK_DIR}/drivers/lpsci + ${SDK_DIR}/drivers/port + ${SDK_DIR}/drivers/smc + ${SDK_DIR}/drivers/uart + ) + update_board(${BOARD_TARGET}) - 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}" + --specs=nosys.specs --specs=nano.specs + -nostartfiles + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" ) - - 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 () endif () endfunction() @@ -104,5 +108,4 @@ function(family_configure_example TARGET RTOS) # Flashing family_flash_jlink(${TARGET}) - #family_flash_nxplink(${TARGET}) endfunction() diff --git a/hw/bsp/kinetis_kl/family.mk b/hw/bsp/kinetis_kl/family.mk index edb2f3366..1fdce981a 100644 --- a/hw/bsp/kinetis_kl/family.mk +++ b/hw/bsp/kinetis_kl/family.mk @@ -6,9 +6,12 @@ include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m0plus CFLAGS += \ + -D__STARTUP_CLEAR_BSS \ -DCFG_TUSB_MCU=OPT_MCU_KINETIS_KL \ LDFLAGS += \ + -nostartfiles \ + -specs=nosys.specs -specs=nano.specs \ -Wl,--defsym,__stack_size__=0x400 \ -Wl,--defsym,__heap_size__=0 diff --git a/hw/bsp/lpc11/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/lpc11/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..27b2d76f5 --- /dev/null +++ b/hw/bsp/lpc11/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,178 @@ +/* + * 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__ + #ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wunused-parameter" + #endif + + #include "chip.h" + + #ifdef __GNUC__ + #pragma GCC diagnostic pop + #endif +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#if defined(__ARM_FP) && __ARM_FP >= 4 + #define configENABLE_FPU 1 +#else + #define configENABLE_FPU 0 +#endif +#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 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* 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 2 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<= 4 + #define configENABLE_FPU 1 +#else + #define configENABLE_FPU 0 +#endif +#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 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* 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 3 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<= 4 + #define configENABLE_FPU 1 +#else + #define configENABLE_FPU 0 +#endif +#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 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* 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 3 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< RamLoc32 /* NOINIT section for RamAHB32 */ @@ -159,18 +159,36 @@ SECTIONS . = ALIGN(4) ; _end_noinit = .; } > RamLoc32 - PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .); + + /* hathach add heap section for clang */ + .heap (NOLOAD): { + __heap_start = .; + __HeapBase = .; + __heap_base = .; + __end = .; + PROVIDE(end = .); + PROVIDE(_end = .); + PROVIDE(__end__ = .); + KEEP(*(.heap*)) + __HeapLimit = .; + __heap_limit = .; + __heap_end = .; + } > RamLoc32 + +/* PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .);*/ PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_RamLoc32 - 0); /* ## Create checksum value (used in startup) ## */ + /* This cause issue with clang linker, so it is disabled */ + /* MemManage_Handler, BusFault_Handler, UsageFault_Handler may not be defined */ PROVIDE(__valid_user_code_checksum = 0 - (_vStackTop + (ResetISR + 1) + (NMI_Handler + 1) + (HardFault_Handler + 1) - + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1) /* MemManage_Handler may not be defined */ - + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1) /* BusFault_Handler may not be defined */ - + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1) /* UsageFault_Handler may not be defined */ + + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1) + + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1) + + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1) ) ); /* Provide basic symbols giving location and size of main text diff --git a/hw/bsp/lpc17/boards/lpcxpresso1769/lpcxpresso1769.c b/hw/bsp/lpc17/boards/lpcxpresso1769/lpcxpresso1769.c deleted file mode 100644 index c7d655368..000000000 --- a/hw/bsp/lpc17/boards/lpcxpresso1769/lpcxpresso1769.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2019 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. - */ - -#include "chip.h" -#include "bsp/board_api.h" - -//--------------------------------------------------------------------+ -// USB Interrupt Handler -//--------------------------------------------------------------------+ -void USB_IRQHandler(void) -{ - #if CFG_TUD_ENABLED - tud_int_handler(0); - #endif - - #if CFG_TUH_ENABLED - tuh_int_handler(0); - #endif -} - -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM -//--------------------------------------------------------------------+ -#define LED_PORT 0 -#define LED_PIN 22 -#define LED_STATE_ON 1 - -// JOYSTICK_DOWN if using LPCXpresso Base Board -#define BUTTON_PORT 0 -#define BUTTON_PIN 15 -#define BUTTON_STATE_ACTIVE 0 - -#define BOARD_UART_PORT LPC_UART3 - -/* 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[] = -{ - {0, 0, IOCON_MODE_INACT | IOCON_FUNC2}, /* TXD3 */ - {0, 1, IOCON_MODE_INACT | IOCON_FUNC2}, /* RXD3 */ - {LED_PORT, LED_PIN, IOCON_MODE_INACT | IOCON_FUNC0}, /* Led 0 */ - - /* Joystick buttons. */ -// {2, 3, IOCON_MODE_INACT | IOCON_FUNC0}, /* JOYSTICK_UP */ - {BUTTON_PORT, BUTTON_PIN, IOCON_FUNC0 | IOCON_MODE_PULLUP}, /* JOYSTICK_DOWN */ -// {2, 4, IOCON_MODE_INACT | IOCON_FUNC0}, /* JOYSTICK_LEFT */ -// {0, 16, IOCON_MODE_INACT | IOCON_FUNC0}, /* JOYSTICK_RIGHT */ -// {0, 17, IOCON_MODE_INACT | IOCON_FUNC0}, /* JOYSTICK_PRESS */ -}; - -static const PINMUX_GRP_T pin_usb_mux[] = -{ - {0, 29, IOCON_MODE_INACT | IOCON_FUNC1}, // D+ - {0, 30, IOCON_MODE_INACT | IOCON_FUNC1}, // D- - {2, 9, IOCON_MODE_INACT | IOCON_FUNC1}, // Soft Connect - - {1, 19, IOCON_MODE_INACT | IOCON_FUNC2}, // USB_PPWR (Host mode) - - // 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) -{ -#ifdef __USE_LPCOPEN - extern void (* const g_pfnVectors[])(void); - unsigned int *pSCB_VTOR = (unsigned int *) 0xE000ED08; - *pSCB_VTOR = (unsigned int) g_pfnVectors; -#endif - - Chip_IOCON_Init(LPC_IOCON); - Chip_IOCON_SetPinMuxing(LPC_IOCON, pinmuxing, sizeof(pinmuxing) / sizeof(PINMUX_GRP_T)); - Chip_SetupXtalClocking(); - - Chip_SYSCTL_SetFLASHAccess(FLASHTIM_100MHZ_CPU); -} - -void board_init(void) -{ - SystemCoreClockUpdate(); - -#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_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); -#endif - - Chip_GPIO_Init(LPC_GPIO); - - // LED - Chip_GPIO_SetPinDIROutput(LPC_GPIO, LED_PORT, LED_PIN); - - // Button - Chip_GPIO_SetPinDIRInput(LPC_GPIO, BUTTON_PORT, BUTTON_PIN); - -#if 0 - //------------- UART -------------// - PINSEL_CFG_Type PinCfg = - { - .Portnum = 0, - .Pinnum = 0, // TXD is P0.0 - .Funcnum = 2, - .OpenDrain = 0, - .Pinmode = 0 - }; - PINSEL_ConfigPin(&PinCfg); - - PinCfg.Portnum = 0; - PinCfg.Pinnum = 1; // RXD is P0.1 - PINSEL_ConfigPin(&PinCfg); - - UART_CFG_Type UARTConfigStruct; - UART_ConfigStructInit(&UARTConfigStruct); - UARTConfigStruct.Baud_rate = CFG_BOARD_UART_BAUDRATE; - - UART_Init(BOARD_UART_PORT, &UARTConfigStruct); - UART_TxCmd(BOARD_UART_PORT, ENABLE); // Enable UART Transmit -#endif - - //------------- USB -------------// - Chip_IOCON_SetPinMuxing(LPC_IOCON, pin_usb_mux, sizeof(pin_usb_mux) / sizeof(PINMUX_GRP_T)); - Chip_USB_Init(); - - enum { - USBCLK_DEVCIE = 0x12, // AHB + Device - USBCLK_HOST = 0x19, // AHB + Host + OTG -// 0x1B // Host + Device + OTG + AHB - }; - - uint32_t const clk_en = CFG_TUD_ENABLED ? USBCLK_DEVCIE : USBCLK_HOST; - - LPC_USB->OTGClkCtrl = clk_en; - while ( (LPC_USB->OTGClkSt & clk_en) != clk_en ); - -#if CFG_TUH_ENABLED - // set portfunc to host !!! - LPC_USB->StCtrl = 0x3; // should be 1 -#endif -} - -//--------------------------------------------------------------------+ -// Board porting API -//--------------------------------------------------------------------+ - -void board_led_write(bool state) -{ - Chip_GPIO_SetPinState(LPC_GPIO, LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); -} - -uint32_t board_button_read(void) -{ - return BUTTON_STATE_ACTIVE == Chip_GPIO_GetPinState(LPC_GPIO, BUTTON_PORT, BUTTON_PIN); -} - -int board_uart_read(uint8_t* buf, int len) -{ -// return UART_ReceiveByte(BOARD_UART_PORT); - (void) buf; (void) len; - return 0; -} - -int board_uart_write(void const * buf, int len) -{ -// UART_Send(BOARD_UART_PORT, &c, 1, BLOCKING); - (void) buf; (void) len; - return 0; -} - -#if CFG_TUSB_OS == OPT_OS_NONE -volatile uint32_t system_ticks = 0; -void SysTick_Handler (void) -{ - system_ticks++; -} - -uint32_t board_millis(void) -{ - return system_ticks; -} -#endif diff --git a/hw/bsp/lpc17/boards/mbed1768/board.cmake b/hw/bsp/lpc17/boards/mbed1768/board.cmake new file mode 100644 index 000000000..688f34292 --- /dev/null +++ b/hw/bsp/lpc17/boards/mbed1768/board.cmake @@ -0,0 +1,11 @@ +set(MCU_VARIANT LPC1768) + +set(JLINK_DEVICE LPC1768) +set(PYOCD_TARGET LPC1768) +set(NXPLINK_DEVICE LPC1768:LPC1768) + +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/lpc1768.ld) + +function(update_board TARGET) + # nothing to do +endfunction() diff --git a/hw/bsp/lpc17/boards/mbed1768/board.h b/hw/bsp/lpc17/boards/mbed1768/board.h new file mode 100644 index 000000000..2b3ddc905 --- /dev/null +++ b/hw/bsp/lpc17/boards/mbed1768/board.h @@ -0,0 +1,71 @@ +/* + * 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_PORT 1 +#define LED_PIN 18 +#define LED_STATE_ON 1 + +// JOYSTICK_DOWN if using LPCXpresso Base Board +#define BUTTON_PORT 0 +#define BUTTON_PIN 15 +#define BUTTON_STATE_ACTIVE 0 + +#define BOARD_UART_PORT LPC_UART3 + +/* System oscillator rate and RTC oscillator rate */ +const uint32_t OscRateIn = 10000000; +const uint32_t RTCOscRateIn = 32768; + +// Pin muxing configuration +static const PINMUX_GRP_T pinmuxing[] = { + {LED_PORT, LED_PIN, IOCON_MODE_INACT | IOCON_FUNC0}, + {BUTTON_PORT, BUTTON_PIN, IOCON_FUNC0 | IOCON_MODE_PULLUP}, +}; + +static const PINMUX_GRP_T pin_usb_mux[] = { + {0, 29, IOCON_MODE_INACT | IOCON_FUNC1}, // D+ + {0, 30, IOCON_MODE_INACT | IOCON_FUNC1}, // D- + {2, 9, IOCON_MODE_INACT | IOCON_FUNC1}, // Soft Connect + + {1, 19, IOCON_MODE_INACT | IOCON_FUNC2}, // USB_PPWR (Host mode) + {1, 22, IOCON_MODE_INACT | IOCON_FUNC2}, // USB_PWRD + + // 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 diff --git a/hw/bsp/lpc17/boards/mbed1768/lpc1768.ld b/hw/bsp/lpc17/boards/mbed1768/lpc1768.ld index 095bd3d92..a6c35c157 100644 --- a/hw/bsp/lpc17/boards/mbed1768/lpc1768.ld +++ b/hw/bsp/lpc17/boards/mbed1768/lpc1768.ld @@ -140,7 +140,7 @@ SECTIONS *(COMMON) . = ALIGN(4) ; _ebss = .; - PROVIDE(end = .); +/* PROVIDE(end = .);*/ } > RamLoc32 /* NOINIT section for RamAHB32 */ @@ -159,18 +159,36 @@ SECTIONS . = ALIGN(4) ; _end_noinit = .; } > RamLoc32 - PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .); + + /* hathach add heap section for clang */ + .heap (NOLOAD): { + __heap_start = .; + __HeapBase = .; + __heap_base = .; + __end = .; + PROVIDE(end = .); + PROVIDE(_end = .); + PROVIDE(__end__ = .); + KEEP(*(.heap*)) + __HeapLimit = .; + __heap_limit = .; + __heap_end = .; + } > RamLoc32 + +/* PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .);*/ PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_RamLoc32 - 0); /* ## Create checksum value (used in startup) ## */ + /* This cause issue with clang linker, so it is disabled */ + /* MemManage_Handler, BusFault_Handler, UsageFault_Handler may not be defined */ PROVIDE(__valid_user_code_checksum = 0 - (_vStackTop + (ResetISR + 1) + (NMI_Handler + 1) + (HardFault_Handler + 1) - + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1) /* MemManage_Handler may not be defined */ - + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1) /* BusFault_Handler may not be defined */ - + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1) /* UsageFault_Handler may not be defined */ + + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1) + + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1) + + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1) ) ); /* Provide basic symbols giving location and size of main text diff --git a/hw/bsp/lpc17/boards/mbed1768/mbed1768.c b/hw/bsp/lpc17/family.c similarity index 61% rename from hw/bsp/lpc17/boards/mbed1768/mbed1768.c rename to hw/bsp/lpc17/family.c index b2c92d640..79281ba41 100644 --- a/hw/bsp/lpc17/boards/mbed1768/mbed1768.c +++ b/hw/bsp/lpc17/family.c @@ -26,58 +26,24 @@ #include "chip.h" #include "bsp/board_api.h" - -#define LED_PORT 1 -#define LED_PIN 18 -#define LED_STATE_ON 1 - -// JOYSTICK_DOWN if using LPCXpresso Base Board -#define BUTTON_PORT 0 -#define BUTTON_PIN 15 -#define BUTTON_STATE_ACTIVE 0 - -#define BOARD_UART_PORT LPC_UART3 - -/* System oscillator rate and RTC oscillator rate */ -const uint32_t OscRateIn = 10000000; -const uint32_t RTCOscRateIn = 32768; - -/* Pin muxing configuration */ -static const PINMUX_GRP_T pinmuxing[] = -{ - {LED_PORT, LED_PIN, IOCON_MODE_INACT | IOCON_FUNC0}, - {BUTTON_PORT, BUTTON_PIN, IOCON_FUNC0 | IOCON_MODE_PULLUP}, -}; - -static const PINMUX_GRP_T pin_usb_mux[] = -{ - {0, 29, IOCON_MODE_INACT | IOCON_FUNC1}, // D+ - {0, 30, IOCON_MODE_INACT | IOCON_FUNC1}, // D- - {2, 9, IOCON_MODE_INACT | IOCON_FUNC1}, // Connect - - {1, 19, IOCON_MODE_INACT | IOCON_FUNC2}, // USB_PPWR - {1, 22, IOCON_MODE_INACT | IOCON_FUNC2}, // USB_PWRD - - /* 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 */ -}; +#include "board.h" // Invoked by startup code -void SystemInit(void) -{ +void SystemInit(void) { #ifdef __USE_LPCOPEN - extern void (* const g_pfnVectors[])(void); - unsigned int *pSCB_VTOR = (unsigned int *) 0xE000ED08; - *pSCB_VTOR = (unsigned int) g_pfnVectors; + extern void (* const g_pfnVectors[])(void); + unsigned int* pSCB_VTOR = (unsigned int*) 0xE000ED08; + *pSCB_VTOR = (unsigned int) g_pfnVectors; #endif Chip_IOCON_Init(LPC_IOCON); Chip_IOCON_SetPinMuxing(LPC_IOCON, pinmuxing, sizeof(pinmuxing) / sizeof(PINMUX_GRP_T)); Chip_SetupXtalClocking(); + + Chip_SYSCTL_SetFLASHAccess(FLASHTIM_100MHZ_CPU); } -void board_init(void) -{ +void board_init(void) { SystemCoreClockUpdate(); #if CFG_TUSB_OS == OPT_OS_NONE @@ -89,11 +55,7 @@ void board_init(void) #endif Chip_GPIO_Init(LPC_GPIO); - - // LED Chip_GPIO_SetPinDIROutput(LPC_GPIO, LED_PORT, LED_PIN); - - // Button Chip_GPIO_SetPinDIRInput(LPC_GPIO, BUTTON_PORT, BUTTON_PIN); #if 0 @@ -106,34 +68,34 @@ void board_init(void) .OpenDrain = 0, .Pinmode = 0 }; - PINSEL_ConfigPin(&PinCfg); + PINSEL_ConfigPin(&PinCfg); - PinCfg.Portnum = 0; - PinCfg.Pinnum = 1; // RXD is P0.1 - PINSEL_ConfigPin(&PinCfg); + PinCfg.Portnum = 0; + PinCfg.Pinnum = 1; // RXD is P0.1 + PINSEL_ConfigPin(&PinCfg); - UART_CFG_Type UARTConfigStruct; + UART_CFG_Type UARTConfigStruct; UART_ConfigStructInit(&UARTConfigStruct); - UARTConfigStruct.Baud_rate = CFG_BOARD_UART_BAUDRATE; + UARTConfigStruct.Baud_rate = CFG_BOARD_UART_BAUDRATE; - UART_Init(BOARD_UART_PORT, &UARTConfigStruct); - UART_TxCmd(BOARD_UART_PORT, ENABLE); // Enable UART Transmit + UART_Init(BOARD_UART_PORT, &UARTConfigStruct); + UART_TxCmd(BOARD_UART_PORT, ENABLE); // Enable UART Transmit #endif - //------------- USB -------------// + //------------- USB -------------// Chip_IOCON_SetPinMuxing(LPC_IOCON, pin_usb_mux, sizeof(pin_usb_mux) / sizeof(PINMUX_GRP_T)); - Chip_USB_Init(); + Chip_USB_Init(); enum { USBCLK_DEVCIE = 0x12, // AHB + Device - USBCLK_HOST = 0x19, // AHB + Host + OTG + USBCLK_HOST = 0x19, // AHB + Host + OTG // 0x1B // Host + Device + OTG + AHB }; uint32_t const clk_en = CFG_TUD_ENABLED ? USBCLK_DEVCIE : USBCLK_HOST; LPC_USB->OTGClkCtrl = clk_en; - while ( (LPC_USB->OTGClkSt & clk_en) != clk_en ); + while ((LPC_USB->OTGClkSt & clk_en) != clk_en) {} #if CFG_TUH_ENABLED // set portfunc to host !!! @@ -141,57 +103,53 @@ void board_init(void) #endif } -//--------------------------------------------------------------------+ -// USB Interrupt Handler -//--------------------------------------------------------------------+ -void USB_IRQHandler(void) -{ - #if CFG_TUD_ENABLED - tud_int_handler(0); - #endif - - #if CFG_TUH_ENABLED - tuh_int_handler(0); - #endif -} - //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ - -void board_led_write(bool state) -{ - Chip_GPIO_SetPinState(LPC_GPIO, LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +void board_led_write(bool state) { + Chip_GPIO_SetPinState(LPC_GPIO, LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == 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; } + +//--------------------------------------------------------------------+ +// USB Interrupt Handler +//--------------------------------------------------------------------+ +void USB_IRQHandler(void) { + #if CFG_TUD_ENABLED + tud_int_handler(0); + #endif + + #if CFG_TUH_ENABLED + tuh_int_handler(0, true); + #endif +} + #endif diff --git a/hw/bsp/lpc17/family.cmake b/hw/bsp/lpc17/family.cmake new file mode 100644 index 000000000..cccfdac9f --- /dev/null +++ b/hw/bsp/lpc17/family.cmake @@ -0,0 +1,103 @@ +include_guard() + +set(SDK_DIR ${TOP}/hw/mcu/nxp/lpcopen/lpc175x_6x/lpc_chip_175x_6x) +set(CMSIS_DIR ${TOP}/lib/CMSIS_5) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR cortex-m3 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS LPC175X_6X 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_lpc175x_6x.c + ${SDK_DIR}/src/chip_17xx_40xx.c + ${SDK_DIR}/src/clock_17xx_40xx.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_definitions(${BOARD_TARGET} PUBLIC + __USE_LPCOPEN + CORE_M3 + RTC_EV_SUPPORT=0 + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_DIR}/inc + ${CMSIS_DIR}/CMSIS/Core/Include + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_compile_options(${BOARD_TARGET} PUBLIC -nostdlib) + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + ) + 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_LPC175X_6X ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/nxp/lpc17_40/dcd_lpc17_40.c + ${TOP}/src/portable/nxp/lpc17_40/hcd_lpc17_40.c + ${TOP}/src/portable/ohci/ohci.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_flash_jlink(${TARGET}) + #family_flash_nxplink(${TARGET}) +endfunction() diff --git a/hw/bsp/lpc17/family.mk b/hw/bsp/lpc17/family.mk index abf6abe13..84ed95648 100644 --- a/hw/bsp/lpc17/family.mk +++ b/hw/bsp/lpc17/family.mk @@ -18,10 +18,12 @@ CFLAGS += -Wno-error=strict-prototypes -Wno-error=cast-qual # caused by freeRTOS port !! CFLAGS += -Wno-error=maybe-uninitialized -MCU_DIR = hw/mcu/nxp/lpcopen/lpc175x_6x/lpc_chip_175x_6x +LDFLAGS_GCC += --specs=nosys.specs --specs=nano.specs SRC_C += \ src/portable/nxp/lpc17_40/dcd_lpc17_40.c \ + src/portable/ohci/ohci.c \ + src/portable/nxp/lpc17_40/hcd_lpc17_40.c \ $(MCU_DIR)/../gcc/cr_startup_lpc175x_6x.c \ $(MCU_DIR)/src/chip_17xx_40xx.c \ $(MCU_DIR)/src/clock_17xx_40xx.c \ @@ -29,7 +31,9 @@ SRC_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/uart_17xx_40xx.c \ INC += \ - $(TOP)/$(MCU_DIR)/inc + $(TOP)/$(BOARD_PATH) \ + $(TOP)/$(MCU_DIR)/inc \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ diff --git a/hw/bsp/lpc18/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/lpc18/FreeRTOSConfig/FreeRTOSConfig.h index 6f80413c0..17ddc1da4 100644 --- a/hw/bsp/lpc18/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/lpc18/FreeRTOSConfig/FreeRTOSConfig.h @@ -73,14 +73,15 @@ #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 -#define configSUPPORT_STATIC_ALLOCATION 0 -#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 /* 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 +#define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 @@ -116,23 +117,6 @@ #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 diff --git a/hw/bsp/lpc18/boards/lpcxpresso18s37/board.h b/hw/bsp/lpc18/boards/lpcxpresso18s37/board.h index b3a7bc44f..f4c85ddc9 100644 --- a/hw/bsp/lpc18/boards/lpcxpresso18s37/board.h +++ b/hw/bsp/lpc18/boards/lpcxpresso18s37/board.h @@ -62,6 +62,7 @@ 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 + // USB1 //{ 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 {0x2, 5, SCU_MODE_INBUFF_EN | SCU_MODE_PULLUP | SCU_MODE_FUNC4 }, diff --git a/hw/bsp/lpc18/boards/lpcxpresso18s37/lpc1837.ld b/hw/bsp/lpc18/boards/lpcxpresso18s37/lpc1837.ld index f12c1760c..0dd971433 100644 --- a/hw/bsp/lpc18/boards/lpcxpresso18s37/lpc1837.ld +++ b/hw/bsp/lpc18/boards/lpcxpresso18s37/lpc1837.ld @@ -296,7 +296,7 @@ SECTIONS PROVIDE(__end_bss_RamAHB_ETB16 = .) ; } > RamAHB_ETB16 AT> RamAHB_ETB16 - /* MAIN BSS SECTION */ + /* MAIN BSS SECTION: EDIT change to RamLoc40 */ .bss : ALIGN(4) { _bss = .; @@ -308,8 +308,23 @@ SECTIONS _ebss = .; PROVIDE(__end_bss_RAM = .) ; PROVIDE(__end_bss_RamLoc32 = .) ; +/* PROVIDE(end = .);*/ + } > RamLoc40 AT> RamLoc40 /* > RamLoc32 AT> RamLoc32 */ + + /* hathach add heap section for clang */ + .heap (NOLOAD): { + __heap_start = .; + __HeapBase = .; + __heap_base = .; + __end = .; PROVIDE(end = .); - } > RamLoc32 AT> RamLoc32 + PROVIDE(_end = .); + PROVIDE(__end__ = .); + KEEP(*(.heap*)) + __HeapLimit = .; + __heap_limit = .; + __heap_end = .; + } > RamLoc40 /* NOINIT section for RamLoc40 */ .noinit_RAM2 (NOLOAD) : ALIGN(4) @@ -379,19 +394,21 @@ SECTIONS PROVIDE(__end_noinit_RAM = .) ; PROVIDE(__end_noinit_RamLoc32 = .) ; } > RamLoc32 AT> RamLoc32 - PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .); +/* PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .);*/ PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_RamLoc32 - 0); /* ## Create checksum value (used in startup) ## */ - PROVIDE(__valid_user_code_checksum = 0 - - (_vStackTop - + (ResetISR + 1) - + (NMI_Handler + 1) - + (HardFault_Handler + 1) - + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1) /* MemManage_Handler may not be defined */ - + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1) /* BusFault_Handler may not be defined */ - + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1) /* UsageFault_Handler may not be defined */ - ) ); + /* This cause issue with clang linker, so it is disabled */ + /* MemManage_Handler, BusFault_Handler, UsageFault_Handler may not be defined */ +/* PROVIDE(__valid_user_code_checksum = 0 -*/ +/* (_vStackTop*/ +/* + (ResetISR + 1)*/ +/* + (NMI_Handler + 1)*/ +/* + (HardFault_Handler + 1)*/ +/* + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1)*/ +/* + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1)*/ +/* + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1)*/ +/* ) );*/ /* Provide basic symbols giving location and size of main text * block, including initial values of RW data sections. Note that diff --git a/hw/bsp/lpc18/boards/mcb1800/lpc1857.ld b/hw/bsp/lpc18/boards/mcb1800/lpc1857.ld index 9a67e8946..143aa11ec 100644 --- a/hw/bsp/lpc18/boards/mcb1800/lpc1857.ld +++ b/hw/bsp/lpc18/boards/mcb1800/lpc1857.ld @@ -247,7 +247,7 @@ SECTIONS PROVIDE(__end_bss_RAM5 = .) ; } > RamAHB_ETB16 - /* MAIN BSS SECTION */ + /* MAIN BSS SECTION: EDIT change to RamLoc40 */ .bss : ALIGN(4) { _bss = .; @@ -255,8 +255,8 @@ SECTIONS *(COMMON) . = ALIGN(4) ; _ebss = .; - PROVIDE(end = .); - } > RamLoc32 + /* PROVIDE(end = .); */ + } > RamLoc40 /* RamLoc32 */ /* NOINIT section for RamLoc40 */ .noinit_RAM2 (NOLOAD) : ALIGN(4) @@ -266,6 +266,21 @@ SECTIONS . = ALIGN(4) ; } > RamLoc40 + /* hathach add heap section for clang */ + .heap (NOLOAD): { + __heap_start = .; + __HeapBase = .; + __heap_base = .; + __end = .; + PROVIDE(end = .); + PROVIDE(_end = .); + PROVIDE(__end__ = .); + KEEP(*(.heap*)) + __HeapLimit = .; + __heap_limit = .; + __heap_end = .; + } > RamLoc40 + /* NOINIT section for RamAHB32 */ .noinit_RAM3 (NOLOAD) : ALIGN(4) { @@ -298,19 +313,21 @@ SECTIONS . = ALIGN(4) ; _end_noinit = .; } > RamLoc32 - PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .); +/* PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .);*/ PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_RamLoc32 - 0); /* ## Create checksum value (used in startup) ## */ - PROVIDE(__valid_user_code_checksum = 0 - - (_vStackTop - + (ResetISR + 1) - + (NMI_Handler + 1) - + (HardFault_Handler + 1) - + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1) /* MemManage_Handler may not be defined */ - + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1) /* BusFault_Handler may not be defined */ - + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1) /* UsageFault_Handler may not be defined */ - ) ); + /* This cause issue with clang linker, so it is disabled */ + /* MemManage_Handler, BusFault_Handler, UsageFault_Handler may not be defined */ +/* PROVIDE(__valid_user_code_checksum = 0 -*/ +/* (_vStackTop*/ +/* + (ResetISR + 1)*/ +/* + (NMI_Handler + 1)*/ +/* + (HardFault_Handler + 1)*/ +/* + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1)*/ +/* + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1)*/ +/* + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1)*/ +/* ) );*/ /* Provide basic symbols giving location and size of main text * block, including initial values of RW data sections. Note that diff --git a/hw/bsp/lpc18/family.c b/hw/bsp/lpc18/family.c index b11f4fe0e..e6abecb4b 100644 --- a/hw/bsp/lpc18/family.c +++ b/hw/bsp/lpc18/family.c @@ -43,25 +43,23 @@ //--------------------------------------------------------------------+ // USB Interrupt Handler //--------------------------------------------------------------------+ -void USB0_IRQHandler(void) -{ +void USB0_IRQHandler(void) { #if PORT_SUPPORT_DEVICE(0) - tud_int_handler(0); + tud_int_handler(0); #endif #if PORT_SUPPORT_HOST(0) - tuh_int_handler(0); + tuh_int_handler(0, true); #endif } -void USB1_IRQHandler(void) -{ +void USB1_IRQHandler(void) { #if PORT_SUPPORT_DEVICE(1) - tud_int_handler(1); + tud_int_handler(1); #endif #if PORT_SUPPORT_HOST(1) - tuh_int_handler(1); + tuh_int_handler(1, true); #endif } @@ -74,28 +72,26 @@ const uint32_t OscRateIn = 12000000; const uint32_t ExtRateIn = 0; // 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; #endif board_lpc18_pinmux(); - #ifdef TRACE_ETM +#ifdef TRACE_ETM // Trace clock is limited to 60MHz, limit CPU clock to 120MHz Chip_SetupCoreClock(CLKIN_CRYSTAL, 120000000UL, true); - #else +#else // CPU clock max to 180 Mhz Chip_SetupCoreClock(CLKIN_CRYSTAL, MAX_CLOCK_FREQ, true); - #endif +#endif } -void board_init(void) -{ +void board_init(void) { SystemCoreClockUpdate(); #if CFG_TUSB_OS == OPT_OS_NONE @@ -135,27 +131,22 @@ void board_init(void) // Board porting API //--------------------------------------------------------------------+ -void board_led_write(bool state) -{ +void board_led_write(bool state) { Chip_GPIO_SetPinState(LPC_GPIO_PORT, LED_PORT, LED_PIN, state); } -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { // active low return Chip_GPIO_GetPinState(LPC_GPIO_PORT, BUTTON_PORT, BUTTON_PIN) ? 0 : 1; } -int board_uart_read(uint8_t* buf, int len) -{ +int board_uart_read(uint8_t *buf, int len) { return Chip_UART_Read(UART_DEV, buf, len); } -int board_uart_write(void const * buf, int len) -{ - uint8_t const* buf8 = (uint8_t const*) buf; - for(int i=0; iDHCSR */ \ - 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 diff --git a/hw/bsp/lpc40/boards/ea4088_quickstart/lpc4088.ld b/hw/bsp/lpc40/boards/ea4088_quickstart/lpc4088.ld index 5897707f6..55b60e1e7 100644 --- a/hw/bsp/lpc40/boards/ea4088_quickstart/lpc4088.ld +++ b/hw/bsp/lpc40/boards/ea4088_quickstart/lpc4088.ld @@ -140,7 +140,7 @@ SECTIONS *(COMMON) . = ALIGN(4) ; _ebss = .; - PROVIDE(end = .); +/* PROVIDE(end = .);*/ } > RamLoc64 /* NOINIT section for RamPeriph32 */ @@ -159,7 +159,23 @@ SECTIONS . = ALIGN(4) ; _end_noinit = .; } > RamLoc64 - PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .); + + /* hathach add heap section for clang */ + .heap (NOLOAD): { + __heap_start = .; + __HeapBase = .; + __heap_base = .; + __end = .; + PROVIDE(end = .); + PROVIDE(_end = .); + PROVIDE(__end__ = .); + KEEP(*(.heap*)) + __HeapLimit = .; + __heap_limit = .; + __heap_end = .; + } > RamLoc64 + +/* PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .);*/ PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_RamLoc64 - 0); /* ## Create checksum value (used in startup) ## */ diff --git a/hw/bsp/lpc40/family.c b/hw/bsp/lpc40/family.c index 526e3a080..d6c8ef32a 100644 --- a/hw/bsp/lpc40/family.c +++ b/hw/bsp/lpc40/family.c @@ -37,7 +37,7 @@ void USB_IRQHandler(void) { #endif #if CFG_TUH_ENABLED - tuh_int_handler(0); + tuh_int_handler(0, true); #endif } diff --git a/hw/bsp/lpc40/family.cmake b/hw/bsp/lpc40/family.cmake index 56eb37a2f..4c14da8a7 100644 --- a/hw/bsp/lpc40/family.cmake +++ b/hw/bsp/lpc40/family.cmake @@ -1,15 +1,16 @@ include_guard() set(SDK_DIR ${TOP}/hw/mcu/nxp/lpcopen/lpc40xx/lpc_chip_40xx) +set(CMSIS_DIR ${TOP}/lib/CMSIS_5) # 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(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) -set(FAMILY_MCUS LPC18XX CACHE INTERNAL "") +set(FAMILY_MCUS LPC40XX CACHE INTERNAL "") #------------------------------------ @@ -32,9 +33,6 @@ function(add_board_target BOARD_TARGET) ${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 @@ -42,16 +40,20 @@ function(add_board_target BOARD_TARGET) ) target_include_directories(${BOARD_TARGET} PUBLIC ${SDK_DIR}/inc + ${CMSIS_DIR}/CMSIS/Core/Include ) update_board(${BOARD_TARGET}) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_compile_options(${BOARD_TARGET} PUBLIC -nostdlib) + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") 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 diff --git a/hw/bsp/lpc40/family.mk b/hw/bsp/lpc40/family.mk index c11325890..79d868f35 100644 --- a/hw/bsp/lpc40/family.mk +++ b/hw/bsp/lpc40/family.mk @@ -15,6 +15,8 @@ CFLAGS += \ # mcu driver cause following warnings CFLAGS += -Wno-error=strict-prototypes -Wno-error=unused-parameter -Wno-error=cast-qual +LDFLAGS_GCC += --specs=nosys.specs --specs=nano.specs + # All source paths should be relative to the top level. SRC_C += \ src/portable/nxp/lpc17_40/dcd_lpc17_40.c \ @@ -30,4 +32,5 @@ SRC_C += \ INC += \ $(TOP)/$(MCU_DIR)/inc \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(BOARD_PATH) diff --git a/hw/bsp/lpc43/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/lpc43/FreeRTOSConfig/FreeRTOSConfig.h index 6f80413c0..17ddc1da4 100644 --- a/hw/bsp/lpc43/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/lpc43/FreeRTOSConfig/FreeRTOSConfig.h @@ -73,14 +73,15 @@ #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 -#define configSUPPORT_STATIC_ALLOCATION 0 -#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 /* 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 +#define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 @@ -116,23 +117,6 @@ #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 diff --git a/hw/bsp/lpc43/boards/ea4357/board.h b/hw/bsp/lpc43/boards/ea4357/board.h index f026324ef..fb52e32a7 100644 --- a/hw/bsp/lpc43/boards/ea4357/board.h +++ b/hw/bsp/lpc43/boards/ea4357/board.h @@ -33,6 +33,51 @@ extern "C" { #include "pca9532.h" +// P9_1 joystick down +#define BUTTON_PORT 4 +#define BUTTON_PIN 13 +#define BUTTON_STATE_ACTIVE 0 + +#define UART_DEV LPC_USART0 +#define UART_PORT 0x0f +#define UART_PIN_TX 10 +#define UART_PIN_RX 11 + +//static const struct { +// uint8_t mux_port; +// uint8_t mux_pin; +// +// uint8_t gpio_port; +// uint8_t gpio_pin; +//}buttons[] = +//{ +// {0x0a, 3, 4, 10 }, // Joystick up +// {0x09, 1, 4, 13 }, // Joystick down +// {0x0a, 2, 4, 9 }, // Joystick left +// {0x09, 0, 4, 12 }, // Joystick right +// {0x0a, 1, 4, 8 }, // Joystick press +// {0x02, 7, 0, 7 }, // SW6 +//}; + +static const PINMUX_GRP_T pinmuxing[] = { + // Button ( Joystick down ) + { 0x9, 1, SCU_MODE_INBUFF_EN | SCU_MODE_INACT | SCU_MODE_FUNC0 | SCU_MODE_PULLUP }, + + // UART + { UART_PORT, UART_PIN_TX, SCU_MODE_PULLDOWN | SCU_MODE_FUNC1 }, + { UART_PORT, UART_PIN_RX, SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_FUNC1 }, + + // USB +}; + +/* Pin clock mux values, re-used structure, value in first index is meaningless */ +//static const PINMUX_GRP_T pinclockmuxing[] = { +// { 0, 0, SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_HIGHSPEEDSLEW_EN | SCU_MODE_FUNC0 }, +// { 0, 1, SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_HIGHSPEEDSLEW_EN | SCU_MODE_FUNC0 }, +// { 0, 2, SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_HIGHSPEEDSLEW_EN | SCU_MODE_FUNC0 }, +// { 0, 3, SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_HIGHSPEEDSLEW_EN | SCU_MODE_FUNC0 }, +//}; + #ifdef __cplusplus } #endif diff --git a/hw/bsp/lpc43/boards/ea4357/lpc4357.ld b/hw/bsp/lpc43/boards/ea4357/lpc4357.ld index e3dfbfda1..002dcaaed 100644 --- a/hw/bsp/lpc43/boards/ea4357/lpc4357.ld +++ b/hw/bsp/lpc43/boards/ea4357/lpc4357.ld @@ -248,7 +248,7 @@ SECTIONS PROVIDE(__end_bss_RAM5 = .) ; } > RamAHB_ETB16 - /* MAIN BSS SECTION */ + /* MAIN BSS SECTION: EDIT change to RamLoc40 */ .bss : ALIGN(4) { _bss = .; @@ -256,8 +256,8 @@ SECTIONS *(COMMON) . = ALIGN(4) ; _ebss = .; - PROVIDE(end = .); - } > RamLoc32 + /* PROVIDE(end = .); */ + } > RamLoc40 /* RamLoc32 */ /* NOINIT section for RamLoc40 */ .noinit_RAM2 (NOLOAD) : ALIGN(4) @@ -267,6 +267,21 @@ SECTIONS . = ALIGN(4) ; } > RamLoc40 + /* hathach add heap section for clang */ + .heap (NOLOAD): { + __heap_start = .; + __HeapBase = .; + __heap_base = .; + __end = .; + PROVIDE(end = .); + PROVIDE(_end = .); + PROVIDE(__end__ = .); + KEEP(*(.heap*)) + __HeapLimit = .; + __heap_limit = .; + __heap_end = .; + } > RamLoc40 + /* NOINIT section for RamAHB32 */ .noinit_RAM3 (NOLOAD) : ALIGN(4) { @@ -299,19 +314,21 @@ SECTIONS . = ALIGN(4) ; _end_noinit = .; } > RamLoc32 - PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .); +/* PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .);*/ PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_RamLoc32 - 0); /* ## Create checksum value (used in startup) ## */ - PROVIDE(__valid_user_code_checksum = 0 - - (_vStackTop - + (ResetISR + 1) - + (NMI_Handler + 1) - + (HardFault_Handler + 1) - + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1) /* MemManage_Handler may not be defined */ - + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1) /* BusFault_Handler may not be defined */ - + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1) /* UsageFault_Handler may not be defined */ - ) ); + /* This cause issue with clang linker, so it is disabled */ + /* MemManage_Handler, BusFault_Handler, UsageFault_Hander may not be defined */ +/* PROVIDE(__valid_user_code_checksum = 0 -*/ +/* (_vStackTop*/ +/* + (ResetISR + 1)*/ +/* + (NMI_Handler + 1)*/ +/* + (HardFault_Handler + 1)*/ +/* + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1)*/ +/* + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1)*/ +/* + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1)*/ +/* ) );*/ /* Provide basic symbols giving location and size of main text * block, including initial values of RW data sections. Note that diff --git a/hw/bsp/lpc43/boards/lpcxpresso43s67/board.cmake b/hw/bsp/lpc43/boards/lpcxpresso43s67/board.cmake new file mode 100644 index 000000000..0858a97d5 --- /dev/null +++ b/hw/bsp/lpc43/boards/lpcxpresso43s67/board.cmake @@ -0,0 +1,11 @@ +set(MCU_VARIANT LPC43S67_M4) + +set(JLINK_DEVICE LPC43S67_M4) +set(PYOCD_TARGET LPC43S67) +set(NXPLINK_DEVICE LPC43S67:LPCXPRESSO43S67) + +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/lpc4367.ld) + +function(update_board TARGET) + # nothing to do +endfunction() diff --git a/hw/bsp/lpc43/boards/lpcxpresso43s67/board.h b/hw/bsp/lpc43/boards/lpcxpresso43s67/board.h new file mode 100644 index 000000000..4dd90fe29 --- /dev/null +++ b/hw/bsp/lpc43/boards/lpcxpresso43s67/board.h @@ -0,0 +1,73 @@ +/* + * 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_LPCXPRESSO43S67_H_ +#define _BOARD_LPCXPRESSO43S67_H_ + +// Note: For USB Host demo, install JP4 +// WARNING: don't install JP4 when running as device + +#ifdef __cplusplus + extern "C" { +#endif + +// LED Red +#define LED_PORT 3 +#define LED_PIN 7 +#define LED_STATE_ON 0 + +// ISP Button (SW2) +#define BUTTON_PORT 0 +#define BUTTON_PIN 7 +#define BUTTON_STATE_ACTIVE 0 + +#define UART_DEV LPC_USART0 + +static const PINMUX_GRP_T pinmuxing[] = { + // LEDs P6_11 as GPIO3[7] + { 0x6, 11, SCU_MODE_INBUFF_EN | SCU_MODE_PULLUP | SCU_MODE_FUNC0 }, + + // Button P2_7 as GPIO0[7] + { 0x2, 7, SCU_MODE_PULLUP | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_FUNC0 }, + + // UART + { 0x06, 4, SCU_MODE_PULLDOWN | SCU_MODE_FUNC2 }, + { 0x02, 1, SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_FUNC1 }, + + // USB0 + //{ 0x6, 3, SCU_MODE_PULLUP | SCU_MODE_INBUFF_EN | SCU_MODE_FUNC1 }, // P6_3 USB0_PWR_EN, USB0 VBus function + + // USB 1 + //{ 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 + {0x2, 5, SCU_MODE_INBUFF_EN | SCU_MODE_PULLUP | SCU_MODE_FUNC4 }, +}; + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/hw/bsp/lpc43/boards/lpcxpresso43s67/board.mk b/hw/bsp/lpc43/boards/lpcxpresso43s67/board.mk new file mode 100644 index 000000000..eeb02e311 --- /dev/null +++ b/hw/bsp/lpc43/boards/lpcxpresso43s67/board.mk @@ -0,0 +1,6 @@ +LD_FILE = $(BOARD_PATH)/lpc4367.ld + +# For flash-jlink target +JLINK_DEVICE = LPC43S67_M4 + +flash: flash-jlink diff --git a/hw/bsp/ngx4330/ngx4330.ld b/hw/bsp/lpc43/boards/lpcxpresso43s67/lpc4367.ld similarity index 51% rename from hw/bsp/ngx4330/ngx4330.ld rename to hw/bsp/lpc43/boards/lpcxpresso43s67/lpc4367.ld index 300869c20..f19350e00 100644 --- a/hw/bsp/ngx4330/ngx4330.ld +++ b/hw/bsp/lpc43/boards/lpcxpresso43s67/lpc4367.ld @@ -2,33 +2,42 @@ * GENERATED FILE - DO NOT EDIT * Copyright (c) 2008-2013 Code Red Technologies Ltd, * Copyright 2015, 2018-2019 NXP - * (c) NXP Semiconductors 2013-2019 - * Generated linker script file for LPC4330 + * (c) NXP Semiconductors 2013-2023 + * Generated linker script file for LPC4337 * Created from linkscript.ldt by FMCreateLinkLibraries - * Using Freemarker v2.3.23 - * MCUXpresso IDE v11.0.0 [Build 2516] [2019-06-05] on Sep 9, 2019 12:09:49 PM + * Using Freemarker v2.3.30 + * MCUXpresso IDE v11.7.1 [Build 9221] [2023-03-28] on Aug 14, 2023, 3:36:29 PM */ MEMORY { /* Define each memory region */ - RamLoc128 (rwx) : ORIGIN = 0x10000000, LENGTH = 0x20000 /* 128K bytes (alias RAM) */ - RamLoc72 (rwx) : ORIGIN = 0x10080000, LENGTH = 0x12000 /* 72K bytes (alias RAM2) */ + MFlashA512 (rx) : ORIGIN = 0x1a000000, LENGTH = 0x80000 /* 512K bytes (alias Flash) */ + MFlashB512 (rx) : ORIGIN = 0x1b000000, LENGTH = 0x80000 /* 512K bytes (alias Flash2) */ + RamLoc32 (rwx) : ORIGIN = 0x10000000, LENGTH = 0x8000 /* 32K bytes (alias RAM) */ + RamLoc40 (rwx) : ORIGIN = 0x10080000, LENGTH = 0xa000 /* 40K bytes (alias RAM2) */ RamAHB32 (rwx) : ORIGIN = 0x20000000, LENGTH = 0x8000 /* 32K bytes (alias RAM3) */ RamAHB16 (rwx) : ORIGIN = 0x20008000, LENGTH = 0x4000 /* 16K bytes (alias RAM4) */ RamAHB_ETB16 (rwx) : ORIGIN = 0x2000c000, LENGTH = 0x4000 /* 16K bytes (alias RAM5) */ - SPIFI (rx) : ORIGIN = 0x14000000, LENGTH = 0x400000 /* 4M bytes (alias Flash) */ } /* Define a symbol for the top of each memory region */ - __base_RamLoc128 = 0x10000000 ; /* RamLoc128 */ + __base_MFlashA512 = 0x1a000000 ; /* MFlashA512 */ + __base_Flash = 0x1a000000 ; /* Flash */ + __top_MFlashA512 = 0x1a000000 + 0x80000 ; /* 512K bytes */ + __top_Flash = 0x1a000000 + 0x80000 ; /* 512K bytes */ + __base_MFlashB512 = 0x1b000000 ; /* MFlashB512 */ + __base_Flash2 = 0x1b000000 ; /* Flash2 */ + __top_MFlashB512 = 0x1b000000 + 0x80000 ; /* 512K bytes */ + __top_Flash2 = 0x1b000000 + 0x80000 ; /* 512K bytes */ + __base_RamLoc32 = 0x10000000 ; /* RamLoc32 */ __base_RAM = 0x10000000 ; /* RAM */ - __top_RamLoc128 = 0x10000000 + 0x20000 ; /* 128K bytes */ - __top_RAM = 0x10000000 + 0x20000 ; /* 128K bytes */ - __base_RamLoc72 = 0x10080000 ; /* RamLoc72 */ + __top_RamLoc32 = 0x10000000 + 0x8000 ; /* 32K bytes */ + __top_RAM = 0x10000000 + 0x8000 ; /* 32K bytes */ + __base_RamLoc40 = 0x10080000 ; /* RamLoc40 */ __base_RAM2 = 0x10080000 ; /* RAM2 */ - __top_RamLoc72 = 0x10080000 + 0x12000 ; /* 72K bytes */ - __top_RAM2 = 0x10080000 + 0x12000 ; /* 72K bytes */ + __top_RamLoc40 = 0x10080000 + 0xa000 ; /* 40K bytes */ + __top_RAM2 = 0x10080000 + 0xa000 ; /* 40K bytes */ __base_RamAHB32 = 0x20000000 ; /* RamAHB32 */ __base_RAM3 = 0x20000000 ; /* RAM3 */ __top_RamAHB32 = 0x20000000 + 0x8000 ; /* 32K bytes */ @@ -41,16 +50,28 @@ MEMORY __base_RAM5 = 0x2000c000 ; /* RAM5 */ __top_RamAHB_ETB16 = 0x2000c000 + 0x4000 ; /* 16K bytes */ __top_RAM5 = 0x2000c000 + 0x4000 ; /* 16K bytes */ - __base_SPIFI = 0x14000000 ; /* SPIFI */ - __base_Flash = 0x14000000 ; /* Flash */ - __top_SPIFI = 0x14000000 + 0x400000 ; /* 4M bytes */ - __top_Flash = 0x14000000 + 0x400000 ; /* 4M bytes */ ENTRY(ResetISR) SECTIONS { - /* MAIN TEXT SECTION */ + .text_Flash2 : ALIGN(4) + { + FILL(0xff) + *(.text_Flash2) /* for compatibility with previous releases */ + *(.text_MFlashB512) /* for compatibility with previous releases */ + *(.text.$Flash2) + *(.text.$MFlashB512) + *(.text_Flash2.*) /* for compatibility with previous releases */ + *(.text_MFlashB512.*) /* for compatibility with previous releases */ + *(.text.$Flash2.*) + *(.text.$MFlashB512.*) + *(.rodata.$Flash2) + *(.rodata.$MFlashB512) + *(.rodata.$Flash2.*) + *(.rodata.$MFlashB512.*) } > MFlashB512 + + /* MAIN TEXT SECTION */ .text : ALIGN(4) { FILL(0xff) @@ -93,14 +114,10 @@ SECTIONS *(.after_vectors*) - } > SPIFI - - .text : ALIGN(4) - { *(.text*) *(.rodata .rodata.* .constdata .constdata.*) . = ALIGN(4); - } > SPIFI + } > MFlashA512 /* * for exception handling/unwind - some Newlib functions (in common * with C++ and STDC++) use this. @@ -108,39 +125,42 @@ SECTIONS .ARM.extab : ALIGN(4) { *(.ARM.extab* .gnu.linkonce.armextab.*) - } > SPIFI - - __exidx_start = .; + } > MFlashA512 .ARM.exidx : ALIGN(4) { + __exidx_start = .; *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > SPIFI - __exidx_end = .; + __exidx_end = .; + } > MFlashA512 _etext = .; - /* DATA section for RamLoc72 */ + /* DATA section for RamLoc40 */ .data_RAM2 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM2 = .) ; + PROVIDE(__start_data_RamLoc40 = .) ; *(.ramfunc.$RAM2) - *(.ramfunc.$RamLoc72) + *(.ramfunc.$RamLoc40) *(.data.$RAM2) - *(.data.$RamLoc72) + *(.data.$RamLoc40) *(.data.$RAM2.*) - *(.data.$RamLoc72.*) + *(.data.$RamLoc40.*) . = ALIGN(4) ; PROVIDE(__end_data_RAM2 = .) ; - } > RamLoc72 AT>SPIFI + PROVIDE(__end_data_RamLoc40 = .) ; + } > RamLoc40 AT>MFlashA512 + /* DATA section for RamAHB32 */ .data_RAM3 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM3 = .) ; + PROVIDE(__start_data_RamAHB32 = .) ; *(.ramfunc.$RAM3) *(.ramfunc.$RamAHB32) *(.data.$RAM3) @@ -149,13 +169,16 @@ SECTIONS *(.data.$RamAHB32.*) . = ALIGN(4) ; PROVIDE(__end_data_RAM3 = .) ; - } > RamAHB32 AT>SPIFI + PROVIDE(__end_data_RamAHB32 = .) ; + } > RamAHB32 AT>MFlashA512 + /* DATA section for RamAHB16 */ .data_RAM4 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM4 = .) ; + PROVIDE(__start_data_RamAHB16 = .) ; *(.ramfunc.$RAM4) *(.ramfunc.$RamAHB16) *(.data.$RAM4) @@ -164,13 +187,16 @@ SECTIONS *(.data.$RamAHB16.*) . = ALIGN(4) ; PROVIDE(__end_data_RAM4 = .) ; - } > RamAHB16 AT>SPIFI + PROVIDE(__end_data_RamAHB16 = .) ; + } > RamAHB16 AT>MFlashA512 + /* DATA section for RamAHB_ETB16 */ .data_RAM5 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM5 = .) ; + PROVIDE(__start_data_RamAHB_ETB16 = .) ; *(.ramfunc.$RAM5) *(.ramfunc.$RamAHB_ETB16) *(.data.$RAM5) @@ -179,158 +205,208 @@ SECTIONS *(.data.$RamAHB_ETB16.*) . = ALIGN(4) ; PROVIDE(__end_data_RAM5 = .) ; - } > RamAHB_ETB16 AT>SPIFI + PROVIDE(__end_data_RamAHB_ETB16 = .) ; + } > RamAHB_ETB16 AT>MFlashA512 + /* MAIN DATA SECTION */ - .uninit_RESERVED (NOLOAD) : + .uninit_RESERVED (NOLOAD) : ALIGN(4) { - . = ALIGN(4) ; + _start_uninit_RESERVED = .; KEEP(*(.bss.$RESERVED*)) . = ALIGN(4) ; _end_uninit_RESERVED = .; - } > RamLoc128 + } > RamLoc32 AT> RamLoc32 - /* Main DATA section (RamLoc128) */ + /* Main DATA section (RamLoc32) */ .data : ALIGN(4) { FILL(0xff) _data = . ; + PROVIDE(__start_data_RAM = .) ; + PROVIDE(__start_data_RamLoc32 = .) ; *(vtable) *(.ramfunc*) + KEEP(*(CodeQuickAccess)) + KEEP(*(DataQuickAccess)) + *(RamFunction) *(.data*) . = ALIGN(4) ; _edata = . ; - } > RamLoc128 AT>SPIFI + PROVIDE(__end_data_RAM = .) ; + PROVIDE(__end_data_RamLoc32 = .) ; + } > RamLoc32 AT>MFlashA512 - /* BSS section for RamLoc72 */ - .bss_RAM2 : + /* BSS section for RamLoc40 */ + .bss_RAM2 : ALIGN(4) { - . = ALIGN(4) ; PROVIDE(__start_bss_RAM2 = .) ; + PROVIDE(__start_bss_RamLoc40 = .) ; *(.bss.$RAM2) - *(.bss.$RamLoc72) + *(.bss.$RamLoc40) *(.bss.$RAM2.*) - *(.bss.$RamLoc72.*) + *(.bss.$RamLoc40.*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM2 = .) ; - } > RamLoc72 + PROVIDE(__end_bss_RamLoc40 = .) ; + } > RamLoc40 AT> RamLoc40 /* BSS section for RamAHB32 */ - .bss_RAM3 : + .bss_RAM3 : ALIGN(4) { - . = ALIGN(4) ; PROVIDE(__start_bss_RAM3 = .) ; + PROVIDE(__start_bss_RamAHB32 = .) ; *(.bss.$RAM3) *(.bss.$RamAHB32) *(.bss.$RAM3.*) *(.bss.$RamAHB32.*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM3 = .) ; - } > RamAHB32 + PROVIDE(__end_bss_RamAHB32 = .) ; + } > RamAHB32 AT> RamAHB32 /* BSS section for RamAHB16 */ - .bss_RAM4 : + .bss_RAM4 : ALIGN(4) { - . = ALIGN(4) ; PROVIDE(__start_bss_RAM4 = .) ; + PROVIDE(__start_bss_RamAHB16 = .) ; *(.bss.$RAM4) *(.bss.$RamAHB16) *(.bss.$RAM4.*) *(.bss.$RamAHB16.*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM4 = .) ; - } > RamAHB16 + PROVIDE(__end_bss_RamAHB16 = .) ; + } > RamAHB16 AT> RamAHB16 /* BSS section for RamAHB_ETB16 */ - .bss_RAM5 : + .bss_RAM5 : ALIGN(4) { - . = ALIGN(4) ; PROVIDE(__start_bss_RAM5 = .) ; + PROVIDE(__start_bss_RamAHB_ETB16 = .) ; *(.bss.$RAM5) *(.bss.$RamAHB_ETB16) *(.bss.$RAM5.*) *(.bss.$RamAHB_ETB16.*) . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ PROVIDE(__end_bss_RAM5 = .) ; - } > RamAHB_ETB16 + PROVIDE(__end_bss_RamAHB_ETB16 = .) ; + } > RamAHB_ETB16 AT> RamAHB_ETB16 - /* MAIN BSS SECTION */ - .bss : + /* MAIN BSS SECTION: EDIT change to RamLoc40 */ + .bss : ALIGN(4) { - . = ALIGN(4) ; _bss = .; + PROVIDE(__start_bss_RAM = .) ; + PROVIDE(__start_bss_RamLoc32 = .) ; *(.bss*) *(COMMON) . = ALIGN(4) ; _ebss = .; - PROVIDE(end = .); - } > RamLoc128 + PROVIDE(__end_bss_RAM = .) ; + PROVIDE(__end_bss_RamLoc32 = .) ; +/* PROVIDE(end = .);*/ + } > RamLoc40 AT> RamLoc40 /* > RamLoc32 AT> RamLoc32 */ - /* NOINIT section for RamLoc72 */ - .noinit_RAM2 (NOLOAD) : + /* hathach add heap section for clang */ + .heap (NOLOAD): { + __heap_start = .; + __HeapBase = .; + __heap_base = .; + __end = .; + PROVIDE(end = .); + PROVIDE(_end = .); + PROVIDE(__end__ = .); + KEEP(*(.heap*)) + __HeapLimit = .; + __heap_limit = .; + __heap_end = .; + } > RamLoc40 + + /* NOINIT section for RamLoc40 */ + .noinit_RAM2 (NOLOAD) : ALIGN(4) { - . = ALIGN(4) ; + PROVIDE(__start_noinit_RAM2 = .) ; + PROVIDE(__start_noinit_RamLoc40 = .) ; *(.noinit.$RAM2) - *(.noinit.$RamLoc72) + *(.noinit.$RamLoc40) *(.noinit.$RAM2.*) - *(.noinit.$RamLoc72.*) + *(.noinit.$RamLoc40.*) . = ALIGN(4) ; - } > RamLoc72 + PROVIDE(__end_noinit_RAM2 = .) ; + PROVIDE(__end_noinit_RamLoc40 = .) ; + } > RamLoc40 AT> RamLoc40 /* NOINIT section for RamAHB32 */ - .noinit_RAM3 (NOLOAD) : + .noinit_RAM3 (NOLOAD) : ALIGN(4) { - . = ALIGN(4) ; + PROVIDE(__start_noinit_RAM3 = .) ; + PROVIDE(__start_noinit_RamAHB32 = .) ; *(.noinit.$RAM3) *(.noinit.$RamAHB32) *(.noinit.$RAM3.*) *(.noinit.$RamAHB32.*) . = ALIGN(4) ; - } > RamAHB32 + PROVIDE(__end_noinit_RAM3 = .) ; + PROVIDE(__end_noinit_RamAHB32 = .) ; + } > RamAHB32 AT> RamAHB32 /* NOINIT section for RamAHB16 */ - .noinit_RAM4 (NOLOAD) : + .noinit_RAM4 (NOLOAD) : ALIGN(4) { - . = ALIGN(4) ; + PROVIDE(__start_noinit_RAM4 = .) ; + PROVIDE(__start_noinit_RamAHB16 = .) ; *(.noinit.$RAM4) *(.noinit.$RamAHB16) *(.noinit.$RAM4.*) *(.noinit.$RamAHB16.*) . = ALIGN(4) ; - } > RamAHB16 + PROVIDE(__end_noinit_RAM4 = .) ; + PROVIDE(__end_noinit_RamAHB16 = .) ; + } > RamAHB16 AT> RamAHB16 /* NOINIT section for RamAHB_ETB16 */ - .noinit_RAM5 (NOLOAD) : + .noinit_RAM5 (NOLOAD) : ALIGN(4) { - . = ALIGN(4) ; + PROVIDE(__start_noinit_RAM5 = .) ; + PROVIDE(__start_noinit_RamAHB_ETB16 = .) ; *(.noinit.$RAM5) *(.noinit.$RamAHB_ETB16) *(.noinit.$RAM5.*) *(.noinit.$RamAHB_ETB16.*) . = ALIGN(4) ; - } > RamAHB_ETB16 + PROVIDE(__end_noinit_RAM5 = .) ; + PROVIDE(__end_noinit_RamAHB_ETB16 = .) ; + } > RamAHB_ETB16 AT> RamAHB_ETB16 /* DEFAULT NOINIT SECTION */ - .noinit (NOLOAD): + .noinit (NOLOAD): ALIGN(4) { - . = ALIGN(4) ; _noinit = .; + PROVIDE(__start_noinit_RAM = .) ; + PROVIDE(__start_noinit_RamLoc32 = .) ; *(.noinit*) . = ALIGN(4) ; _end_noinit = .; - } > RamLoc128 - PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .); - PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_RamLoc128 - 0); + PROVIDE(__end_noinit_RAM = .) ; + PROVIDE(__end_noinit_RamLoc32 = .) ; + } > RamLoc32 AT> RamLoc32 + +/* PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .);*/ + + PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_RamLoc32 - 0); /* ## Create checksum value (used in startup) ## */ - PROVIDE(__valid_user_code_checksum = 0 - - (_vStackTop - + (ResetISR + 1) - + (NMI_Handler + 1) - + (HardFault_Handler + 1) - + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1) /* MemManage_Handler may not be defined */ - + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1) /* BusFault_Handler may not be defined */ - + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1) /* UsageFault_Handler may not be defined */ - ) ); + /* This cause issue with clang linker, so it is disabled */ + /* MemManage_Handler, BusFault_Handler, UsageFault_Hander may not be defined */ +/* PROVIDE(__valid_user_code_checksum = 0 -*/ +/* (_vStackTop*/ +/* + (ResetISR + 1)*/ +/* + (NMI_Handler + 1)*/ +/* + (HardFault_Handler + 1)*/ +/* + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1)*/ +/* + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1)*/ +/* + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1)*/ +/* ) );*/ /* Provide basic symbols giving location and size of main text * block, including initial values of RW data sections. Note that diff --git a/hw/bsp/lpc43/family.c b/hw/bsp/lpc43/family.c index ba3191d5f..8be729f7d 100644 --- a/hw/bsp/lpc43/family.c +++ b/hw/bsp/lpc43/family.c @@ -39,31 +39,6 @@ #include "bsp/board_api.h" #include "board.h" -#define UART_DEV LPC_USART0 -#define UART_PORT 0x0f -#define UART_PIN_TX 10 -#define UART_PIN_RX 11 - -// P9_1 joystick down -#define BUTTON_PORT 4 -#define BUTTON_PIN 13 - -//static const struct { -// uint8_t mux_port; -// uint8_t mux_pin; -// -// uint8_t gpio_port; -// uint8_t gpio_pin; -//}buttons[] = -//{ -// {0x0a, 3, 4, 10 }, // Joystick up -// {0x09, 1, 4, 13 }, // Joystick down -// {0x0a, 2, 4, 9 }, // Joystick left -// {0x09, 0, 4, 12 }, // Joystick right -// {0x0a, 1, 4, 8 }, // Joystick press -// {0x02, 7, 0, 7 }, // SW6 -//}; - #ifdef BOARD_TUD_RHPORT #define PORT_SUPPORT_DEVICE(_n) (BOARD_TUD_RHPORT == _n) #else @@ -76,56 +51,46 @@ #define PORT_SUPPORT_HOST(_n) 0 #endif -/*------------------------------------------------------------------*/ -/* BOARD API - *------------------------------------------------------------------*/ - /* System configuration variables used by chip driver */ const uint32_t OscRateIn = 12000000; const uint32_t ExtRateIn = 0; -static const PINMUX_GRP_T pinmuxing[] = -{ - // Button ( Joystick down ) - {0x9, 1, (SCU_MODE_INBUFF_EN | SCU_MODE_INACT | SCU_MODE_FUNC0 | SCU_MODE_PULLUP)}, - - // UART - {UART_PORT, UART_PIN_TX, SCU_MODE_PULLDOWN | SCU_MODE_FUNC1}, - {UART_PORT, UART_PIN_RX, SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_FUNC1}, - - // USB -}; - -/* Pin clock mux values, re-used structure, value in first index is meaningless */ -static const PINMUX_GRP_T pinclockmuxing[] = -{ - {0, 0, (SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_HIGHSPEEDSLEW_EN | SCU_MODE_FUNC0)}, - {0, 1, (SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_HIGHSPEEDSLEW_EN | SCU_MODE_FUNC0)}, - {0, 2, (SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_HIGHSPEEDSLEW_EN | SCU_MODE_FUNC0)}, - {0, 3, (SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_HIGHSPEEDSLEW_EN | SCU_MODE_FUNC0)}, -}; +/*------------------------------------------------------------------*/ +/* BOARD API + *------------------------------------------------------------------*/ // Invoked by startup code void SystemInit(void) { #ifdef __USE_LPCOPEN - extern void (* const g_pfnVectors[])(void); unsigned int *pSCB_VTOR = (unsigned int *) 0xE000ED08; + +#ifdef __ICCARM__ + extern void *__vector_table; + *pSCB_VTOR = (unsigned int) &__vector_table; + +#elif defined(__ARMCC_VERSION) + extern void *__Vectors; + *pSCB_VTOR = (unsigned int) &__Vectors; + +#else // other compoiler using cr_startup_lpc43xx.c + extern void (* const g_pfnVectors[])(void); *pSCB_VTOR = (unsigned int) g_pfnVectors; +#endif #if __FPU_USED == 1 fpuInit(); #endif -#endif // __USE_LPCOPEN - /* Setup system level pin muxing */ - Chip_SCU_SetPinMuxing(pinmuxing, sizeof(pinmuxing) / sizeof(PINMUX_GRP_T)); +#endif - /* Clock pins only, group field not used */ - for (int i = 0; i <(int) (sizeof(pinclockmuxing) / sizeof(pinclockmuxing[0])); i++) - { - Chip_SCU_ClockPinMuxSet(pinclockmuxing[i].pinnum, pinclockmuxing[i].modefunc); - } + /* Setup system level pin muxing */ + Chip_SCU_SetPinMuxing(pinmuxing, sizeof(pinmuxing) / sizeof(PINMUX_GRP_T)); + +// /* Clock pins only, group field not used */ +// for ( int i = 0; i < (int) (sizeof(pinclockmuxing) / sizeof(pinclockmuxing[0])); i++ ) { +// Chip_SCU_ClockPinMuxSet(pinclockmuxing[i].pinnum, pinclockmuxing[i].modefunc); +// } Chip_SetupXtalClocking(); } @@ -144,13 +109,16 @@ void board_init(void) Chip_GPIO_Init(LPC_GPIO_PORT); +#ifdef __PCA9532C_H // LED via pca9532 I2C Chip_SCU_I2C0PinConfig(I2C0_STANDARD_FAST_MODE); Chip_I2C_Init(I2C0); Chip_I2C_SetClockRate(I2C0, 100000); Chip_I2C_SetMasterEventHandler(I2C0, Chip_I2C_EventHandlerPolling); - pca9532_init(); +#else + Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, LED_PORT, LED_PIN); +#endif // Button Chip_GPIO_SetPinDIRInput(LPC_GPIO_PORT, BUTTON_PORT, BUTTON_PIN); @@ -245,7 +213,7 @@ void USB0_IRQHandler(void) #endif #if PORT_SUPPORT_HOST(0) - tuh_int_handler(0); + tuh_int_handler(0, true); #endif } @@ -256,7 +224,7 @@ void USB1_IRQHandler(void) #endif #if PORT_SUPPORT_HOST(1) - tuh_int_handler(1); + tuh_int_handler(1, true); #endif } @@ -264,34 +232,37 @@ void USB1_IRQHandler(void) // Board porting API //--------------------------------------------------------------------+ -void board_led_write(bool state) -{ - if (state) - { - pca9532_setLeds( LED1, 0 ); - }else - { - pca9532_setLeds( 0, LED1); +void board_led_write(bool state) { + #ifdef __PCA9532C_H + if ( state ) { + pca9532_setLeds(LED1, 0); + } else { + pca9532_setLeds(0, LED1); } + #else + Chip_GPIO_SetPinState(LPC_GPIO_PORT, LED_PORT, LED_PIN, state ? LED_STATE_ON : !LED_STATE_ON); + #endif } -uint32_t board_button_read(void) -{ - // active low - return Chip_GPIO_GetPinState(LPC_GPIO_PORT, BUTTON_PORT, BUTTON_PIN) ? 0 : 1; +uint32_t board_button_read(void) { + return BUTTON_STATE_ACTIVE == Chip_GPIO_GetPinState(LPC_GPIO_PORT, BUTTON_PORT, BUTTON_PIN); } -int board_uart_read(uint8_t* buf, int len) -{ +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + if ( max_len < 16 ) return 0; + uint32_t* id32 = (uint32_t*) (uintptr_t) id; + Chip_IAP_ReadUID(id32); + return 16; +} + +int board_uart_read(uint8_t *buf, int len) { return Chip_UART_Read(UART_DEV, buf, len); } -int board_uart_write(void const * buf, int len) -{ - uint8_t const* buf8 = (uint8_t const*) buf; - for(int i=0; i= 4 + #define configENABLE_FPU 1 +#else + #define configENABLE_FPU 0 +#endif +#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 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* 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 2 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<) + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif() + + if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_CORE}_flash.ld) + endif () + set(LD_FILE_Clang ${LD_FILE_GNU}) + + if (NOT DEFINED STARTUP_FILE_GNU) + set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_CORE}.S) + endif () + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + # driver + ${SDK_DIR}/drivers/lpc_gpio/fsl_gpio.c + ${SDK_DIR}/drivers/common/fsl_common_arm.c + ${SDK_DIR}/drivers/flexcomm/fsl_flexcomm.c + ${SDK_DIR}/drivers/flexcomm/fsl_usart.c + # mcu + ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_CORE}.c + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_power.c + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_reset.c + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${TOP}/lib/sct_neopixel + # driver + ${SDK_DIR}/drivers/common + ${SDK_DIR}/drivers/flexcomm + ${SDK_DIR}/drivers/lpc_iocon + ${SDK_DIR}/drivers/lpc_gpio + ${SDK_DIR}/drivers/lpuart + ${SDK_DIR}/drivers/sctimer + # mcu + ${SDK_DIR}/devices/${MCU_VARIANT} + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers + ${CMSIS_DIR}/CMSIS/Core/Include + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + CFG_TUSB_MEM_ALIGN=TU_ATTR_ALIGNED\(64\) + BOARD_TUD_RHPORT=${PORT} + BOARD_TUH_RHPORT=${HOST_PORT} + __STARTUP_CLEAR_BSS + ) + + # Port 0 is Fullspeed, Port 1 is Highspeed. Port1 controller can only access USB_SRAM + if (PORT EQUAL 1) + target_compile_definitions(${BOARD_TARGET} PUBLIC + BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + BOARD_TUH_MAX_SPEED=OPT_MODE_FULL_SPEED + CFG_TUD_MEM_SECTION=__attribute__\(\(section\(\"m_usb_global\"\)\)\) + ) + else () + target_compile_definitions(${BOARD_TARGET} PUBLIC + BOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED + BOARD_TUH_MAX_SPEED=OPT_MODE_HIGH_SPEED + CFG_TUH_MEM_SECTION=__attribute__\(\(section\(\"m_usb_global\"\)\)\) + #CFG_TUD_MEM_SECTION=__attribute__\(\(section\(\"m_usb_global\"\)\)\) + ) + endif () + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + --specs=nosys.specs --specs=nano.specs + -nostartfiles + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + 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 + ) + + # https://github.com/gsteiert/sct_neopixel/pull/1 + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + set_source_files_properties(${TOP}/lib/sct_neopixel/sct_neopixel.c PROPERTIES + COMPILE_FLAGS "-Wno-unused-parameter") + endif () + + 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_LPC54 ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.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}) + #family_flash_pyocd(${TARGET}) +endfunction() diff --git a/hw/bsp/lpc54/family.mk b/hw/bsp/lpc54/family.mk index 7d8bb86cd..ea4c9c39c 100644 --- a/hw/bsp/lpc54/family.mk +++ b/hw/bsp/lpc54/family.mk @@ -3,16 +3,18 @@ DEPS_SUBMODULES += $(SDK_DIR) lib/CMSIS_5 include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m4 +MCU_DIR = $(SDK_DIR)/devices/$(MCU_VARIANT) CFLAGS += \ -flto \ + -D__STARTUP_CLEAR_BSS \ -DCFG_TUSB_MCU=OPT_MCU_LPC54XXX \ - -DCFG_TUSB_MEM_ALIGN='__attribute__((aligned(64)))' + -DCFG_TUSB_MEM_ALIGN='__attribute__((aligned(64)))' \ ifeq ($(PORT), 1) $(info "PORT1 High Speed") CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED - + CFLAGS += -DBOARD_TUD_RHPORT=1 # LPC55 Highspeed Port1 can only write to USB_SRAM region CFLAGS += -DCFG_TUSB_MEM_SECTION='__attribute__((section("m_usb_global")))' else @@ -22,7 +24,9 @@ endif # mcu driver cause following warnings CFLAGS += -Wno-error=unused-parameter -MCU_DIR = $(SDK_DIR)/devices/$(MCU_VARIANT) +LDFLAGS_GCC += \ + -nostartfiles \ + --specs=nosys.specs --specs=nano.specs SRC_C += \ src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c \ @@ -32,7 +36,8 @@ SRC_C += \ $(MCU_DIR)/drivers/fsl_reset.c \ $(SDK_DIR)/drivers/lpc_gpio/fsl_gpio.c \ $(SDK_DIR)/drivers/flexcomm/fsl_flexcomm.c \ - $(SDK_DIR)/drivers/flexcomm/fsl_usart.c + $(SDK_DIR)/drivers/flexcomm/fsl_usart.c \ + $(SDK_DIR)/drivers/common/fsl_common_arm.c INC += \ $(TOP)/$(BOARD_PATH) \ diff --git a/hw/bsp/lpc55/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/lpc55/FreeRTOSConfig/FreeRTOSConfig.h index fc0ab1f2d..6f10a7ab0 100644 --- a/hw/bsp/lpc55/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/lpc55/FreeRTOSConfig/FreeRTOSConfig.h @@ -73,14 +73,15 @@ #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 -#define configSUPPORT_STATIC_ALLOCATION 0 -#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 /* 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 +#define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 @@ -116,23 +117,6 @@ #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 diff --git a/hw/bsp/lpc55/boards/double_m33_express/board.cmake b/hw/bsp/lpc55/boards/double_m33_express/board.cmake index f84e629c7..3324ce888 100644 --- a/hw/bsp/lpc55/boards/double_m33_express/board.cmake +++ b/hw/bsp/lpc55/boards/double_m33_express/board.cmake @@ -7,10 +7,13 @@ set(NXPLINK_DEVICE LPC55S69:LPCXpresso55S69) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/LPC55S69_cm33_core0_uf2.ld) +# Device port default to PORT1 Highspeed +if (NOT DEFINED PORT) + set(PORT 1) +endif() + function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC CPU_LPC55S69JBD100_cm33_core0 - # port 1 is highspeed - BOARD_TUD_RHPORT=1 ) endfunction() diff --git a/hw/bsp/lpc55/boards/lpcxpresso55s28/board.cmake b/hw/bsp/lpc55/boards/lpcxpresso55s28/board.cmake index d935b70e6..b3d0c3349 100644 --- a/hw/bsp/lpc55/boards/lpcxpresso55s28/board.cmake +++ b/hw/bsp/lpc55/boards/lpcxpresso55s28/board.cmake @@ -5,6 +5,11 @@ set(JLINK_DEVICE LPC55S28) set(PYOCD_TARGET LPC55S28) set(NXPLINK_DEVICE LPC55S28:LPCXpresso55S28) +# Device port default to PORT1 Highspeed +if (NOT DEFINED PORT) + set(PORT 1) +endif() + function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC CPU_LPC55S28JBD100 diff --git a/hw/bsp/lpc55/boards/lpcxpresso55s69/board.cmake b/hw/bsp/lpc55/boards/lpcxpresso55s69/board.cmake index fd7cb6de6..b52ec2f9d 100644 --- a/hw/bsp/lpc55/boards/lpcxpresso55s69/board.cmake +++ b/hw/bsp/lpc55/boards/lpcxpresso55s69/board.cmake @@ -1,14 +1,17 @@ set(MCU_VARIANT LPC55S69) set(MCU_CORE LPC55S69_cm33_core0) -set(JLINK_DEVICE LPC55S69) +set(JLINK_DEVICE LPC55S69_M33_0) set(PYOCD_TARGET LPC55S69) set(NXPLINK_DEVICE LPC55S69:LPCXpresso55S69) +# Device port default to PORT1 Highspeed +if (NOT DEFINED PORT) + set(PORT 1) +endif() + function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC CPU_LPC55S69JBD100_cm33_core0 - # port 1 is highspeed - # BOARD_TUD_RHPORT=1 ) endfunction() diff --git a/hw/bsp/lpc55/family.c b/hw/bsp/lpc55/family.c index 0fd85988a..cfd5b7032 100644 --- a/hw/bsp/lpc55/family.c +++ b/hw/bsp/lpc55/family.c @@ -72,13 +72,11 @@ //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ -void USB0_IRQHandler(void) -{ +void USB0_IRQHandler(void) { tud_int_handler(0); } -void USB1_IRQHandler(void) -{ +void USB1_IRQHandler(void) { tud_int_handler(1); } @@ -92,8 +90,7 @@ settings: sources: - {id: SYSCON.fro_hf.outFreq, value: 96 MHz} ******************************************************************/ -void BootClockFROHF96M(void) -{ +void BootClockFROHF96M(void) { /*!< Set up the clock sources */ /*!< Set up FRO */ POWER_DisablePD(kPDRUNCFG_PD_FRO192M); /*!< Ensure FRO is on */ @@ -116,8 +113,7 @@ void BootClockFROHF96M(void) SystemCoreClock = 96000000U; } -void board_init(void) -{ +void board_init(void) { // Enable IOCON clock CLOCK_EnableClock(kCLOCK_Iocon); @@ -138,7 +134,7 @@ void board_init(void) // LED IOCON_PinMuxSet(IOCON, LED_PORT, LED_PIN, IOCON_PIO_DIG_FUNC0_EN); - gpio_pin_config_t const led_config = { kGPIO_DigitalOutput, 1}; + gpio_pin_config_t const led_config = {kGPIO_DigitalOutput, 1}; GPIO_PinInit(GPIO, LED_PORT, LED_PIN, &led_config); board_led_write(0); @@ -157,7 +153,7 @@ void board_init(void) // Button IOCON_PinMuxSet(IOCON, BUTTON_PORT, BUTTON_PIN, IOCON_PIO_DIG_FUNC0_EN); - gpio_pin_config_t const button_config = { kGPIO_DigitalInput, 0}; + gpio_pin_config_t const button_config = {kGPIO_DigitalInput, 0}; GPIO_PinInit(GPIO, BUTTON_PORT, BUTTON_PIN, &button_config); #ifdef UART_DEV @@ -170,8 +166,8 @@ void board_init(void) usart_config_t uart_config; USART_GetDefaultConfig(&uart_config); uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE; - uart_config.enableTx = true; - uart_config.enableRx = true; + uart_config.enableTx = true; + uart_config.enableRx = true; USART_Init(UART_DEV, &uart_config, 12000000); #endif @@ -250,9 +246,8 @@ void board_init(void) // Board porting API //--------------------------------------------------------------------+ -void board_led_write(bool state) -{ - GPIO_PinWrite(GPIO, LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +void board_led_write(bool state) { + GPIO_PinWrite(GPIO, LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); #ifdef NEOPIXEL_PIN if (state) { @@ -266,33 +261,50 @@ void board_led_write(bool state) #endif } -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { // active low return BUTTON_STATE_ACTIVE == GPIO_PinRead(GPIO, BUTTON_PORT, BUTTON_PIN); } -int board_uart_read(uint8_t* buf, int len) -{ - (void) buf; (void) len; +int board_uart_read(uint8_t* buf, int len) { + (void) buf; + (void) len; return 0; } -int board_uart_write(void const * buf, int len) -{ - USART_WriteBlocking(UART_DEV, (uint8_t const *) buf, len); +int board_uart_write(void const* buf, int len) { + USART_WriteBlocking(UART_DEV, (uint8_t const*) buf, len); return len; } #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 + + +#ifndef __ICCARM__ +// Implement _start() since we use linker flag '-nostartfiles'. +// Requires defined __STARTUP_CLEAR_BSS, +extern int main(void); + +TU_ATTR_UNUSED void _start(void) { + // called by startup code + main(); + while (1) {} +} + +#ifdef __clang__ +void _exit (int __status) { + while (1) {} +} +#endif + +#endif diff --git a/hw/bsp/lpc55/family.cmake b/hw/bsp/lpc55/family.cmake index dfd08a732..21c57fc1f 100644 --- a/hw/bsp/lpc55/family.cmake +++ b/hw/bsp/lpc55/family.cmake @@ -1,85 +1,108 @@ include_guard() -if (NOT BOARD) - message(FATAL_ERROR "BOARD not specified") -endif () - set(SDK_DIR ${TOP}/hw/mcu/nxp/mcux-sdk) set(CMSIS_DIR ${TOP}/lib/CMSIS_5) -# toolchain set up -set(CMAKE_SYSTEM_PROCESSOR cortex-m33 CACHE INTERNAL "System Processor") -set(CMAKE_TOOLCHAIN_FILE ${TOP}/tools/cmake/toolchain/arm_${TOOLCHAIN}.cmake) - -set(FAMILY_MCUS LPC55XX CACHE INTERNAL "") - # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR cortex-m33 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS LPC55 CACHE INTERNAL "") + +if (NOT DEFINED PORT) + set(PORT 0) +endif() + +# Host port will be the other port if available +set(HOST_PORT $) #------------------------------------ # BOARD_TARGET #------------------------------------ # 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 - # driver - ${SDK_DIR}/drivers/lpc_gpio/fsl_gpio.c - ${SDK_DIR}/drivers/common/fsl_common_arm.c - ${SDK_DIR}/drivers/flexcomm/fsl_flexcomm.c - ${SDK_DIR}/drivers/flexcomm/fsl_usart.c - # mcu - ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_CORE}.c - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_power.c - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_reset.c - ) + if (TARGET ${BOARD_TARGET}) + return() + endif() + + if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_CORE}_flash.ld) + endif () + set(LD_FILE_Clang ${LD_FILE_GNU}) + + if (NOT DEFINED STARTUP_FILE_GNU) + set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_CORE}.S) + endif () + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + # driver + ${SDK_DIR}/drivers/lpc_gpio/fsl_gpio.c + ${SDK_DIR}/drivers/common/fsl_common_arm.c + ${SDK_DIR}/drivers/flexcomm/fsl_flexcomm.c + ${SDK_DIR}/drivers/flexcomm/fsl_usart.c + # mcu + ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_CORE}.c + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_power.c + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_reset.c + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${TOP}/lib/sct_neopixel + # driver + ${SDK_DIR}/drivers/common + ${SDK_DIR}/drivers/flexcomm + ${SDK_DIR}/drivers/lpc_iocon + ${SDK_DIR}/drivers/lpc_gpio + ${SDK_DIR}/drivers/lpuart + ${SDK_DIR}/drivers/sctimer + # mcu + ${SDK_DIR}/devices/${MCU_VARIANT} + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers + ${CMSIS_DIR}/CMSIS/Core/Include + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + CFG_TUSB_MEM_ALIGN=TU_ATTR_ALIGNED\(64\) + BOARD_TUD_RHPORT=${PORT} + BOARD_TUH_RHPORT=${HOST_PORT} + __STARTUP_CLEAR_BSS + ) + + # Port 0 is Fullspeed, Port 1 is Highspeed. Port1 controller can only access USB_SRAM + if (PORT EQUAL 1) target_compile_definitions(${BOARD_TARGET} PUBLIC - CFG_TUSB_MEM_ALIGN=TU_ATTR_ALIGNED\(64\) + BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + BOARD_TUH_MAX_SPEED=OPT_MODE_FULL_SPEED + CFG_TUD_MEM_SECTION=__attribute__\(\(section\(\"m_usb_global\"\)\)\) ) - target_include_directories(${BOARD_TARGET} PUBLIC - ${TOP}/lib/sct_neopixel - # driver - ${SDK_DIR}/drivers/common - ${SDK_DIR}/drivers/flexcomm - ${SDK_DIR}/drivers/lpc_iocon - ${SDK_DIR}/drivers/lpc_gpio - ${SDK_DIR}/drivers/lpuart - ${SDK_DIR}/drivers/sctimer - # mcu - ${CMSIS_DIR}/CMSIS/Core/Include - ${SDK_DIR}/devices/${MCU_VARIANT} - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers + else () + target_compile_definitions(${BOARD_TARGET} PUBLIC + BOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED + BOARD_TUH_MAX_SPEED=OPT_MODE_HIGH_SPEED + CFG_TUH_MEM_SECTION=__attribute__\(\(section\(\"m_usb_global\"\)\)\) ) + endif () - update_board(${BOARD_TARGET}) + update_board(${BOARD_TARGET}) - if (NOT DEFINED LD_FILE_${CMAKE_C_COMPILER_ID}) - set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_CORE}_flash.ld) - endif () - - if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) - set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_CORE}.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}" + --specs=nosys.specs --specs=nano.specs + -nostartfiles + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" ) - - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${BOARD_TARGET} PUBLIC - # linker file - "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 () endif () endfunction() @@ -117,7 +140,7 @@ function(family_configure_example TARGET RTOS) ) # Add TinyUSB target and port source - family_add_tinyusb(${TARGET} OPT_MCU_LPC55XX ${RTOS}) + family_add_tinyusb(${TARGET} OPT_MCU_LPC55 ${RTOS}) target_sources(${TARGET}-tinyusb PUBLIC ${TOP}/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c ) diff --git a/hw/bsp/lpc55/family.mk b/hw/bsp/lpc55/family.mk index a87fa5acf..d82e85904 100644 --- a/hw/bsp/lpc55/family.mk +++ b/hw/bsp/lpc55/family.mk @@ -4,15 +4,17 @@ DEPS_SUBMODULES += lib/CMSIS_5 lib/sct_neopixel $(SDK_DIR) include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m33 +MCU_DIR = $(SDK_DIR)/devices/$(MCU_VARIANT) # Default to Highspeed PORT1 PORT ?= 1 CFLAGS += \ -flto \ + -D__STARTUP_CLEAR_BSS \ -DCFG_TUSB_MCU=OPT_MCU_LPC55XX \ -DCFG_TUSB_MEM_ALIGN='__attribute__((aligned(64)))' \ - -DBOARD_TUD_RHPORT=$(PORT) + -DBOARD_TUD_RHPORT=$(PORT) \ ifeq ($(PORT), 1) $(info "PORT1 High Speed") @@ -27,7 +29,9 @@ endif # mcu driver cause following warnings CFLAGS += -Wno-error=unused-parameter -Wno-error=float-equal -MCU_DIR = $(SDK_DIR)/devices/$(MCU_VARIANT) +LDFLAGS_GCC += \ + -nostartfiles \ + --specs=nosys.specs --specs=nano.specs \ # All source paths should be relative to the top level. LD_FILE ?= $(MCU_DIR)/gcc/$(MCU_CORE)_flash.ld diff --git a/hw/bsp/mcx/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/mcx/FreeRTOSConfig/FreeRTOSConfig.h index fc0ab1f2d..5bf990bab 100644 --- a/hw/bsp/mcx/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/mcx/FreeRTOSConfig/FreeRTOSConfig.h @@ -49,7 +49,11 @@ /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 -#define configENABLE_FPU 1 +#if defined(__ARM_FP) && __ARM_FP >= 4 + #define configENABLE_FPU 1 +#else + #define configENABLE_FPU 0 +#endif #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) @@ -73,14 +77,15 @@ #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 -#define configSUPPORT_STATIC_ALLOCATION 0 -#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 /* 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 +#define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 @@ -116,23 +121,6 @@ #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 diff --git a/hw/bsp/mcx/boards/frdm_mcxa153/board.cmake b/hw/bsp/mcx/boards/frdm_mcxa153/board.cmake new file mode 100644 index 000000000..7cd8991e6 --- /dev/null +++ b/hw/bsp/mcx/boards/frdm_mcxa153/board.cmake @@ -0,0 +1,21 @@ +set(MCU_VARIANT MCXA153) +set(MCU_CORE MCXA153) + +set(JLINK_DEVICE MCXA153_M33) +set(PYOCD_TARGET MCXA153) +set(NXPLINK_DEVICE MCXA153:MCXA153) + +set(PORT 0) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + CPU_MCXA153VLH + BOARD_TUD_RHPORT=0 + BOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED + CFG_EXAMPLE_VIDEO_READONLY + ) + target_sources(${TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clock_config.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/pin_mux.c + ) +endfunction() diff --git a/src/common/tusb_timeout.h b/hw/bsp/mcx/boards/frdm_mcxa153/board.h similarity index 58% rename from src/common/tusb_timeout.h rename to hw/bsp/mcx/boards/frdm_mcxa153/board.h index 533e67ab8..e207d89d9 100644 --- a/src/common/tusb_timeout.h +++ b/hw/bsp/mcx/boards/frdm_mcxa153/board.h @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019 Ha Thach (tinyusb.org) + * 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 @@ -24,57 +24,41 @@ * This file is part of the TinyUSB stack. */ -/** \ingroup Group_Common Common Files - * \defgroup Group_TimeoutTimer timeout timer - * @{ */ - -#ifndef _TUSB_TIMEOUT_H_ -#define _TUSB_TIMEOUT_H_ - -#include -#include +#ifndef BOARD_H_ +#define BOARD_H_ #ifdef __cplusplus extern "C" { #endif -typedef struct { - uint32_t start; - uint32_t interval; -}tu_timeout_t; +// LED +#define LED_GPIO GPIO3 +#define LED_CLK kCLOCK_GateGPIO3 +#define LED_PIN 12 // red +#define LED_STATE_ON 0 -#if 0 +// ISP button (Dummy, use unused pin +#define BUTTON_GPIO GPIO3 +#define BUTTON_CLK kCLOCK_GateGPIO3 +#define BUTTON_PIN 29 //sw2 +#define BUTTON_STATE_ACTIVE 0 -extern uint32_t tusb_hal_millis(void); +// UART +#define UART_DEV LPUART0 -static inline void tu_timeout_set(tu_timeout_t* tt, uint32_t msec) -{ - tt->interval = msec; - tt->start = tusb_hal_millis(); +static inline void board_uart_init_clock(void) { + /* attach 12 MHz clock to LPUART0 (debug console) */ + CLOCK_SetClockDiv(kCLOCK_DivLPUART0, 1u); + CLOCK_AttachClk(kFRO12M_to_LPUART0); + + RESET_PeripheralReset(kLPUART0_RST_SHIFT_RSTn); } -static inline bool tu_timeout_expired(tu_timeout_t* tt) -{ - return ( tusb_hal_millis() - tt->start ) >= tt->interval; -} - -// For used with periodic event to prevent drift -static inline void tu_timeout_reset(tu_timeout_t* tt) -{ - tt->start += tt->interval; -} - -static inline void tu_timeout_restart(tu_timeout_t* tt) -{ - tt->start = tusb_hal_millis(); -} - -#endif +// XTAL +#define XTAL0_CLK_HZ (24 * 1000 * 1000U) #ifdef __cplusplus - } +} #endif -#endif /* _TUSB_TIMEOUT_H_ */ - -/** @} */ +#endif diff --git a/hw/bsp/mcx/boards/frdm_mcxa153/board.mk b/hw/bsp/mcx/boards/frdm_mcxa153/board.mk new file mode 100644 index 000000000..af8416d8e --- /dev/null +++ b/hw/bsp/mcx/boards/frdm_mcxa153/board.mk @@ -0,0 +1,14 @@ +MCU_VARIANT = MCXA153 +MCU_CORE = MCXA153 +PORT = 0 + +CPU_CORE = cortex-m33-nodsp-nofp +CFLAGS += \ + -DCPU_MCXA153VLH \ + -DCFG_TUSB_MCU=OPT_MCU_MCXA15 \ + +JLINK_DEVICE = MCXA153 +PYOCD_TARGET = MCXA153 + +# flash using pyocd +flash: flash-jlink diff --git a/hw/bsp/mcx/boards/frdm_mcxa153/clock_config.c b/hw/bsp/mcx/boards/frdm_mcxa153/clock_config.c new file mode 100644 index 000000000..f16bc51f6 --- /dev/null +++ b/hw/bsp/mcx/boards/frdm_mcxa153/clock_config.c @@ -0,0 +1,468 @@ +/* + * Copyright 2023 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ +/* + * How to setup clock using clock driver functions: + * + * 1. Setup clock sources. + * + * 2. Set up wait states of the flash. + * + * 3. Set up all dividers. + * + * 4. Set up all selectors to provide selected clocks. + * + */ + +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Clocks v12.0 +processor: MCXA153 +package_id: MCXA153VLH +mcu_data: ksdk2_0 +processor_version: 0.13.0 + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +#include "fsl_clock.h" +#include "clock_config.h" +#include "fsl_spc.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* System clock frequency. */ +//uint32_t SystemCoreClock; + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ +void BOARD_InitBootClocks(void) +{ + BOARD_BootClockFRO96M(); +} + +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO12M ********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockFRO12M +outputs: +- {id: CLK_1M_clock.outFreq, value: 1 MHz} +- {id: CPU_clock.outFreq, value: 12 MHz} +- {id: FRO_12M_clock.outFreq, value: 12 MHz} +- {id: MAIN_clock.outFreq, value: 12 MHz} +- {id: Slow_clock.outFreq, value: 3 MHz} +- {id: System_clock.outFreq, value: 12 MHz} +settings: +- {id: SCGMode, value: SIRC} +- {id: FRO_HF_PERIPHERALS_EN_CFG, value: Disabled} +- {id: MRCC.OSTIMERCLKSEL.sel, value: VBAT.CLK16K_1} +- {id: SCG.SCSSEL.sel, value: SCG.SIRC} +- {id: SCG_FIRCCSR_FIRCEN_CFG, value: Disabled} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +void BOARD_BootClockFRO12M(void) +{ + uint32_t coreFreq; + spc_active_mode_core_ldo_option_t ldoOption; + spc_sram_voltage_config_t sramOption; + + /* Get the CPU Core frequency */ + coreFreq = CLOCK_GetCoreSysClkFreq(); + + /* The flow of increasing voltage and frequency */ + if (coreFreq <= BOARD_BOOTCLOCKFRO12M_CORE_CLOCK) { + /* Set the LDO_CORE VDD regulator level */ + ldoOption.CoreLDOVoltage = kSPC_CoreLDO_MidDriveVoltage; + ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; + (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); + /* Configure Flash to support different voltage level and frequency */ + FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x0U)); + /* Specifies the operating voltage for the SRAM's read/write timing margin */ + sramOption.operateVoltage = kSPC_sramOperateAt1P0V; + sramOption.requestVoltageUpdate = true; + (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); + } + + CLOCK_SetupFRO12MClocking(); /*!< Setup FRO12M clock */ + + CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /* !< Switch MAIN_CLK to FRO12M */ + + /* The flow of decreasing voltage and frequency */ + if (coreFreq > BOARD_BOOTCLOCKFRO12M_CORE_CLOCK) { + /* Configure Flash to support different voltage level and frequency */ + FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x0U)); + /* Specifies the operating voltage for the SRAM's read/write timing margin */ + sramOption.operateVoltage = kSPC_sramOperateAt1P0V; + sramOption.requestVoltageUpdate = true; + (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); + /* Set the LDO_CORE VDD regulator level */ + ldoOption.CoreLDOVoltage = kSPC_CoreLDO_MidDriveVoltage; + ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; + (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); + } + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + + /*!< Set up dividers */ + CLOCK_SetClockDiv(kCLOCK_DivAHBCLK, 1U); /* !< Set AHBCLKDIV divider to value 1 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKFRO12M_CORE_CLOCK; +} +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO24M ********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockFRO24M +outputs: +- {id: CLK_1M_clock.outFreq, value: 1 MHz} +- {id: CLK_48M_clock.outFreq, value: 48 MHz} +- {id: CPU_clock.outFreq, value: 24 MHz} +- {id: FRO_12M_clock.outFreq, value: 12 MHz} +- {id: FRO_HF_DIV_clock.outFreq, value: 48 MHz} +- {id: FRO_HF_clock.outFreq, value: 48 MHz} +- {id: MAIN_clock.outFreq, value: 48 MHz} +- {id: Slow_clock.outFreq, value: 6 MHz} +- {id: System_clock.outFreq, value: 24 MHz} +settings: +- {id: MRCC.OSTIMERCLKSEL.sel, value: VBAT.CLK16K_1} +- {id: SYSCON.AHBCLKDIV.scale, value: '2', locked: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockFRO24M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockFRO24M configuration + ******************************************************************************/ +void BOARD_BootClockFRO24M(void) +{ + uint32_t coreFreq; + spc_active_mode_core_ldo_option_t ldoOption; + spc_sram_voltage_config_t sramOption; + + /* Get the CPU Core frequency */ + coreFreq = CLOCK_GetCoreSysClkFreq(); + + /* The flow of increasing voltage and frequency */ + if (coreFreq <= BOARD_BOOTCLOCKFRO24M_CORE_CLOCK) { + /* Set the LDO_CORE VDD regulator level */ + ldoOption.CoreLDOVoltage = kSPC_CoreLDO_MidDriveVoltage; + ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; + (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); + /* Configure Flash to support different voltage level and frequency */ + FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x0U)); + /* Specifies the operating voltage for the SRAM's read/write timing margin */ + sramOption.operateVoltage = kSPC_sramOperateAt1P0V; + sramOption.requestVoltageUpdate = true; + (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); + } + + CLOCK_SetupFROHFClocking(48000000U); /*!< Enable FRO HF(48MHz) output */ + + CLOCK_SetupFRO12MClocking(); /*!< Setup FRO12M clock */ + + CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /* !< Switch MAIN_CLK to FRO_HF */ + + /* The flow of decreasing voltage and frequency */ + if (coreFreq > BOARD_BOOTCLOCKFRO24M_CORE_CLOCK) { + /* Configure Flash to support different voltage level and frequency */ + FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x0U)); + /* Specifies the operating voltage for the SRAM's read/write timing margin */ + sramOption.operateVoltage = kSPC_sramOperateAt1P0V; + sramOption.requestVoltageUpdate = true; + (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); + /* Set the LDO_CORE VDD regulator level */ + ldoOption.CoreLDOVoltage = kSPC_CoreLDO_MidDriveVoltage; + ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; + (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); + } + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + + /*!< Set up dividers */ + CLOCK_SetClockDiv(kCLOCK_DivAHBCLK, 2U); /* !< Set AHBCLKDIV divider to value 2 */ + CLOCK_SetClockDiv(kCLOCK_DivFRO_HF_DIV, 1U); /* !< Set FROHFDIV divider to value 1 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKFRO24M_CORE_CLOCK; +} +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO48M ********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockFRO48M +outputs: +- {id: CLK_1M_clock.outFreq, value: 1 MHz} +- {id: CLK_48M_clock.outFreq, value: 48 MHz} +- {id: CPU_clock.outFreq, value: 48 MHz} +- {id: FRO_12M_clock.outFreq, value: 12 MHz} +- {id: FRO_HF_DIV_clock.outFreq, value: 48 MHz} +- {id: FRO_HF_clock.outFreq, value: 48 MHz} +- {id: MAIN_clock.outFreq, value: 48 MHz} +- {id: Slow_clock.outFreq, value: 12 MHz} +- {id: System_clock.outFreq, value: 48 MHz} +settings: +- {id: MRCC.OSTIMERCLKSEL.sel, value: VBAT.CLK16K_1} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockFRO48M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockFRO48M configuration + ******************************************************************************/ +void BOARD_BootClockFRO48M(void) +{ + uint32_t coreFreq; + spc_active_mode_core_ldo_option_t ldoOption; + spc_sram_voltage_config_t sramOption; + + /* Get the CPU Core frequency */ + coreFreq = CLOCK_GetCoreSysClkFreq(); + + /* The flow of increasing voltage and frequency */ + if (coreFreq <= BOARD_BOOTCLOCKFRO48M_CORE_CLOCK) { + /* Set the LDO_CORE VDD regulator level */ + ldoOption.CoreLDOVoltage = kSPC_CoreLDO_MidDriveVoltage; + ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; + (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); + /* Configure Flash to support different voltage level and frequency */ + FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x1U)); + /* Specifies the operating voltage for the SRAM's read/write timing margin */ + sramOption.operateVoltage = kSPC_sramOperateAt1P0V; + sramOption.requestVoltageUpdate = true; + (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); + } + + CLOCK_SetupFROHFClocking(48000000U); /*!< Enable FRO HF(48MHz) output */ + + CLOCK_SetupFRO12MClocking(); /*!< Setup FRO12M clock */ + + CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /* !< Switch MAIN_CLK to FRO_HF */ + + /* The flow of decreasing voltage and frequency */ + if (coreFreq > BOARD_BOOTCLOCKFRO48M_CORE_CLOCK) { + /* Configure Flash to support different voltage level and frequency */ + FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x1U)); + /* Specifies the operating voltage for the SRAM's read/write timing margin */ + sramOption.operateVoltage = kSPC_sramOperateAt1P0V; + sramOption.requestVoltageUpdate = true; + (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); + /* Set the LDO_CORE VDD regulator level */ + ldoOption.CoreLDOVoltage = kSPC_CoreLDO_MidDriveVoltage; + ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; + (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); + } + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + + /*!< Set up dividers */ + CLOCK_SetClockDiv(kCLOCK_DivAHBCLK, 1U); /* !< Set AHBCLKDIV divider to value 1 */ + CLOCK_SetClockDiv(kCLOCK_DivFRO_HF_DIV, 1U); /* !< Set FROHFDIV divider to value 1 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKFRO48M_CORE_CLOCK; +} +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO64M ********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockFRO64M +outputs: +- {id: CLK_1M_clock.outFreq, value: 1 MHz} +- {id: CLK_48M_clock.outFreq, value: 48 MHz} +- {id: CPU_clock.outFreq, value: 64 MHz} +- {id: FRO_12M_clock.outFreq, value: 12 MHz} +- {id: FRO_HF_DIV_clock.outFreq, value: 64 MHz} +- {id: FRO_HF_clock.outFreq, value: 64 MHz} +- {id: MAIN_clock.outFreq, value: 64 MHz} +- {id: Slow_clock.outFreq, value: 16 MHz} +- {id: System_clock.outFreq, value: 64 MHz} +settings: +- {id: VDD_CORE, value: voltage_1v1} +- {id: MRCC.FROHFDIV.scale, value: '1', locked: true} +- {id: MRCC.OSTIMERCLKSEL.sel, value: VBAT.CLK16K_1} +- {id: SYSCON.AHBCLKDIV.scale, value: '1', locked: true} +sources: +- {id: SCG.FIRC.outFreq, value: 64 MHz} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockFRO64M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockFRO64M configuration + ******************************************************************************/ +void BOARD_BootClockFRO64M(void) +{ + uint32_t coreFreq; + spc_active_mode_core_ldo_option_t ldoOption; + spc_sram_voltage_config_t sramOption; + + /* Get the CPU Core frequency */ + coreFreq = CLOCK_GetCoreSysClkFreq(); + + /* The flow of increasing voltage and frequency */ + if (coreFreq <= BOARD_BOOTCLOCKFRO64M_CORE_CLOCK) { + /* Set the LDO_CORE VDD regulator level */ + ldoOption.CoreLDOVoltage = kSPC_CoreLDO_NormalVoltage; + ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; + (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); + /* Configure Flash to support different voltage level and frequency */ + FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x1U)); + /* Specifies the operating voltage for the SRAM's read/write timing margin */ + sramOption.operateVoltage = kSPC_sramOperateAt1P1V; + sramOption.requestVoltageUpdate = true; + (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); + } + + CLOCK_SetupFROHFClocking(64000000U); /*!< Enable FRO HF(64MHz) output */ + + CLOCK_SetupFRO12MClocking(); /*!< Setup FRO12M clock */ + + CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /* !< Switch MAIN_CLK to FRO_HF */ + + /* The flow of decreasing voltage and frequency */ + if (coreFreq > BOARD_BOOTCLOCKFRO64M_CORE_CLOCK) { + /* Configure Flash to support different voltage level and frequency */ + FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x1U)); + /* Specifies the operating voltage for the SRAM's read/write timing margin */ + sramOption.operateVoltage = kSPC_sramOperateAt1P1V; + sramOption.requestVoltageUpdate = true; + (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); + /* Set the LDO_CORE VDD regulator level */ + ldoOption.CoreLDOVoltage = kSPC_CoreLDO_NormalVoltage; + ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; + (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); + } + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + + /*!< Set up dividers */ + CLOCK_SetClockDiv(kCLOCK_DivAHBCLK, 1U); /* !< Set AHBCLKDIV divider to value 1 */ + CLOCK_SetClockDiv(kCLOCK_DivFRO_HF_DIV, 1U); /* !< Set FROHFDIV divider to value 1 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKFRO64M_CORE_CLOCK; +} +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO96M ********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockFRO96M +called_from_default_init: true +outputs: +- {id: CLK_1M_clock.outFreq, value: 1 MHz} +- {id: CLK_48M_clock.outFreq, value: 48 MHz} +- {id: CPU_clock.outFreq, value: 96 MHz} +- {id: FRO_12M_clock.outFreq, value: 12 MHz} +- {id: FRO_HF_DIV_clock.outFreq, value: 96 MHz} +- {id: FRO_HF_clock.outFreq, value: 96 MHz} +- {id: MAIN_clock.outFreq, value: 96 MHz} +- {id: Slow_clock.outFreq, value: 24 MHz} +- {id: System_clock.outFreq, value: 96 MHz} +settings: +- {id: VDD_CORE, value: voltage_1v1} +- {id: CLKOUTDIV_HALT, value: Enable} +- {id: MRCC.FROHFDIV.scale, value: '1', locked: true} +- {id: MRCC.OSTIMERCLKSEL.sel, value: VBAT.CLK16K_1} +- {id: SYSCON.AHBCLKDIV.scale, value: '1', locked: true} +sources: +- {id: SCG.FIRC.outFreq, value: 96 MHz} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockFRO96M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockFRO96M configuration + ******************************************************************************/ +void BOARD_BootClockFRO96M(void) +{ + uint32_t coreFreq; + spc_active_mode_core_ldo_option_t ldoOption; + spc_sram_voltage_config_t sramOption; + + /* Get the CPU Core frequency */ + coreFreq = CLOCK_GetCoreSysClkFreq(); + + /* The flow of increasing voltage and frequency */ + if (coreFreq <= BOARD_BOOTCLOCKFRO96M_CORE_CLOCK) { + /* Set the LDO_CORE VDD regulator level */ + ldoOption.CoreLDOVoltage = kSPC_CoreLDO_NormalVoltage; + ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; + (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); + /* Configure Flash to support different voltage level and frequency */ + FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x2U)); + /* Specifies the operating voltage for the SRAM's read/write timing margin */ + sramOption.operateVoltage = kSPC_sramOperateAt1P1V; + sramOption.requestVoltageUpdate = true; + (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); + } + + CLOCK_SetupFROHFClocking(96000000U); /*!< Enable FRO HF(96MHz) output */ + + CLOCK_SetupFRO12MClocking(); /*!< Setup FRO12M clock */ + + CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /* !< Switch MAIN_CLK to FRO_HF */ + + /* The flow of decreasing voltage and frequency */ + if (coreFreq > BOARD_BOOTCLOCKFRO96M_CORE_CLOCK) { + /* Configure Flash to support different voltage level and frequency */ + FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x2U)); + /* Specifies the operating voltage for the SRAM's read/write timing margin */ + sramOption.operateVoltage = kSPC_sramOperateAt1P1V; + sramOption.requestVoltageUpdate = true; + (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); + /* Set the LDO_CORE VDD regulator level */ + ldoOption.CoreLDOVoltage = kSPC_CoreLDO_NormalVoltage; + ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; + (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); + } + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + + /*!< Set up dividers */ + CLOCK_SetClockDiv(kCLOCK_DivAHBCLK, 1U); /* !< Set AHBCLKDIV divider to value 1 */ + CLOCK_SetClockDiv(kCLOCK_DivFRO_HF_DIV, 1U); /* !< Set FROHFDIV divider to value 1 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKFRO96M_CORE_CLOCK; +} diff --git a/hw/bsp/mcx/boards/frdm_mcxa153/clock_config.h b/hw/bsp/mcx/boards/frdm_mcxa153/clock_config.h new file mode 100644 index 000000000..aae811052 --- /dev/null +++ b/hw/bsp/mcx/boards/frdm_mcxa153/clock_config.h @@ -0,0 +1,170 @@ +/* + * Copyright 2023 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO12M ********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKFRO12M_CORE_CLOCK 12000000U /*!< Core clock frequency: 12000000Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockFRO12M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO24M ********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockFRO24M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKFRO24M_CORE_CLOCK 24000000U /*!< Core clock frequency: 24000000Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockFRO24M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockFRO24M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO48M ********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockFRO48M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKFRO48M_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockFRO48M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockFRO48M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO64M ********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockFRO64M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKFRO64M_CORE_CLOCK 64000000U /*!< Core clock frequency: 64000000Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockFRO64M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockFRO64M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO96M ********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockFRO96M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKFRO96M_CORE_CLOCK 96000000U /*!< Core clock frequency: 96000000Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockFRO96M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockFRO96M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ diff --git a/hw/bsp/mcx/boards/frdm_mcxa153/pin_mux.c b/hw/bsp/mcx/boards/frdm_mcxa153/pin_mux.c new file mode 100644 index 000000000..cc8f56e63 --- /dev/null +++ b/hw/bsp/mcx/boards/frdm_mcxa153/pin_mux.c @@ -0,0 +1,159 @@ +/* + * Copyright 2023 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Pins v14.0 +processor: MCXA153 +package_id: MCXA153VLH +mcu_data: ksdk2_0 +processor_version: 0.14.3 +pin_labels: +- {pin_num: '38', pin_signal: P3_12/LPUART2_RTS_B/CT1_MAT2/PWM0_X0, label: LED_RED, identifier: LED_RED} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +#include "fsl_common.h" +#include "fsl_port.h" +#include "fsl_gpio.h" +#include "pin_mux.h" + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitBootPins + * Description : Calls initialization functions. + * + * END ****************************************************************************************************************/ +void BOARD_InitBootPins(void) +{ + BOARD_InitPins(); +} + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitPins: +- options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} +- pin_list: + - {pin_num: '38', peripheral: GPIO3, signal: 'GPIO, 12', pin_signal: P3_12/LPUART2_RTS_B/CT1_MAT2/PWM0_X0, direction: OUTPUT, gpio_init_state: 'false', slew_rate: fast, + open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, input_buffer: enable, invert_input: normal} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitPins(void) +{ + RESET_PeripheralReset(kLPUART0_RST_SHIFT_RSTn); + RESET_PeripheralReset(kPORT0_RST_SHIFT_RSTn); + CLOCK_SetClockDiv(kCLOCK_DivLPUART0, 1u); + CLOCK_AttachClk(kFRO12M_to_LPUART0); + + /* write to PORT0: Peripheral clock is enabled */ + CLOCK_EnableClock(kCLOCK_GatePORT0); + + /* Write to GPIO3: Peripheral clock is enabled */ + CLOCK_EnableClock(kCLOCK_GateGPIO3); + /* Write to PORT3: Peripheral clock is enabled */ + CLOCK_EnableClock(kCLOCK_GatePORT3); + /* GPIO3 peripheral is released from reset */ + RESET_ReleasePeripheralReset(kGPIO3_RST_SHIFT_RSTn); + /* PORT3 peripheral is released from reset */ + RESET_ReleasePeripheralReset(kPORT3_RST_SHIFT_RSTn); + + const port_pin_config_t port3_12_pin38_config = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Low internal pull resistor value is selected. */ + kPORT_LowPullResistor, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive input filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain output is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Normal drive strength is configured */ + kPORT_NormalDriveStrength, + /* Pin is configured as P3_12 */ + kPORT_MuxAlt0, + /* Digital input enabled */ + kPORT_InputBufferEnable, + /* Digital input is not inverted */ + kPORT_InputNormal, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORT3_12 (pin 38) is configured as P3_12 */ + PORT_SetPinConfig(PORT3, 12U, &port3_12_pin38_config); + + const port_pin_config_t port0_2_pin51_config = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Low internal pull resistor value is selected. */ + kPORT_LowPullResistor, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive input filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain output is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Normal drive strength is configured */ + kPORT_NormalDriveStrength, + /* Pin is configured as LPUART0_RXD */ + kPORT_MuxAlt2, + /* Digital input enabled */ + kPORT_InputBufferEnable, + /* Digital input is not inverted */ + kPORT_InputNormal, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORT0_2 (pin 51) is configured as LPUART0_RXD */ + PORT_SetPinConfig(PORT0, 2U, &port0_2_pin51_config); + + const port_pin_config_t port0_3_pin52_config = {/* Internal pull-up resistor is enabled */ + kPORT_PullUp, + /* Low internal pull resistor value is selected. */ + kPORT_LowPullResistor, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive input filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain output is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Normal drive strength is configured */ + kPORT_NormalDriveStrength, + /* Pin is configured as LPUART0_TXD */ + kPORT_MuxAlt2, + /* Digital input enabled */ + kPORT_InputBufferEnable, + /* Digital input is not inverted */ + kPORT_InputNormal, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORT0_3 (pin 52) is configured as LPUART0_TXD */ + PORT_SetPinConfig(PORT0, 3U, &port0_3_pin52_config); + +} +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/mcx/boards/frdm_mcxa153/pin_mux.h b/hw/bsp/mcx/boards/frdm_mcxa153/pin_mux.h new file mode 100644 index 000000000..06b6fdee9 --- /dev/null +++ b/hw/bsp/mcx/boards/frdm_mcxa153/pin_mux.h @@ -0,0 +1,47 @@ +/* + * Copyright 2022 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _PIN_MUX_H_ +#define _PIN_MUX_H_ + +/*! + * @addtogroup pin_mux + * @{ + */ + +/*********************************************************************************************************************** + * API + **********************************************************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Calls initialization functions. + * + */ +void BOARD_InitBootPins(void); + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitPins(void); + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif /* _PIN_MUX_H_ */ + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/mcx/boards/frdm_mcxn947/board.cmake b/hw/bsp/mcx/boards/frdm_mcxn947/board.cmake new file mode 100644 index 000000000..8c3280743 --- /dev/null +++ b/hw/bsp/mcx/boards/frdm_mcxn947/board.cmake @@ -0,0 +1,21 @@ +set(MCU_VARIANT MCXN947) +set(MCU_CORE MCXN947_cm33_core0) + +set(JLINK_DEVICE MCXN947_M33_0) +set(PYOCD_TARGET MCXN947) +set(NXPLINK_DEVICE MCXN947:MCXN947) + +set(PORT 1) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + CPU_MCXN947VDF_cm33_core0 + BOARD_TUD_RHPORT=${PORT} + # port 0 is fullspeed, port 1 is highspeed + BOARD_TUD_MAX_SPEED=$ + ) + target_sources(${TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clock_config.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/pin_mux.c + ) +endfunction() diff --git a/hw/bsp/mcx/boards/frdm_mcxn947/board.h b/hw/bsp/mcx/boards/frdm_mcxn947/board.h new file mode 100644 index 000000000..acb73363f --- /dev/null +++ b/hw/bsp/mcx/boards/frdm_mcxn947/board.h @@ -0,0 +1,66 @@ +/* + * 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 + +// LED +#define LED_GPIO GPIO0 +#define LED_CLK kCLOCK_Gpio0 +#define LED_PIN 10 // red +#define LED_STATE_ON 0 + +// WAKE button (Dummy, use unused pin +#define BUTTON_GPIO GPIO0 +#define BUTTON_CLK kCLOCK_Gpio0 +#define BUTTON_PIN 23 +#define BUTTON_STATE_ACTIVE 0 + +// UART +#define UART_DEV LPUART4 + +static inline void board_uart_init_clock(void) { + /* attach FRO 12M to FLEXCOMM4 */ + CLOCK_SetClkDiv(kCLOCK_DivFlexcom4Clk, 1u); + CLOCK_AttachClk(kFRO12M_to_FLEXCOMM4); + RESET_ClearPeripheralReset(kFC4_RST_SHIFT_RSTn); +} + +//#define UART_RX_PINMUX 0, 24, IOCON_PIO_DIG_FUNC1_EN +//#define UART_TX_PINMUX 0, 25, IOCON_PIO_DIG_FUNC1_EN + +// XTAL +#define XTAL0_CLK_HZ (24 * 1000 * 1000U) + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/hw/bsp/mcx/boards/frdm_mcxn947/board.mk b/hw/bsp/mcx/boards/frdm_mcxn947/board.mk new file mode 100644 index 000000000..22fefd79b --- /dev/null +++ b/hw/bsp/mcx/boards/frdm_mcxn947/board.mk @@ -0,0 +1,14 @@ +MCU_VARIANT = MCXN947 +MCU_CORE = MCXN947_cm33_core0 +PORT ?= 1 + +CPU_CORE = cortex-m33 +CFLAGS += \ + -DCPU_MCXN947VDF_cm33_core0 \ + -DCFG_TUSB_MCU=OPT_MCU_MCXN9 \ + +JLINK_DEVICE = MCXN947_M33_0 +PYOCD_TARGET = MCXN947 + +# flash using pyocd +flash: flash-jlink diff --git a/hw/bsp/mcx/boards/frdm_mcxn947/clock_config.c b/hw/bsp/mcx/boards/frdm_mcxn947/clock_config.c new file mode 100644 index 000000000..37d2b4dfc --- /dev/null +++ b/hw/bsp/mcx/boards/frdm_mcxn947/clock_config.c @@ -0,0 +1,338 @@ +/* + * Copyright 2022 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ +/* + * How to setup clock using clock driver functions: + * + * 1. Setup clock sources. + * + * 2. Set up wait states of the flash. + * + * 3. Set up all dividers. + * + * 4. Set up all selectors to provide selected clocks. + * + */ + +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Clocks v10.0 +processor: MCXN947 +package_id: MCXN947VDF +mcu_data: ksdk2_0 +processor_version: 0.12.3 +board: MCX-N9XX-EVK + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +#include "clock_config.h" +#include "fsl_clock.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* System clock frequency. */ +// extern uint32_t SystemCoreClock; + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ +void BOARD_InitBootClocks(void) +{ + BOARD_BootClockPLL150M(); +} + +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO12M ********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockFRO12M +outputs: +- {id: CLK_144M_clock.outFreq, value: 144 MHz} +- {id: CLK_48M_clock.outFreq, value: 48 MHz} +- {id: FRO_12M_clock.outFreq, value: 12 MHz} +- {id: MAIN_clock.outFreq, value: 12 MHz} +- {id: Slow_clock.outFreq, value: 3 MHz} +- {id: System_clock.outFreq, value: 12 MHz} +- {id: gdet_clock.outFreq, value: 48 MHz} +- {id: trng_clock.outFreq, value: 48 MHz} +settings: +- {id: SCGMode, value: SIRC} +- {id: SCG.SCSSEL.sel, value: SCG.SIRC} +- {id: SCG_FIRCCSR_FIRCEN_CFG, value: Disabled} +- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} +- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +void BOARD_BootClockFRO12M(void) +{ + /*!< Enable SCG clock */ + CLOCK_EnableClock(kCLOCK_Scg); + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO12M */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKFRO12M_CORE_CLOCK; +} + +/******************************************************************************* + ******************* Configuration BOARD_BootClockFROHF48M ********************* + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockFROHF48M +outputs: +- {id: CLK_144M_clock.outFreq, value: 144 MHz} +- {id: CLK_48M_clock.outFreq, value: 48 MHz} +- {id: FRO_12M_clock.outFreq, value: 12 MHz} +- {id: FRO_HF_clock.outFreq, value: 48 MHz} +- {id: MAIN_clock.outFreq, value: 48 MHz} +- {id: Slow_clock.outFreq, value: 12 MHz} +- {id: System_clock.outFreq, value: 48 MHz} +- {id: gdet_clock.outFreq, value: 48 MHz} +- {id: trng_clock.outFreq, value: 48 MHz} +settings: +- {id: SYSCON.FLEXCAN0CLKSEL.sel, value: NO_CLOCK} +- {id: SYSCON.FLEXCAN1CLKSEL.sel, value: NO_CLOCK} +- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} +- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockFROHF48M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockFROHF48M configuration + ******************************************************************************/ +void BOARD_BootClockFROHF48M(void) +{ + /*!< Enable SCG clock */ + CLOCK_EnableClock(kCLOCK_Scg); + + CLOCK_SetupFROHFClocking(48000000U); /*!< Enable FRO HF(48MHz) output */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO_HF */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKFROHF48M_CORE_CLOCK; +} + +/******************************************************************************* + ******************* Configuration BOARD_BootClockFROHF144M ******************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockFROHF144M +outputs: +- {id: CLK_144M_clock.outFreq, value: 144 MHz} +- {id: CLK_48M_clock.outFreq, value: 48 MHz} +- {id: FRO_12M_clock.outFreq, value: 12 MHz} +- {id: FRO_HF_clock.outFreq, value: 144 MHz} +- {id: MAIN_clock.outFreq, value: 144 MHz} +- {id: Slow_clock.outFreq, value: 18 MHz} +- {id: System_clock.outFreq, value: 72 MHz} +- {id: gdet_clock.outFreq, value: 48 MHz} +- {id: trng_clock.outFreq, value: 48 MHz} +settings: +- {id: SYSCON.AHBCLKDIV.scale, value: '2', locked: true} +- {id: SYSCON.FLEXCAN0CLKSEL.sel, value: NO_CLOCK} +- {id: SYSCON.FLEXCAN1CLKSEL.sel, value: NO_CLOCK} +- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} +- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} +sources: +- {id: SCG.FIRC.outFreq, value: 144 MHz} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockFROHF144M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockFROHF144M configuration + ******************************************************************************/ +void BOARD_BootClockFROHF144M(void) +{ + /*!< Enable SCG clock */ + CLOCK_EnableClock(kCLOCK_Scg); + + CLOCK_SetupFROHFClocking(144000000U); /*!< Enable FRO HF(144MHz) output */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO_HF */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 2U); /*!< Set AHBCLKDIV divider to value 2 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKFROHF144M_CORE_CLOCK; +} + +/******************************************************************************* + ******************** Configuration BOARD_BootClockPLL150M ********************* + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockPLL150M +called_from_default_init: true +outputs: +- {id: CLK_144M_clock.outFreq, value: 144 MHz} +- {id: CLK_48M_clock.outFreq, value: 48 MHz} +- {id: FRO_12M_clock.outFreq, value: 12 MHz} +- {id: FRO_HF_clock.outFreq, value: 48 MHz} +- {id: MAIN_clock.outFreq, value: 150 MHz} +- {id: PLL0_CLK_clock.outFreq, value: 150 MHz} +- {id: Slow_clock.outFreq, value: 37.5 MHz} +- {id: System_clock.outFreq, value: 150 MHz} +- {id: gdet_clock.outFreq, value: 48 MHz} +- {id: trng_clock.outFreq, value: 48 MHz} +settings: +- {id: PLL0_Mode, value: Normal} +- {id: RunPowerMode, value: OD} +- {id: SCGMode, value: PLL0} +- {id: SCG.PLL0M_MULT.scale, value: '50', locked: true} +- {id: SCG.PLL0SRCSEL.sel, value: SCG.FIRC_48M} +- {id: SCG.PLL0_NDIV.scale, value: '8', locked: true} +- {id: SCG.SCSSEL.sel, value: SCG.PLL0_CLK} +- {id: SYSCON.FLEXCAN0CLKSEL.sel, value: NO_CLOCK} +- {id: SYSCON.FLEXCAN1CLKSEL.sel, value: NO_CLOCK} +- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} +- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockPLL150M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockPLL150M configuration + ******************************************************************************/ +void BOARD_BootClockPLL150M(void) +{ + /*!< Enable SCG clock */ + CLOCK_EnableClock(kCLOCK_Scg); + + CLOCK_SetupFROHFClocking(48000000U); /*!< Enable FRO HF(48MHz) output */ + + /*!< Set up PLL0 */ + const pll_setup_t pll0Setup = { + .pllctrl = SCG_APLLCTRL_SOURCE(1U) | SCG_APLLCTRL_SELI(27U) | SCG_APLLCTRL_SELP(13U), + .pllndiv = SCG_APLLNDIV_NDIV(8U), + .pllpdiv = SCG_APLLPDIV_PDIV(1U), + .pllmdiv = SCG_APLLMDIV_MDIV(50U), + .pllRate = 150000000U + }; + CLOCK_SetPLL0Freq(&pll0Setup); /*!< Configure PLL0 to the desired values */ + CLOCK_SetPll0MonitorMode(kSCG_Pll0MonitorDisable); /* Pll0 Monitor is disabled */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kPLL0_to_MAIN_CLK); /*!< Switch MAIN_CLK to PLL0 */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKPLL150M_CORE_CLOCK; +} + +/******************************************************************************* + ******************** Configuration BOARD_BootClockPLL100M ********************* + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockPLL100M +outputs: +- {id: CLK_144M_clock.outFreq, value: 144 MHz} +- {id: CLK_48M_clock.outFreq, value: 48 MHz} +- {id: CLK_IN_clock.outFreq, value: 24 MHz} +- {id: FRO_12M_clock.outFreq, value: 12 MHz} +- {id: MAIN_clock.outFreq, value: 100 MHz} +- {id: PLL1_CLK_clock.outFreq, value: 100 MHz} +- {id: Slow_clock.outFreq, value: 25 MHz} +- {id: System_clock.outFreq, value: 100 MHz} +- {id: gdet_clock.outFreq, value: 48 MHz} +- {id: trng_clock.outFreq, value: 48 MHz} +settings: +- {id: PLL1_Mode, value: Normal} +- {id: SCGMode, value: PLL1} +- {id: SCG.PLL1M_MULT.scale, value: '100', locked: true} +- {id: SCG.PLL1_NDIV.scale, value: '6', locked: true} +- {id: SCG.PLL1_PDIV.scale, value: '4', locked: true} +- {id: SCG.SCSSEL.sel, value: SCG.PLL1_CLK} +- {id: SCG_FIRCCSR_FIRCEN_CFG, value: Disabled} +- {id: SCG_SOSCCSR_SOSCEN_CFG, value: Enabled} +- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a} +- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a} +sources: +- {id: SCG.SOSC.outFreq, value: 24 MHz, enabled: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockPLL100M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockPLL100M configuration + ******************************************************************************/ +void BOARD_BootClockPLL100M(void) +{ + /*!< Enable SCG clock */ + CLOCK_EnableClock(kCLOCK_Scg); + + CLOCK_SetupExtClocking(24000000U); + CLOCK_SetSysOscMonitorMode(kSCG_SysOscMonitorDisable); /* System OSC Clock Monitor is disabled */ + + /*!< Set up PLL1 */ + const pll_setup_t pll1Setup = { + .pllctrl = SCG_SPLLCTRL_SOURCE(0U) | SCG_SPLLCTRL_SELI(53U) | SCG_SPLLCTRL_SELP(26U), + .pllndiv = SCG_SPLLNDIV_NDIV(6U), + .pllpdiv = SCG_SPLLPDIV_PDIV(2U), + .pllmdiv = SCG_SPLLMDIV_MDIV(100U), + .pllRate = 100000000U + }; + CLOCK_SetPLL1Freq(&pll1Setup); /*!< Configure PLL1 to the desired values */ + CLOCK_SetPll1MonitorMode(kSCG_Pll1MonitorDisable); /* Pll1 Monitor is disabled */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kPLL1_to_MAIN_CLK); /*!< Switch MAIN_CLK to PLL1 */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */ + + /* Set SystemCoreClock variable */ + SystemCoreClock = BOARD_BOOTCLOCKPLL100M_CORE_CLOCK; +} diff --git a/hw/bsp/mcx/boards/frdm_mcxn947/clock_config.h b/hw/bsp/mcx/boards/frdm_mcxn947/clock_config.h new file mode 100644 index 000000000..c238a0423 --- /dev/null +++ b/hw/bsp/mcx/boards/frdm_mcxn947/clock_config.h @@ -0,0 +1,177 @@ +/* + * Copyright 2022 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal frequency in Hz */ +#define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32K frequency in Hz */ + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO12M ********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKFRO12M_CORE_CLOCK 12000000U /*!< Core clock frequency: 12000000Hz */ +#define BOARD_BOOTCLOCKFRO12M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockFRO12M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************* Configuration BOARD_BootClockFROHF48M ********************* + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockFROHF48M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKFROHF48M_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ +#define BOARD_BOOTCLOCKFROHF48M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockFROHF48M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockFROHF48M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************* Configuration BOARD_BootClockFROHF144M ******************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockFROHF144M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKFROHF144M_CORE_CLOCK 144000000U /*!< Core clock frequency: 144000000Hz */ +#define BOARD_BOOTCLOCKFROHF144M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockFROHF144M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockFROHF144M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockPLL150M ********************* + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockPLL150M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKPLL150M_CORE_CLOCK 150000000U /*!< Core clock frequency: 150000000Hz */ +#define BOARD_BOOTCLOCKPLL150M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockPLL150M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockPLL150M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockPLL100M ********************* + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockPLL100M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKPLL100M_CORE_CLOCK 100000000U /*!< Core clock frequency: 100000000Hz */ +#define BOARD_BOOTCLOCKPLL100M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockPLL100M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockPLL100M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ diff --git a/hw/bsp/mcx/boards/frdm_mcxn947/pin_mux.c b/hw/bsp/mcx/boards/frdm_mcxn947/pin_mux.c new file mode 100644 index 000000000..c33790ac5 --- /dev/null +++ b/hw/bsp/mcx/boards/frdm_mcxn947/pin_mux.c @@ -0,0 +1,143 @@ +/* + * Copyright 2022 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Pins v12.0 +processor: MCXN947 +package_id: MCXN947VDF +mcu_data: ksdk2_0 +processor_version: 0.12.3 + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +#include "fsl_common.h" +#include "fsl_port.h" +#include "pin_mux.h" + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitBootPins + * Description : Calls initialization functions. + * + * END ****************************************************************************************************************/ +void BOARD_InitBootPins(void) +{ + BOARD_InitPins(); +} + +/* clang-format off */ +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitPins: +- options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'} +- pin_list: + - {pin_num: A1, peripheral: LPFlexcomm4, signal: LPFLEXCOMM_P0, pin_signal: PIO1_8/WUU0_IN10/LPTMR1_ALT3/TRACE_DATA0/FC4_P0/FC5_P4/CT_INP8/SCT0_OUT2/FLEXIO0_D16/PLU_OUT0/ENET0_TXD2/I3C1_SDA/TSI0_CH17/ADC1_A8, + slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable, pull_value: low, input_buffer: enable, + invert_input: normal} + - {pin_num: B1, peripheral: LPFlexcomm4, signal: LPFLEXCOMM_P1, pin_signal: PIO1_9/TRACE_DATA1/FC4_P1/FC5_P5/CT_INP9/SCT0_OUT3/FLEXIO0_D17/PLU_OUT1/ENET0_TXD3/I3C1_SCL/TSI0_CH18/ADC1_A9, + slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, passive_filter: disable, input_buffer: enable, invert_input: normal} + - {pin_num: B7, peripheral: GPIO0, signal: 'GPIO, 23', pin_signal: PIO0_23/WUU0_IN5/EWM0_OUT_b/FC1_P3/CT_INP3/FLEXIO0_D7/ADC0_A15/CMP2_IN2, direction: INPUT, slew_rate: fast, + open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, input_buffer: enable, invert_input: normal} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ +/* clang-format on */ + +/* FUNCTION ************************************************************************************************************ + * + * Function Name : BOARD_InitPins + * Description : Configures pin routing and optionally pin electrical features. + * + * END ****************************************************************************************************************/ +void BOARD_InitPins(void) +{ + /* Enables the clock for PORT0: Enables clock */ + CLOCK_EnableClock(kCLOCK_Port0); + + /* Enables the clock for PORT1: Enables clock */ + CLOCK_EnableClock(kCLOCK_Port1); + + + const port_pin_config_t port1_8_pinA1_config = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Low internal pull resistor value is selected. */ + kPORT_LowPullResistor, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive input filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain output is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as FC4_P0 */ + kPORT_MuxAlt2, + /* Digital input enabled */ + kPORT_InputBufferEnable, + /* Digital input is not inverted */ + kPORT_InputNormal, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORT1_8 (pin A1) is configured as FC4_P0 */ + PORT_SetPinConfig(PORT1, 8U, &port1_8_pinA1_config); + + const port_pin_config_t port1_9_pinB1_config = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Low internal pull resistor value is selected. */ + kPORT_LowPullResistor, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive input filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain output is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as FC4_P1 */ + kPORT_MuxAlt2, + /* Digital input enabled */ + kPORT_InputBufferEnable, + /* Digital input is not inverted */ + kPORT_InputNormal, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORT1_9 (pin B1) is configured as FC4_P1 */ + PORT_SetPinConfig(PORT1, 9U, &port1_9_pinB1_config); + + const port_pin_config_t SW2 = {/* Internal pull-up/down resistor is disabled */ + kPORT_PullDisable, + /* Low internal pull resistor value is selected. */ + kPORT_LowPullResistor, + /* Fast slew rate is configured */ + kPORT_FastSlewRate, + /* Passive input filter is disabled */ + kPORT_PassiveFilterDisable, + /* Open drain output is disabled */ + kPORT_OpenDrainDisable, + /* Low drive strength is configured */ + kPORT_LowDriveStrength, + /* Pin is configured as PIO0_23 */ + kPORT_MuxAlt0, + /* Digital input enabled */ + kPORT_InputBufferEnable, + /* Digital input is not inverted */ + kPORT_InputNormal, + /* Pin Control Register fields [15:0] are not locked */ + kPORT_UnlockRegister}; + /* PORT0_23 (pin B7) is configured as PIO0_23 */ + PORT_SetPinConfig(PORT0, 23U, &SW2); +} +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/mcx/boards/frdm_mcxn947/pin_mux.h b/hw/bsp/mcx/boards/frdm_mcxn947/pin_mux.h new file mode 100644 index 000000000..40968c275 --- /dev/null +++ b/hw/bsp/mcx/boards/frdm_mcxn947/pin_mux.h @@ -0,0 +1,51 @@ +/* + * Copyright 2022 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _PIN_MUX_H_ +#define _PIN_MUX_H_ + +/*! + * @addtogroup pin_mux + * @{ + */ + +/*********************************************************************************************************************** + * API + **********************************************************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Calls initialization functions. + * + */ +void BOARD_InitBootPins(void); + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitPins(void); + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif /* _PIN_MUX_H_ */ + +/*********************************************************************************************************************** + * EOF + **********************************************************************************************************************/ diff --git a/hw/bsp/mcx/boards/mcxn947brk/board.mk b/hw/bsp/mcx/boards/mcxn947brk/board.mk index aaad5e73e..22fefd79b 100644 --- a/hw/bsp/mcx/boards/mcxn947brk/board.mk +++ b/hw/bsp/mcx/boards/mcxn947brk/board.mk @@ -2,7 +2,10 @@ MCU_VARIANT = MCXN947 MCU_CORE = MCXN947_cm33_core0 PORT ?= 1 -CFLAGS += -DCPU_MCXN947VDF_cm33_core0 +CPU_CORE = cortex-m33 +CFLAGS += \ + -DCPU_MCXN947VDF_cm33_core0 \ + -DCFG_TUSB_MCU=OPT_MCU_MCXN9 \ JLINK_DEVICE = MCXN947_M33_0 PYOCD_TARGET = MCXN947 diff --git a/hw/bsp/mcx/family.c b/hw/bsp/mcx/family.c index 8672ca63f..cc675a49d 100644 --- a/hw/bsp/mcx/family.c +++ b/hw/bsp/mcx/family.c @@ -33,6 +33,10 @@ #include "pin_mux.h" #include "clock_config.h" +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ + #ifdef BOARD_TUD_RHPORT #define PORT_SUPPORT_DEVICE(_n) (BOARD_TUD_RHPORT == _n) #else @@ -45,44 +49,50 @@ #define PORT_SUPPORT_HOST(_n) 0 #endif -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM -//--------------------------------------------------------------------+ - //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ -void USB0_FS_IRQHandler(void) -{ + +#if CFG_TUSB_MCU == OPT_MCU_MCXN9 +void USB0_FS_IRQHandler(void) { tud_int_handler(0); } -void USB1_HS_IRQHandler(void) -{ +void USB1_HS_IRQHandler(void) { tud_int_handler(1); } -void board_init(void) -{ +#elif CFG_TUSB_MCU == OPT_MCU_MCXA15 + +void USB0_IRQHandler(void) { + tud_int_handler(0); +} + +#endif + + +void board_init(void) { BOARD_InitPins(); BOARD_InitBootClocks(); CLOCK_SetupExtClocking(XTAL0_CLK_HZ); +#if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); - -#if CFG_TUSB_OS == OPT_OS_FREERTOS +#elif CFG_TUSB_OS == OPT_OS_FREERTOS // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) - NVIC_SetPriority(USB1_HS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); + #if CFG_TUSB_MCU == OPT_MCU_MCXN9 + NVIC_SetPriority(USB0_FS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); + NVIC_SetPriority(USB1_HS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); + #else + NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); + #endif #endif // LED CLOCK_EnableClock(LED_CLK); - gpio_pin_config_t led_config = { - kGPIO_DigitalOutput, - 0, - }; - GPIO_PinInit(LED_GPIO,LED_PIN, &led_config); + gpio_pin_config_t led_config = {kGPIO_DigitalOutput, 0}; + GPIO_PinInit(LED_GPIO, LED_PIN, &led_config); board_led_write(0); #ifdef NEOPIXEL_PIN @@ -100,7 +110,7 @@ void board_init(void) // Button #ifdef BUTTON_GPIO CLOCK_EnableClock(BUTTON_CLK); - gpio_pin_config_t const button_config = { kGPIO_DigitalInput, 0}; + gpio_pin_config_t const button_config = {kGPIO_DigitalInput, 0}; GPIO_PinInit(BUTTON_GPIO, BUTTON_PIN, &button_config); #endif @@ -115,8 +125,8 @@ void board_init(void) lpuart_config_t uart_config; LPUART_GetDefaultConfig(&uart_config); uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE; - uart_config.enableTx = true; - uart_config.enableRx = true; + uart_config.enableTx = true; + uart_config.enableRx = true; LPUART_Init(UART_DEV, &uart_config, 12000000u); #endif @@ -126,13 +136,18 @@ void board_init(void) #if PORT_SUPPORT_DEVICE(0) // Port0 is Full Speed + #if CFG_TUSB_MCU == OPT_MCU_MCXA15 + RESET_PeripheralReset(kUSB0_RST_SHIFT_RSTn); + #elif CFG_TUSB_MCU == OPT_MCU_MCXN9 CLOCK_AttachClk(kCLK_48M_to_USB0); CLOCK_EnableClock(kCLOCK_Usb0Ram); CLOCK_EnableClock(kCLOCK_Usb0Fs); + #endif + CLOCK_EnableUsbfsClock(); #endif -#if PORT_SUPPORT_DEVICE(1) +#if PORT_SUPPORT_DEVICE(1) && (CFG_TUSB_MCU == OPT_MCU_MCXN9) // Port1 is High Speed // Power @@ -191,9 +206,8 @@ void board_init(void) // Board porting API //--------------------------------------------------------------------+ -void board_led_write(bool state) -{ - GPIO_PinWrite(LED_GPIO, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +void board_led_write(bool state) { + GPIO_PinWrite(LED_GPIO, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); #ifdef NEOPIXEL_PIN if (state) { @@ -207,23 +221,21 @@ void board_led_write(bool state) #endif } -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { #ifdef BUTTON_GPIO return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_GPIO, BUTTON_PIN); #endif } -int board_uart_read(uint8_t* buf, int len) -{ - (void) buf; (void) len; +int board_uart_read(uint8_t* buf, int 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) { #ifdef UART_DEV - LPUART_WriteBlocking(UART_DEV, (uint8_t const *) buf, len); + LPUART_WriteBlocking(UART_DEV, (uint8_t const*) buf, len); return len; #else (void) buf; (void) len; @@ -233,13 +245,13 @@ int board_uart_write(void const * buf, int len) #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; -void SysTick_Handler(void) -{ + +void SysTick_Handler(void) { system_ticks++; } -uint32_t board_millis(void) -{ +uint32_t board_millis(void) { return system_ticks; } + #endif diff --git a/hw/bsp/mcx/family.cmake b/hw/bsp/mcx/family.cmake index b3a4a846e..223afb9ec 100644 --- a/hw/bsp/mcx/family.cmake +++ b/hw/bsp/mcx/family.cmake @@ -1,9 +1,5 @@ include_guard() -if (NOT BOARD) - message(FATAL_ERROR "BOARD not specified") -endif () - set(SDK_DIR ${TOP}/hw/mcu/nxp/mcux-sdk) set(CMSIS_DIR ${TOP}/lib/CMSIS_5) @@ -11,60 +7,80 @@ set(CMSIS_DIR ${TOP}/lib/CMSIS_5) include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up -set(CMAKE_SYSTEM_PROCESSOR cortex-m33 CACHE INTERNAL "System Processor") -set(CMAKE_TOOLCHAIN_FILE ${TOP}/tools/cmake/toolchain/arm_${TOOLCHAIN}.cmake) - -set(FAMILY_MCUS MCXN9 CACHE INTERNAL "") +if (MCU_VARIANT STREQUAL "MCXA153") + set(CMAKE_SYSTEM_PROCESSOR cortex-m33-nodsp-nofp CACHE INTERNAL "System Processor") + set(FAMILY_MCUS MCXA15 CACHE INTERNAL "") +elseif (MCU_VARIANT STREQUAL "MCXN947") + set(CMAKE_SYSTEM_PROCESSOR cortex-m33 CACHE INTERNAL "System Processor") + set(FAMILY_MCUS MCXN9 CACHE INTERNAL "") +else() + message(FATAL_ERROR "MCU_VARIANT not supported") +endif() +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) #------------------------------------ # BOARD_TARGET #------------------------------------ # 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 - # external driver - #lib/sct_neopixel/sct_neopixel.c + if (TARGET ${BOARD_TARGET}) + return() + endif() - # driver - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_gpio.c - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_common_arm.c - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_lpuart.c + if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_CORE}_flash.ld) + endif () + set(LD_FILE_Clang ${LD_FILE_GNU}) + + if (NOT DEFINED STARTUP_FILE_GNU) + set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_CORE}.S) + endif() + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + # driver + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_gpio.c + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_common_arm.c + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_lpuart.c + # mcu + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_reset.c + ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_CORE}.c + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMSIS_DIR}/CMSIS/Core/Include + ${SDK_DIR}/devices/${MCU_VARIANT} + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers + ) + + if (${FAMILY_MCUS} STREQUAL "MCXN9") + target_sources(${BOARD_TARGET} PRIVATE ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_lpflexcomm.c - # mcu - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_reset.c - ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_CORE}.c - ) - # target_compile_definitions(${BOARD_TARGET} PUBLIC - # ) - target_include_directories(${BOARD_TARGET} PUBLIC - # driver - # mcu - ${CMSIS_DIR}/CMSIS/Core/Include - ${SDK_DIR}/devices/${MCU_VARIANT} - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers - ) + ) + elseif(${FAMILY_MCUS} STREQUAL "MCXA15") + target_sources(${BOARD_TARGET} PRIVATE + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_spc.c + ) + endif() - update_board(${BOARD_TARGET}) + update_board(${BOARD_TARGET}) - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_sources(${BOARD_TARGET} PUBLIC - ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_CORE}.S - ) - target_link_options(${BOARD_TARGET} PUBLIC - # linker file - "LINKER:--script=${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_CORE}_flash.ld" - # 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 () + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + --specs=nosys.specs --specs=nano.specs + #-nostartfiles + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) endif () endfunction() @@ -93,7 +109,12 @@ function(family_configure_example TARGET RTOS) ) # Add TinyUSB target and port source - family_add_tinyusb(${TARGET} OPT_MCU_MCXN9 ${RTOS}) + if (${FAMILY_MCUS} STREQUAL "MCXN9") + family_add_tinyusb(${TARGET} OPT_MCU_MCXN9 ${RTOS}) + elseif(${FAMILY_MCUS} STREQUAL "MCXA15") + family_add_tinyusb(${TARGET} OPT_MCU_MCXA15 ${RTOS}) + endif() + target_sources(${TARGET}-tinyusb PUBLIC # TinyUSB: Port0 is chipidea FS, Port1 is chipidea HS ${TOP}/src/portable/chipidea/$ diff --git a/hw/bsp/mcx/family.mk b/hw/bsp/mcx/family.mk index e384aa8eb..58149fb8d 100644 --- a/hw/bsp/mcx/family.mk +++ b/hw/bsp/mcx/family.mk @@ -4,19 +4,19 @@ SDK_DIR = hw/mcu/nxp/mcux-sdk DEPS_SUBMODULES += $(SDK_DIR) lib/CMSIS_5 include $(TOP)/$(BOARD_PATH)/board.mk -CPU_CORE ?= cortex-m33 # Default to Highspeed PORT1 PORT ?= 1 CFLAGS += \ -flto \ - -DCFG_TUSB_MCU=OPT_MCU_MCXN9 \ -DBOARD_TUD_RHPORT=$(PORT) \ # mcu driver cause following warnings CFLAGS += -Wno-error=unused-parameter -Wno-error=old-style-declaration +LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs + # All source paths should be relative to the top level. LD_FILE ?= $(SDK_DIR)/devices/$(MCU_VARIANT)/gcc/$(MCU_CORE)_flash.ld @@ -36,9 +36,18 @@ SRC_C += \ $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_clock.c \ $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_reset.c \ $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_gpio.c \ - $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_common_arm.c \ - $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_lpflexcomm.c \ $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_lpuart.c \ + $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_common_arm.c \ + +# fsl_lpflexcomm for MCXN9 +ifeq ($(MCU_VARIANT), MCXN947) + SRC_C += $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_lpflexcomm.c +endif + +# fsl_spc for MCXNA15 +ifeq ($(MCU_VARIANT), MCXA153) + SRC_C += $(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_spc.c +endif INC += \ $(TOP)/$(BOARD_PATH) \ diff --git a/hw/bsp/mm32/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/mm32/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..6622cf801 --- /dev/null +++ b/hw/bsp/mm32/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,150 @@ +/* + * 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 "mm32_device.h" + extern u32 SystemCoreClock; +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#define configENABLE_FPU 0 +#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 4 +#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 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* 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 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* 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 + +/* 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 4 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<CFGR &= ~(0x3 << 22); - RCC->CFGR |= (0x1 << 22); - - /* Enable USB clock */ - RCC->AHB2ENR |= 0x1 << 7; -} -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM DECLARATION -//--------------------------------------------------------------------+ -// LED - -extern u32 SystemCoreClock; -const int baudrate = 115200; - -void board_init (void) -{ -// usb clock - USB_DeviceClockInit(); - - if ( SysTick_Config(SystemCoreClock / 1000) ) - { - while ( 1 ) - ; - } - NVIC_SetPriority(SysTick_IRQn, 0x0); - - // LED on PB2 - GPIO_InitTypeDef GPIO_InitStruct; - RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOB, ENABLE); - GPIO_StructInit(&GPIO_InitStruct); - - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2; - GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; - GPIO_Init(GPIOB, &GPIO_InitStruct); - - board_led_write(true); - - // KEY on PA0 - RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE); - GPIO_StructInit(&GPIO_InitStruct); - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; - GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD; - GPIO_Init(GPIOA, &GPIO_InitStruct); - - // UART - UART_InitTypeDef UART_InitStruct; - - RCC_APB2PeriphClockCmd(RCC_APB2ENR_UART1, ENABLE); //enableUART1,GPIOAclock - RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE); // - //UART initialset - - GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_7); - GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_7); - - UART_StructInit(&UART_InitStruct); - UART_InitStruct.UART_BaudRate = baudrate; - UART_InitStruct.UART_WordLength = UART_WordLength_8b; - UART_InitStruct.UART_StopBits = UART_StopBits_1; //one stopbit - UART_InitStruct.UART_Parity = UART_Parity_No; //none odd-even verify bit - UART_InitStruct.UART_HardwareFlowControl = UART_HardwareFlowControl_None; //No hardware flow control - UART_InitStruct.UART_Mode = UART_Mode_Rx | UART_Mode_Tx; // receive and sent mode - - UART_Init(UART1, &UART_InitStruct); //initial uart 1 - UART_Cmd(UART1, ENABLE); //enable uart 1 - - //UART1_TX GPIOA.9 - GPIO_StructInit(&GPIO_InitStruct); - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; - GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; - GPIO_Init(GPIOA, &GPIO_InitStruct); - - //UART1_RX GPIOA.10 - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; - GPIO_Init(GPIOA, &GPIO_InitStruct); - -} - - -//--------------------------------------------------------------------+ -// Board porting API -//--------------------------------------------------------------------+ - -void board_led_write (bool state) -{ - state ? (GPIO_ResetBits(GPIOB, GPIO_Pin_2)) : (GPIO_SetBits(GPIOB, GPIO_Pin_2)); -} - -uint32_t board_button_read (void) -{ - uint32_t key = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == Bit_SET; - return key; -} - -int board_uart_read (uint8_t *buf, int len) -{ - (void) buf; - (void) len; - return 0; -} - -int board_uart_write (void const *buf, int len) -{ - const char *buff = buf; - while ( len ) - { - while ( (UART1->CSR & UART_IT_TXIEN) == 0 ) - ; //The loop is sent until it is finished - UART1->TDR = (*buff & 0xFF); - buff++; - len--; - } - return len; -} - -#if CFG_TUSB_OS == OPT_OS_NONE -volatile uint32_t system_ticks = 0; -void SysTick_Handler (void) -{ - system_ticks++; -} - -uint32_t board_millis (void) -{ - return system_ticks; -} -#endif - -// Required by __libc_init_array in startup code if we are compiling using -// -nostdlib/-nostartfiles. -void _init(void) -{ - -} diff --git a/hw/bsp/mm32/boards/mm32f327x_mb39/board.cmake b/hw/bsp/mm32/boards/mm32f327x_mb39/board.cmake new file mode 100644 index 000000000..4f3d145cf --- /dev/null +++ b/hw/bsp/mm32/boards/mm32f327x_mb39/board.cmake @@ -0,0 +1,10 @@ +set(MCU_VARIANT mm32f327x) +set(JLINK_DEVICE MM32F3273G9P) + +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/flash.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + HSE_VALUE=8000000 + ) +endfunction() diff --git a/hw/bsp/mm32/boards/mm32f327x_mb39/board.h b/hw/bsp/mm32/boards/mm32f327x_mb39/board.h new file mode 100644 index 000000000..3ac048cf1 --- /dev/null +++ b/hw/bsp/mm32/boards/mm32f327x_mb39/board.h @@ -0,0 +1,19 @@ +#ifndef BOARD_H +#define BOARD_H + +// GPIO_PinAFConfig(GPIOA, GPIO_PinSource15, GPIO_AF_15); //Disable JTDI AF to AF15 +#define LED_PORT GPIOA +#define LED_PIN GPIO_Pin_15 +#define LED_STATE_ON 1 + +//#define BUTTON_PORT GPIOC +//#define BUTTON_PIN GPIO_PIN_13 +//#define BUTTON_STATE_ACTIVE 1 + +#define UART_DEV UART1 +#define UART_GPIO_PORT GPIOA +#define UART_GPIO_AF GPIO_AF_7 +#define UART_TX_PIN 9 +#define UART_RX_PIN 10 + +#endif diff --git a/hw/bsp/mm32/boards/mm32f327x_mb39/board.mk b/hw/bsp/mm32/boards/mm32f327x_mb39/board.mk index a0d92d1c7..f6d18315d 100644 --- a/hw/bsp/mm32/boards/mm32f327x_mb39/board.mk +++ b/hw/bsp/mm32/boards/mm32f327x_mb39/board.mk @@ -1,12 +1,9 @@ +MCU_VARIANT = mm32f327x CFLAGS += \ -DHSE_VALUE=8000000 +JLINK_DEVICE = MM32F3273G9P + LD_FILE = $(BOARD_PATH)/flash.ld -SRC_S += $(SDK_DIR)/mm32f327x/MM32F327x/Source/GCC_StartAsm/startup_mm32m3ux_u_gcc.S - -# For flash-jlink target -#JLINK_DEVICE = stm32f411ve - -# flash target using on-board stlink -#flash: flash-jlink +flash: flash-jlink diff --git a/hw/bsp/mm32/boards/mm32f327x_mb39/mm32f327x_mb39.c b/hw/bsp/mm32/boards/mm32f327x_mb39/mm32f327x_mb39.c deleted file mode 100644 index 086532179..000000000 --- a/hw/bsp/mm32/boards/mm32f327x_mb39/mm32f327x_mb39.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 MM32 SE TEAM - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#include "mm32_device.h" -#include "hal_conf.h" -#include "tusb.h" -#include "bsp/board_api.h" - -//--------------------------------------------------------------------+ -// Forward USB interrupt events to TinyUSB IRQ Handler -//--------------------------------------------------------------------+ -void OTG_FS_IRQHandler (void) -{ - tud_int_handler(0); - -} -void USB_DeviceClockInit (void) -{ - /* Select USBCLK source */ - // RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div1); - RCC->CFGR &= ~(0x3 << 22); - RCC->CFGR |= (0x1 << 22); - - /* Enable USB clock */ - RCC->AHB2ENR |= 0x1 << 7; -} -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM DECLARATION -//--------------------------------------------------------------------+ -// LED - -extern u32 SystemCoreClock; -const int baudrate = 115200; - -void board_init (void) -{ -// usb clock - USB_DeviceClockInit(); - - if ( SysTick_Config(SystemCoreClock / 1000) ) - { - while ( 1 ) - ; - } - NVIC_SetPriority(SysTick_IRQn, 0x0); - - // LED - GPIO_InitTypeDef GPIO_InitStruct; - RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE); - GPIO_StructInit(&GPIO_InitStruct); - GPIO_PinAFConfig(GPIOA, GPIO_PinSource15, GPIO_AF_15); //Disable JTDI AF to AF15 - - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15; - GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; - GPIO_Init(GPIOA, &GPIO_InitStruct); - - board_led_write(true); - - // UART - UART_InitTypeDef UART_InitStruct; - - RCC_APB2PeriphClockCmd(RCC_APB2ENR_UART1, ENABLE); //enableUART1,GPIOAclock - RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE); // - //UART initialset - - GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_7); - GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_7); - - UART_StructInit(&UART_InitStruct); - UART_InitStruct.UART_BaudRate = baudrate; - UART_InitStruct.UART_WordLength = UART_WordLength_8b; - UART_InitStruct.UART_StopBits = UART_StopBits_1; //one stopbit - UART_InitStruct.UART_Parity = UART_Parity_No; //none odd-even verify bit - UART_InitStruct.UART_HardwareFlowControl = UART_HardwareFlowControl_None; //No hardware flow control - UART_InitStruct.UART_Mode = UART_Mode_Rx | UART_Mode_Tx; // receive and sent mode - - UART_Init(UART1, &UART_InitStruct); //initial uart 1 - UART_Cmd(UART1, ENABLE); //enable uart 1 - - //UART1_TX GPIOA.9 - GPIO_StructInit(&GPIO_InitStruct); - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; - GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; - GPIO_Init(GPIOA, &GPIO_InitStruct); - - //UART1_RX GPIOA.10 - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; - GPIO_Init(GPIOA, &GPIO_InitStruct); - -} - -//--------------------------------------------------------------------+ -// Board porting API -//--------------------------------------------------------------------+ - -void board_led_write (bool state) -{ - state ? (GPIO_ResetBits(GPIOA, GPIO_Pin_15)) : (GPIO_SetBits(GPIOA, GPIO_Pin_15)); -} - -uint32_t board_button_read (void) -{ - return 0; -} - -int board_uart_read (uint8_t *buf, int len) -{ - (void) buf; - (void) len; - return 0; -} - -int board_uart_write (void const *buf, int len) -{ - const char *buff = buf; - while ( len ) - { - while ( (UART1->CSR & UART_IT_TXIEN) == 0 ) - ; //The loop is sent until it is finished - UART1->TDR = (*buff & 0xFF); - buff++; - len--; - } - return len; -} - -#if CFG_TUSB_OS == OPT_OS_NONE -volatile uint32_t system_ticks = 0; -void SysTick_Handler (void) -{ - system_ticks++; -} - -uint32_t board_millis (void) -{ - return system_ticks; -} -#endif - -// Required by __libc_init_array in startup code if we are compiling using -// -nostdlib/-nostartfiles. -void _init(void) -{ - -} diff --git a/hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.cmake b/hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.cmake new file mode 100644 index 000000000..4de25e2c4 --- /dev/null +++ b/hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.cmake @@ -0,0 +1,10 @@ +set(MCU_VARIANT mm32f327x) +set(JLINK_DEVICE MM32F3273G8P) + +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/flash.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + HSE_VALUE=12000000 + ) +endfunction() diff --git a/hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.h b/hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.h new file mode 100644 index 000000000..2b3f54a60 --- /dev/null +++ b/hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.h @@ -0,0 +1,14 @@ +#ifndef BOARD_H +#define BOARD_H + +// GPIO_PinAFConfig(GPIOA, GPIO_PinSource15, GPIO_AF_15); //Disable JTDI AF to AF15 +#define LED_PORT GPIOA +#define LED_PIN GPIO_Pin_1 +#define LED_STATE_ON 1 + +#define BUTTON_PORT GPIOA +#define BUTTON_PIN GPIO_Pin_0 +#define BUTTON_STATE_ACTIVE 0 + + +#endif diff --git a/hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.mk b/hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.mk index a778e749f..dbcd314c8 100644 --- a/hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.mk +++ b/hw/bsp/mm32/boards/mm32f327x_pitaya_lite/board.mk @@ -1,11 +1,12 @@ +MCU_VARIANT = mm32f327x + CFLAGS += \ -DHSE_VALUE=12000000 LD_FILE = $(BOARD_PATH)/flash.ld -SRC_S += $(SDK_DIR)/mm32f327x/MM32F327x/Source/GCC_StartAsm/startup_mm32m3ux_u_gcc.S # For flash-jlink target -#JLINK_DEVICE = MM32F3273G8P +JLINK_DEVICE = MM32F3273G8P # flash target using on-board stlink #flash: flash-jlink diff --git a/hw/bsp/mm32/boards/mm32f327x_pitaya_lite/mm32f327x_pitaya_lite.c b/hw/bsp/mm32/family.c similarity index 61% rename from hw/bsp/mm32/boards/mm32f327x_pitaya_lite/mm32f327x_pitaya_lite.c rename to hw/bsp/mm32/family.c index bd2d36ae0..f0fd6d334 100644 --- a/hw/bsp/mm32/boards/mm32f327x_pitaya_lite/mm32f327x_pitaya_lite.c +++ b/hw/bsp/mm32/family.c @@ -24,23 +24,35 @@ * This file is part of the TinyUSB stack. */ -/* DshanMCU Pitaya Lite with MM32F3273 */ - -#include "mm32_device.h" #include "hal_conf.h" -#include "tusb.h" +#include "mm32_device.h" + #include "bsp/board_api.h" +#include "board.h" + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ + +#ifdef __GNUC__ // caused by extra declaration of SystemCoreClock in freeRTOSConfig.h +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wredundant-decls" +#endif + +extern u32 SystemCoreClock; + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ -void OTG_FS_IRQHandler (void) -{ +void OTG_FS_IRQHandler(void) { tud_int_handler(0); - } -void USB_DeviceClockInit (void) -{ + +void USB_DeviceClockInit(void) { /* Select USBCLK source */ // RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div1); RCC->CFGR &= ~(0x3 << 22); @@ -49,134 +61,117 @@ void USB_DeviceClockInit (void) /* Enable USB clock */ RCC->AHB2ENR |= 0x1 << 7; } -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM DECLARATION -//--------------------------------------------------------------------+ -// LED -extern u32 SystemCoreClock; -const int baudrate = 115200; - -void board_init (void) -{ +void board_init(void) { // usb clock -// requires SYSCLK_FREQ_XXMHz (HSE_VALUE*8) in system_mm32f327x.c USB_DeviceClockInit(); - if ( SysTick_Config(SystemCoreClock / 1000) ) - { - while ( 1 ) - ; - } + SysTick_Config(SystemCoreClock / 1000); NVIC_SetPriority(SysTick_IRQn, 0x0); - // LED on PA1 - GPIO_InitTypeDef GPIO_InitStruct; RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE); - GPIO_StructInit(&GPIO_InitStruct); - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1; + // LED + GPIO_InitTypeDef GPIO_InitStruct; + GPIO_StructInit(&GPIO_InitStruct); + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStruct); board_led_write(true); - // KEY on PA0 + #ifdef BUTTON_PORT GPIO_StructInit(&GPIO_InitStruct); - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; + GPIO_InitStruct.GPIO_Pin = BUTTON_PIN; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_FLOATING; - GPIO_Init(GPIOA, &GPIO_InitStruct); + GPIO_InitStruct.GPIO_Mode = BUTTON_STATE_ACTIVE ? GPIO_Mode_IPD : GPIO_Mode_IPU; + GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); + #endif + #ifdef UART_DEV // UART UART_InitTypeDef UART_InitStruct; - RCC_APB2PeriphClockCmd(RCC_APB2ENR_UART1, ENABLE); //enableUART1,GPIOAclock - RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE); // - //UART initialset - - GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_7); - GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_7); + RCC_APB2PeriphClockCmd(RCC_APB2ENR_UART1, ENABLE); //enableUART1,GPIOAclock + GPIO_PinAFConfig(GPIOA, UART_TX_PIN, UART_GPIO_AF); + GPIO_PinAFConfig(GPIOA, UART_RX_PIN, UART_GPIO_AF); UART_StructInit(&UART_InitStruct); - UART_InitStruct.UART_BaudRate = baudrate; + UART_InitStruct.UART_BaudRate = CFG_BOARD_UART_BAUDRATE; UART_InitStruct.UART_WordLength = UART_WordLength_8b; - UART_InitStruct.UART_StopBits = UART_StopBits_1; //one stopbit - UART_InitStruct.UART_Parity = UART_Parity_No; //none odd-even verify bit - UART_InitStruct.UART_HardwareFlowControl = UART_HardwareFlowControl_None; //No hardware flow control - UART_InitStruct.UART_Mode = UART_Mode_Rx | UART_Mode_Tx; // receive and sent mode + UART_InitStruct.UART_StopBits = UART_StopBits_1; + UART_InitStruct.UART_Parity = UART_Parity_No; + UART_InitStruct.UART_HardwareFlowControl = UART_HardwareFlowControl_None; + UART_InitStruct.UART_Mode = UART_Mode_Rx | UART_Mode_Tx; - UART_Init(UART1, &UART_InitStruct); //initial uart 1 - UART_Cmd(UART1, ENABLE); //enable uart 1 + UART_Init(UART_DEV, &UART_InitStruct); + UART_Cmd(UART_DEV, ENABLE); - //UART1_TX GPIOA.9 GPIO_StructInit(&GPIO_InitStruct); - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; + GPIO_InitStruct.GPIO_Pin = 1 << UART_TX_PIN; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; - GPIO_Init(GPIOA, &GPIO_InitStruct); + GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); - //UART1_RX GPIOA.10 - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5; + GPIO_InitStruct.GPIO_Pin = 1 << UART_RX_PIN; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; - GPIO_Init(GPIOA, &GPIO_InitStruct); - + GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); + #endif } - //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ -void board_led_write (bool state) -{ - state ? (GPIO_ResetBits(GPIOA, GPIO_Pin_1)) : (GPIO_SetBits(GPIOA, GPIO_Pin_1)); +void board_led_write(bool state) { + GPIO_WriteBit(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } -uint32_t board_button_read (void) -{ - uint32_t key = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == Bit_RESET; - return key; +uint32_t board_button_read(void) { +#ifdef BUTTON_PORT + return GPIO_ReadInputDataBit(BUTTON_PORT, BUTTON_PIN) == BUTTON_STATE_ACTIVE; +#else + return 0; +#endif } -int board_uart_read (uint8_t *buf, int len) -{ +int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } -int board_uart_write (void const *buf, int len) -{ - const char *buff = buf; - while ( len ) - { - while ( (UART1->CSR & UART_IT_TXIEN) == 0 ) - ; //The loop is sent until it is finished +int board_uart_write(void const* buf, int len) { + #ifdef UART_DEV + const char* buff = buf; + while (len) { + while ((UART1->CSR & UART_IT_TXIEN) == 0); //The loop is sent until it is finished UART1->TDR = (*buff & 0xFF); buff++; len--; } return len; + #else + (void) buf; + (void) len; + return 0; + #endif } #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 // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. -void _init(void) -{ - +void _init(void) { } diff --git a/hw/bsp/mm32/family.cmake b/hw/bsp/mm32/family.cmake new file mode 100644 index 000000000..bf315acaa --- /dev/null +++ b/hw/bsp/mm32/family.cmake @@ -0,0 +1,101 @@ +include_guard() + +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +string(REPLACE "mm32f" "MM32F" MCU_VARIANT_UPPER ${MCU_VARIANT}) +set(SDK_DIR ${TOP}/hw/mcu/mindmotion/mm32sdk/${MCU_VARIANT_UPPER}) +set(CMSIS_5 ${TOP}/lib/CMSIS_5) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR cortex-m3 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS MM32F327X 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() + + # Startup & Linker script + set(STARTUP_FILE_GNU ${SDK_DIR}/Source/GCC_StartAsm/startup_${MCU_VARIANT}_gcc.s) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + set(STARTUP_FILE_IAR ${SDK_DIR}/Source/IAR_StartAsm/startup_${MCU_VARIANT}_iar.s) + + set(LD_FILE_Clang ${LD_FILE_GNU}) + # set(LD_FILE_IAR ) + + add_library(${BOARD_TARGET} STATIC + ${SDK_DIR}/Source/system_${MCU_VARIANT}.c + ${SDK_DIR}/HAL_Lib/Src/hal_gpio.c + ${SDK_DIR}/HAL_Lib/Src/hal_rcc.c + ${SDK_DIR}/HAL_Lib/Src/hal_uart.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMSIS_5}/CMSIS/Core/Include + ${SDK_DIR}/Include + ${SDK_DIR}/HAL_Lib/Inc + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + 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_MM32F327X ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.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}) +endfunction() diff --git a/hw/bsp/mm32/family.mk b/hw/bsp/mm32/family.mk index d5b6e315a..a790663ab 100644 --- a/hw/bsp/mm32/family.mk +++ b/hw/bsp/mm32/family.mk @@ -1,30 +1,33 @@ UF2_FAMILY_ID = 0x0 -SDK_DIR = hw/mcu/mindmotion/mm32sdk -DEPS_SUBMODULES += lib/CMSIS_5 $(SDK_DIR) - include $(TOP)/$(BOARD_PATH)/board.mk + +MCU_VARIANT_UPPER = $(subst mm32f,MM32F,${MCU_VARIANT}) +SDK_DIR = hw/mcu/mindmotion/mm32sdk/${MCU_VARIANT_UPPER} + CPU_CORE ?= cortex-m3 CFLAGS += \ -flto \ - -nostdlib -nostartfiles \ - -DCFG_TUSB_MCU=OPT_MCU_MM32F327X + -DCFG_TUSB_MCU=OPT_MCU_MM32F327X \ # suppress warning caused by vendor mcu driver CFLAGS += -Wno-error=unused-parameter -Wno-error=maybe-uninitialized -Wno-error=cast-qual +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + -specs=nosys.specs -specs=nano.specs \ + SRC_C += \ src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c \ - $(SDK_DIR)/mm32f327x/MM32F327x/Source/system_mm32f327x.c \ - $(SDK_DIR)/mm32f327x/MM32F327x/HAL_Lib/Src/hal_gpio.c \ - $(SDK_DIR)/mm32f327x/MM32F327x/HAL_Lib/Src/hal_rcc.c \ - $(SDK_DIR)/mm32f327x/MM32F327x/HAL_Lib/Src/hal_uart.c \ + $(SDK_DIR)/Source/system_${MCU_VARIANT}.c \ + $(SDK_DIR)/HAL_Lib/Src/hal_gpio.c \ + $(SDK_DIR)/HAL_Lib/Src/hal_rcc.c \ + $(SDK_DIR)/HAL_Lib/Src/hal_uart.c \ + +SRC_S += ${SDK_DIR}/Source/GCC_StartAsm/startup_${MCU_VARIANT}_gcc.s INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ - $(TOP)/$(SDK_DIR)/mm32f327x/MM32F327x/Include \ - $(TOP)/$(SDK_DIR)/mm32f327x/MM32F327x/HAL_Lib/Inc - -# flash target using on-board -flash: flash-jlink + $(TOP)/$(SDK_DIR)/Include \ + $(TOP)/$(SDK_DIR)/HAL_Lib/Inc diff --git a/hw/bsp/msp430/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/msp430/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..4049fba65 --- /dev/null +++ b/hw/bsp/msp430/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,80 @@ +/* + * 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 "msp430.h" +#endif + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 +#define configCPU_CLOCK_HZ ( ( unsigned long ) 7995392 ) /* Clock setup from main.c in the demo application. */ +#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) +#define configMAX_PRIORITIES ( 4 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 50 ) +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 1700 ) ) +#define configMAX_TASK_NAME_LEN ( 8 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 1 +#define configIDLE_SHOULD_YIELD 1 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ + +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 + +#endif /* FREERTOS_CONFIG_H */ diff --git a/hw/bsp/msp430/boards/msp_exp430f5529lp/board.cmake b/hw/bsp/msp430/boards/msp_exp430f5529lp/board.cmake new file mode 100644 index 000000000..59f591263 --- /dev/null +++ b/hw/bsp/msp430/boards/msp_exp430f5529lp/board.cmake @@ -0,0 +1,9 @@ +set(MCU_VARIANT msp430f5529) +set(LD_FILE_GNU ${SDK_DIR}/msp430f5529.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} INTERFACE + __MSP430F5529__ + ) + +endfunction() diff --git a/hw/bsp/msp430/boards/msp_exp430f5529lp/board.mk b/hw/bsp/msp430/boards/msp_exp430f5529lp/board.mk new file mode 100644 index 000000000..b45c62e83 --- /dev/null +++ b/hw/bsp/msp430/boards/msp_exp430f5529lp/board.mk @@ -0,0 +1,4 @@ +CFLAGS += \ + -D__MSP430F5529__ \ + +LD_FILE = ${SDK_DIR}/msp430f5529.ld diff --git a/hw/bsp/msp430/family.cmake b/hw/bsp/msp430/family.cmake new file mode 100644 index 000000000..e0b4ed28a --- /dev/null +++ b/hw/bsp/msp430/family.cmake @@ -0,0 +1,84 @@ +include_guard() + +set(SDK_DIR ${TOP}/hw/mcu/ti/msp430/msp430-gcc-support-files/include) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR msp430 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/msp430_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS MSP430x5xx CACHE INTERNAL "") + + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (NOT TARGET ${BOARD_TARGET}) + add_library(${BOARD_TARGET} INTERFACE) + target_compile_definitions(${BOARD_TARGET} INTERFACE + CFG_TUD_ENDPOINT0_SIZE=8 + CFG_EXAMPLE_VIDEO_READONLY + CFG_EXAMPLE_MSC_READONLY + ) + target_include_directories(${BOARD_TARGET} INTERFACE + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${SDK_DIR} + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} INTERFACE + "LINKER:--script=${LD_FILE_GNU}" + -L${SDK_DIR} + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} INTERFACE + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () + 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_MSP430x5xx ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_add_bin_hex(${TARGET}) + family_flash_msp430flasher(${TARGET}) +endfunction() diff --git a/hw/bsp/msp430/family.mk b/hw/bsp/msp430/family.mk index ceafa6ec1..06508ab2c 100644 --- a/hw/bsp/msp430/family.mk +++ b/hw/bsp/msp430/family.mk @@ -2,21 +2,21 @@ CROSS_COMPILE = msp430-elf- DEPS_SUBMODULES += hw/mcu/ti SKIP_NANOLIB = 1 +SDK_DIR = hw/mcu/ti/msp430/msp430-gcc-support-files/include + +include $(TOP)/$(BOARD_PATH)/board.mk + CFLAGS += \ - -D__MSP430F5529__ \ -DCFG_TUSB_MCU=OPT_MCU_MSP430x5xx \ -DCFG_EXAMPLE_MSC_READONLY \ -DCFG_TUD_ENDPOINT0_SIZE=8 -# All source paths should be relative to the top level. -LD_FILE = hw/mcu/ti/msp430/msp430-gcc-support-files/include/msp430f5529.ld -LDINC += $(TOP)/hw/mcu/ti/msp430/msp430-gcc-support-files/include -LDFLAGS += $(addprefix -L,$(LDINC)) +LDFLAGS += -L${TOP}/${SDK_DIR} SRC_C += src/portable/ti/msp430x5xx/dcd_msp430x5xx.c INC += \ - $(TOP)/hw/mcu/ti/msp430/msp430-gcc-support-files/include \ + ${TOP}/${SDK_DIR} \ $(TOP)/$(BOARD_PATH) # export for libmsp430.so to same installation diff --git a/hw/bsp/msp432e4/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/msp432e4/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..3dd5a1ee1 --- /dev/null +++ b/hw/bsp/msp432e4/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,149 @@ +/* + * 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 "msp.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 4 +#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 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* 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 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* 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 + +/* 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 3 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<CTRL |= SPIFI_CTRL_FBCLK(1); // and set FBCLK in SPIFI controller - - Chip_SetupCoreClock(CLKIN_CRYSTAL, MAX_CLOCK_FREQ, true); - - /* Reset and enable 32Khz oscillator */ - LPC_CREG->CREG0 &= ~((1 << 3) | (1 << 2)); - LPC_CREG->CREG0 |= (1 << 1) | (1 << 0); - - /* Setup a divider E for main PLL clock switch SPIFI clock to that divider. - Divide rate is based on CPU speed and speed of SPI FLASH part. */ -#if (MAX_CLOCK_FREQ > 180000000) - Chip_Clock_SetDivider(CLK_IDIV_E, CLKIN_MAINPLL, 5); -#else - Chip_Clock_SetDivider(CLK_IDIV_E, CLKIN_MAINPLL, 4); -#endif - Chip_Clock_SetBaseClock(CLK_BASE_SPIFI, CLKIN_IDIVE, true, false); - - /* Setup system base clocks and initial states. This won't enable and - disable individual clocks, but sets up the base clock sources for - each individual peripheral clock. */ - Chip_Clock_SetBaseClock(CLK_BASE_USB1, CLKIN_IDIVD, true, true); -} - -void board_init(void) -{ - SystemCoreClockUpdate(); - -#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(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); -#endif - - Chip_GPIO_Init(LPC_GPIO_PORT); - - // LED - Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, LED_PORT, LED_PIN); - - // Button - Chip_GPIO_SetPinDIRInput(LPC_GPIO_PORT, BUTTON_PORT, BUTTON_PIN); - -#if 0 - //------------- UART -------------// - scu_pinmux(BOARD_UART_PIN_PORT, BOARD_UART_PIN_TX, MD_PDN, FUNC1); - scu_pinmux(BOARD_UART_PIN_PORT, BOARD_UART_PIN_RX, MD_PLN | MD_EZI | MD_ZI, FUNC1); - - UART_CFG_Type UARTConfigStruct; - UART_ConfigStructInit(&UARTConfigStruct); - UARTConfigStruct.Baud_rate = CFG_BOARD_UART_BAUDRATE; - UARTConfigStruct.Clock_Speed = 0; - - UART_Init(BOARD_UART_PORT, &UARTConfigStruct); - UART_TxCmd(BOARD_UART_PORT, ENABLE); // Enable UART Transmit -#endif - - //------------- USB -------------// - enum { - USBMODE_DEVICE = 2, - USBMODE_HOST = 3 - }; - - enum { - USBMODE_VBUS_LOW = 0, - USBMODE_VBUS_HIGH = 1 - }; - - /* USB0 - * For USB Device operation; insert jumpers in position 1-2 in JP17/JP18/JP19. GPIO28 controls USB - * connect functionality and LED32 lights when the USB Device is connected. SJ4 has pads 1-2 shorted - * by default. LED33 is controlled by GPIO27 and signals USB-up state. GPIO54 is used for VBUS - * sensing. - * For USB Host operation; insert jumpers in position 2-3 in JP17/JP18/JP19. USB Host power is - * controlled via distribution switch U20 (found in schematic page 11). Signal GPIO26 is active low and - * enables +5V on VBUS2. LED35 light whenever +5V is present on VBUS2. GPIO55 is connected to - * status feedback from the distribution switch. GPIO54 is used for VBUS sensing. 15Kohm pull-down - * resistors are always active - */ - Chip_USB0_Init(); - - /* USB1 - * When USB channel #1 is used as USB Host, 15Kohm pull-down resistors are needed on the USB data - * signals. These are activated inside the USB OTG chip (U31), and this has to be done via the I2C - * interface of GPIO52/GPIO53. - * J20 is the connector to use when USB Host is used. In order to provide +5V to the external USB - * device connected to this connector (J20), channel A of U20 must be enabled. It is enabled by default - * since SJ5 is normally connected between pin 1-2. LED34 lights green when +5V is available on J20. - * JP15 shall not be inserted. JP16 has no effect - * - * When USB channel #1 is used as USB Device, a 1.5Kohm pull-up resistor is needed on the USB DP - * data signal. There are two methods to create this. JP15 is inserted and the pull-up resistor is always - * enabled. Alternatively, the pull-up resistor is activated inside the USB OTG chip (U31), and this has to - * be done via the I2C interface of GPIO52/GPIO53. In the latter case, JP15 shall not be inserted. - * J19 is the connector to use when USB Device is used. Normally it should be a USB-B connector for - * creating a USB Device interface, but the mini-AB connector can also be used in this case. The status - * of VBUS can be read via U31. - * JP16 shall not be inserted. - */ - Chip_USB1_Init(); -// Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, 5, 6); /* GPIO5[6] = USB1_PWR_EN */ -// Chip_GPIO_SetPinState(LPC_GPIO_PORT, 5, 6, true); /* GPIO5[6] output high */ -} - -//--------------------------------------------------------------------+ -// USB Interrupt Handler -//--------------------------------------------------------------------+ -void USB0_IRQHandler(void) -{ - #if PORT_SUPPORT_DEVICE(0) - tud_int_handler(0); - #endif - - #if PORT_SUPPORT_HOST(0) - tuh_int_handler(0); - #endif -} - -void USB1_IRQHandler(void) -{ - #if PORT_SUPPORT_DEVICE(1) - tud_int_handler(1); - #endif - - #if PORT_SUPPORT_HOST(1) - tuh_int_handler(1); - #endif -} - -//--------------------------------------------------------------------+ -// Board porting API -//--------------------------------------------------------------------+ - -void board_led_write(bool state) -{ - Chip_GPIO_SetPinState(LPC_GPIO_PORT, LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); -} - -uint32_t board_button_read(void) -{ - return BUTTON_STATE_ACTIVE == Chip_GPIO_GetPinState(LPC_GPIO_PORT, BUTTON_PORT, BUTTON_PIN); -} - -int board_uart_read(uint8_t* buf, int len) -{ - //return UART_ReceiveByte(BOARD_UART_PORT); - (void) buf; (void) len; - return 0; -} - -int board_uart_write(void const * buf, int len) -{ - //UART_Send(BOARD_UART_PORT, &c, 1, BLOCKING); - (void) buf; (void) len; - return 0; -} - -#if CFG_TUSB_OS == OPT_OS_NONE -volatile uint32_t system_ticks = 0; -void SysTick_Handler (void) -{ - system_ticks++; -} - -uint32_t board_millis(void) -{ - return system_ticks; -} -#endif diff --git a/hw/bsp/nrf/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/nrf/FreeRTOSConfig/FreeRTOSConfig.h index efd26a3a7..0ddd536fb 100644 --- a/hw/bsp/nrf/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/nrf/FreeRTOSConfig/FreeRTOSConfig.h @@ -73,14 +73,15 @@ #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 -#define configSUPPORT_STATIC_ALLOCATION 0 -#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 /* 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 +#define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 @@ -116,23 +117,6 @@ #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 diff --git a/hw/bsp/nrf/boards/adafruit_clue/board.cmake b/hw/bsp/nrf/boards/adafruit_clue/board.cmake new file mode 100644 index 000000000..eb97e5c55 --- /dev/null +++ b/hw/bsp/nrf/boards/adafruit_clue/board.cmake @@ -0,0 +1,5 @@ +set(MCU_VARIANT nrf52840) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/nrf52840_s140_v6.ld) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/boards/arduino_nano33_ble/arduino_nano33_ble.ld b/hw/bsp/nrf/boards/arduino_nano33_ble/arduino_nano33_ble.ld index b7cac1019..9288a0c5e 100755 --- a/hw/bsp/nrf/boards/arduino_nano33_ble/arduino_nano33_ble.ld +++ b/hw/bsp/nrf/boards/arduino_nano33_ble/arduino_nano33_ble.ld @@ -1,7 +1,7 @@ /* Linker script to configure memory regions. */ SEARCH_DIR(.) -GROUP(-lgcc -lc -lnosys) +/*GROUP(-lgcc -lc -lnosys) not compatible with clang*/ MEMORY { diff --git a/hw/bsp/nrf/boards/arduino_nano33_ble/board.cmake b/hw/bsp/nrf/boards/arduino_nano33_ble/board.cmake new file mode 100644 index 000000000..93647063a --- /dev/null +++ b/hw/bsp/nrf/boards/arduino_nano33_ble/board.cmake @@ -0,0 +1,5 @@ +set(MCU_VARIANT nrf52840) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/arduino_nano33_ble.ld) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/boards/circuitplayground_bluefruit/board.cmake b/hw/bsp/nrf/boards/circuitplayground_bluefruit/board.cmake new file mode 100644 index 000000000..eb97e5c55 --- /dev/null +++ b/hw/bsp/nrf/boards/circuitplayground_bluefruit/board.cmake @@ -0,0 +1,5 @@ +set(MCU_VARIANT nrf52840) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/nrf52840_s140_v6.ld) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/boards/feather_nrf52840_express/board.cmake b/hw/bsp/nrf/boards/feather_nrf52840_express/board.cmake new file mode 100644 index 000000000..6ff1a7b59 --- /dev/null +++ b/hw/bsp/nrf/boards/feather_nrf52840_express/board.cmake @@ -0,0 +1,8 @@ +set(MCU_VARIANT nrf52840) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/nrf52840_s140_v6.ld) + +# enable max3421 host driver for this board +set(MAX3421_HOST 1) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/boards/feather_nrf52840_express/board.h b/hw/bsp/nrf/boards/feather_nrf52840_express/board.h index 8e6ce3230..3d59516d8 100644 --- a/hw/bsp/nrf/boards/feather_nrf52840_express/board.h +++ b/hw/bsp/nrf/boards/feather_nrf52840_express/board.h @@ -45,6 +45,13 @@ #define UART_RX_PIN 24 #define UART_TX_PIN 25 +// SPI for USB host shield +#define MAX3421_SCK_PIN 14 +#define MAX3421_MOSI_PIN 13 +#define MAX3421_MISO_PIN 15 +#define MAX3421_CS_PIN 27 // D10 +#define MAX3421_INTR_PIN 26 // D9 + #ifdef __cplusplus } #endif diff --git a/hw/bsp/nrf/boards/feather_nrf52840_express/board.mk b/hw/bsp/nrf/boards/feather_nrf52840_express/board.mk index b80807963..488f07b82 100644 --- a/hw/bsp/nrf/boards/feather_nrf52840_express/board.mk +++ b/hw/bsp/nrf/boards/feather_nrf52840_express/board.mk @@ -1,6 +1,9 @@ MCU_VARIANT = nrf52840 CFLAGS += -DNRF52840_XXAA +# enable max3421 host driver for this board +MAX3421_HOST = 1 + # All source paths should be relative to the top level. LD_FILE = hw/bsp/nrf/linker/nrf52840_s140_v6.ld diff --git a/hw/bsp/nrf/boards/feather_nrf52840_sense/board.cmake b/hw/bsp/nrf/boards/feather_nrf52840_sense/board.cmake new file mode 100644 index 000000000..eb97e5c55 --- /dev/null +++ b/hw/bsp/nrf/boards/feather_nrf52840_sense/board.cmake @@ -0,0 +1,5 @@ +set(MCU_VARIANT nrf52840) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/nrf52840_s140_v6.ld) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/boards/itsybitsy_nrf52840/board.cmake b/hw/bsp/nrf/boards/itsybitsy_nrf52840/board.cmake new file mode 100644 index 000000000..eb97e5c55 --- /dev/null +++ b/hw/bsp/nrf/boards/itsybitsy_nrf52840/board.cmake @@ -0,0 +1,5 @@ +set(MCU_VARIANT nrf52840) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/nrf52840_s140_v6.ld) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.cmake b/hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.cmake new file mode 100644 index 000000000..ffa5932c1 --- /dev/null +++ b/hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.cmake @@ -0,0 +1,5 @@ +set(MCU_VARIANT nrf52840) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/nrf52840_mdk_dongle.ld) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/boards/nrf52840_mdk_dongle/nrf52840_mdk_dongle.ld b/hw/bsp/nrf/boards/nrf52840_mdk_dongle/nrf52840_mdk_dongle.ld index 78eddc9c3..a6bc6dcfe 100644 --- a/hw/bsp/nrf/boards/nrf52840_mdk_dongle/nrf52840_mdk_dongle.ld +++ b/hw/bsp/nrf/boards/nrf52840_mdk_dongle/nrf52840_mdk_dongle.ld @@ -1,7 +1,7 @@ /* Linker script to configure memory regions. */ SEARCH_DIR(.) -GROUP(-lgcc -lc -lnosys) +/*GROUP(-lgcc -lc -lnosys) not compatible with clang*/ MEMORY { diff --git a/hw/bsp/nrf/boards/pca10056/board.cmake b/hw/bsp/nrf/boards/pca10056/board.cmake index b4fe39fc0..cc370aac8 100644 --- a/hw/bsp/nrf/boards/pca10056/board.cmake +++ b/hw/bsp/nrf/boards/pca10056/board.cmake @@ -1,8 +1,4 @@ set(MCU_VARIANT nrf52840) -set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf52840_xxaa.ld) function(update_board TARGET) - target_compile_definitions(${TARGET} PUBLIC - NRF52840_XXAA - ) endfunction() diff --git a/hw/bsp/nrf/boards/pca10056/board.h b/hw/bsp/nrf/boards/pca10056/board.h index f4368f830..24d3faa65 100644 --- a/hw/bsp/nrf/boards/pca10056/board.h +++ b/hw/bsp/nrf/boards/pca10056/board.h @@ -31,6 +31,8 @@ extern "C" { #endif +#define _PINNUM(port, pin) ((port)*32 + (pin)) + // LED #define LED_PIN 13 #define LED_STATE_ON 0 @@ -43,6 +45,14 @@ #define UART_RX_PIN 8 #define UART_TX_PIN 6 +// SPI for USB host shield +// Pin is correct but not working probably due to signal incompatible (1.8V 3v3) with MAC3421E !? +//#define MAX3421_SCK_PIN _PINNUM(1, 15) +//#define MAX3421_MOSI_PIN _PINNUM(1, 13) +//#define MAX3421_MISO_PIN _PINNUM(1, 14) +//#define MAX3421_CS_PIN _PINNUM(1, 12) +//#define MAX3421_INTR_PIN _PINNUM(1, 11) + #ifdef __cplusplus } #endif diff --git a/hw/bsp/nrf/boards/pca10059/board.cmake b/hw/bsp/nrf/boards/pca10059/board.cmake new file mode 100644 index 000000000..c79eb5964 --- /dev/null +++ b/hw/bsp/nrf/boards/pca10059/board.cmake @@ -0,0 +1,5 @@ +set(MCU_VARIANT nrf52840) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/pca10059.ld) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/boards/pca10059/pca10059.ld b/hw/bsp/nrf/boards/pca10059/pca10059.ld index 510bfdd8c..adc80f3c4 100644 --- a/hw/bsp/nrf/boards/pca10059/pca10059.ld +++ b/hw/bsp/nrf/boards/pca10059/pca10059.ld @@ -1,7 +1,7 @@ /* Linker script to configure memory regions. */ SEARCH_DIR(.) -GROUP(-lgcc -lc -lnosys) +/*GROUP(-lgcc -lc -lnosys) not compatible with clang*/ MEMORY { @@ -11,3 +11,9 @@ MEMORY INCLUDE "nrf_common.ld" + +/* nrfx v2 linker does not define __tbss_start/end__ __sbss_start/end__*/ +__tbss_start__ = __tbss_start; +__tbss_end__ = __tbss_end; +__sbss_start__ = __sbss_start; +__sbss_end__ = __sbss_end; diff --git a/hw/bsp/nrf/boards/pca10095/board.cmake b/hw/bsp/nrf/boards/pca10095/board.cmake index 1e72243c9..95dd30969 100644 --- a/hw/bsp/nrf/boards/pca10095/board.cmake +++ b/hw/bsp/nrf/boards/pca10095/board.cmake @@ -1,11 +1,6 @@ set(MCU_VARIANT nrf5340_application) -set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf5340_xxaa_application.ld) function(update_board TARGET) - target_compile_definitions(${TARGET} PUBLIC - NRF5340_XXAA - NRF5340_XXAA_APPLICATION - ) target_sources(${TARGET} PRIVATE ${NRFX_DIR}/drivers/src/nrfx_usbreg.c ) diff --git a/hw/bsp/nrf/boards/pca10095/board.h b/hw/bsp/nrf/boards/pca10095/board.h index fd3c63d6a..846c2ee5b 100644 --- a/hw/bsp/nrf/boards/pca10095/board.h +++ b/hw/bsp/nrf/boards/pca10095/board.h @@ -31,6 +31,8 @@ extern "C" { #endif +#define _PINNUM(port, pin) ((port)*32 + (pin)) + // LED #define LED_PIN 28 #define LED_STATE_ON 0 @@ -40,8 +42,16 @@ #define BUTTON_STATE_ACTIVE 0 // UART -#define UART_RX_PIN 32 -#define UART_TX_PIN 33 +#define UART_RX_PIN 22 +#define UART_TX_PIN 20 + +// SPI for USB host shield +// Pin is correct but not working probably due to signal incompatible (1.8V 3v3) with MAC3421E !? +//#define MAX3421_SCK_PIN _PINNUM(1, 15) +//#define MAX3421_MOSI_PIN _PINNUM(1, 13) +//#define MAX3421_MISO_PIN _PINNUM(1, 14) +//#define MAX3421_CS_PIN _PINNUM(1, 12) +//#define MAX3421_INTR_PIN _PINNUM(1, 11) #ifdef __cplusplus } diff --git a/hw/bsp/nrf/boards/pca10095/board.mk b/hw/bsp/nrf/boards/pca10095/board.mk index 9c4edbafc..20580d619 100644 --- a/hw/bsp/nrf/boards/pca10095/board.mk +++ b/hw/bsp/nrf/boards/pca10095/board.mk @@ -2,6 +2,9 @@ CPU_CORE = cortex-m33 MCU_VARIANT = nrf5340_application CFLAGS += -DNRF5340_XXAA -DNRF5340_XXAA_APPLICATION +# enable max3421 host driver for this board +MAX3421_HOST = 1 + LD_FILE = hw/mcu/nordic/nrfx/mdk/nrf5340_xxaa_application.ld SRC_C += hw/mcu/nordic/nrfx/drivers/src/nrfx_usbreg.c diff --git a/hw/bsp/nrf/boards/pca10100/board.cmake b/hw/bsp/nrf/boards/pca10100/board.cmake new file mode 100644 index 000000000..a925dae80 --- /dev/null +++ b/hw/bsp/nrf/boards/pca10100/board.cmake @@ -0,0 +1,4 @@ +set(MCU_VARIANT nrf52833) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake b/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake new file mode 100644 index 000000000..cc370aac8 --- /dev/null +++ b/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake @@ -0,0 +1,4 @@ +set(MCU_VARIANT nrf52840) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/family.c b/hw/bsp/nrf/family.c index 9ca666e36..885910f9a 100644 --- a/hw/bsp/nrf/family.c +++ b/hw/bsp/nrf/family.c @@ -33,13 +33,17 @@ #pragma GCC diagnostic ignored "-Wcast-qual" #pragma GCC diagnostic ignored "-Wcast-align" #pragma GCC diagnostic ignored "-Wunused-parameter" +#pragma GCC diagnostic ignored "-Wunused-variable" #pragma GCC diagnostic ignored "-Wundef" +#pragma GCC diagnostic ignored "-Wredundant-decls" #endif #include "nrfx.h" #include "hal/nrf_gpio.h" +#include "drivers/include/nrfx_gpiote.h" #include "drivers/include/nrfx_power.h" #include "drivers/include/nrfx_uarte.h" +#include "drivers/include/nrfx_spim.h" #ifdef SOFTDEVICE_PRESENT #include "nrf_sdm.h" @@ -51,11 +55,18 @@ #endif +// There is API changes between nrfx v2 and v3 +#if 85301 >= (10000*MDK_MAJOR_VERSION + 100*MDK_MINOR_VERSION + MDK_MICRO_VERSION) + // note MDK 8.53.1 is also used by nrfx v3.0.0, just skip this version and use later 3.x + #define NRFX_VER 2 +#else + #define NRFX_VER 3 +#endif + //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ -void USBD_IRQHandler(void) -{ +void USBD_IRQHandler(void) { tud_int_handler(0); } @@ -74,6 +85,7 @@ enum { #define LFCLK_SRC_RC CLOCK_LFCLKSRC_SRC_LFRC #define VBUSDETECT_Msk USBREG_USBREGSTATUS_VBUSDETECT_Msk #define OUTPUTRDY_Msk USBREG_USBREGSTATUS_OUTPUTRDY_Msk + #define GPIOTE_IRQn GPIOTE1_IRQn #else #define LFCLK_SRC_RC CLOCK_LFCLKSRC_SRC_RC #define VBUSDETECT_Msk POWER_USBREGSTATUS_VBUSDETECT_Msk @@ -86,15 +98,27 @@ static nrfx_uarte_t _uart_id = NRFX_UARTE_INSTANCE(0); // We must call it within SD's SOC event handler, or set it as power event handler if SD is not enabled. extern void tusb_hal_nrf_power_event(uint32_t event); - // nrf power callback, could be unused if SD is enabled or usb is disabled (board_test example) -TU_ATTR_UNUSED static void power_event_handler(nrfx_power_usb_evt_t event) -{ +TU_ATTR_UNUSED static void power_event_handler(nrfx_power_usb_evt_t event) { tusb_hal_nrf_power_event((uint32_t) event); } -void board_init(void) -{ +//------------- Host using MAX2341E -------------// +#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 +static void max3421_init(void); +static nrfx_spim_t _spi = NRFX_SPIM_INSTANCE(1); + +#if NRFX_VER > 2 +static nrfx_gpiote_t _gpiote = NRFX_GPIOTE_INSTANCE(0); +#endif + +#endif + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ + +void board_init(void) { // stop LF clock just in case we jump from application without reset NRF_CLOCK->TASKS_LFCLKSTOP = 1UL; @@ -110,23 +134,38 @@ void board_init(void) nrf_gpio_cfg_input(BUTTON_PIN, NRF_GPIO_PIN_PULLUP); // 1ms tick timer - SysTick_Config(SystemCoreClock/1000); + SysTick_Config(SystemCoreClock / 1000); // UART - nrfx_uarte_config_t uart_cfg = - { - .pseltxd = UART_TX_PIN, - .pselrxd = UART_RX_PIN, - .pselcts = NRF_UARTE_PSEL_DISCONNECTED, - .pselrts = NRF_UARTE_PSEL_DISCONNECTED, - .p_context = NULL, - .baudrate = NRF_UARTE_BAUDRATE_115200, // CFG_BOARD_UART_BAUDRATE - .interrupt_priority = 7, - .hal_cfg = { - .hwfc = NRF_UARTE_HWFC_DISABLED, - .parity = NRF_UARTE_PARITY_EXCLUDED, - } + #if NRFX_VER <= 2 + nrfx_uarte_config_t uart_cfg = { + .pseltxd = UART_TX_PIN, + .pselrxd = UART_RX_PIN, + .pselcts = NRF_UARTE_PSEL_DISCONNECTED, + .pselrts = NRF_UARTE_PSEL_DISCONNECTED, + .p_context = NULL, + .baudrate = NRF_UARTE_BAUDRATE_115200, // CFG_BOARD_UART_BAUDRATE + .interrupt_priority = 7, + .hal_cfg = { + .hwfc = NRF_UARTE_HWFC_DISABLED, + .parity = NRF_UARTE_PARITY_EXCLUDED, + } }; + #else + nrfx_uarte_config_t uart_cfg = { + .txd_pin = UART_TX_PIN, + .rxd_pin = UART_RX_PIN, + .rts_pin = NRF_UARTE_PSEL_DISCONNECTED, + .cts_pin = NRF_UARTE_PSEL_DISCONNECTED, + .p_context = NULL, + .baudrate = NRF_UARTE_BAUDRATE_115200, // CFG_BOARD_UART_BAUDRATE + .interrupt_priority = 7, + .config = { + .hwfc = NRF_UARTE_HWFC_DISABLED, + .parity = NRF_UARTE_PARITY_EXCLUDED, + } + }; + #endif nrfx_uarte_init(&_uart_id, &uart_cfg, NULL); //uart_handler); @@ -165,61 +204,97 @@ void board_init(void) // USB power may already be ready at this time -> no event generated // We need to invoke the handler based on the status initially - #ifdef NRF5340_XXAA +#ifdef NRF5340_XXAA usb_reg = NRF_USBREGULATOR->USBREGSTATUS; - #else +#else usb_reg = NRF_POWER->USBREGSTATUS; - #endif +#endif } if ( usb_reg & VBUSDETECT_Msk ) tusb_hal_nrf_power_event(USB_EVT_DETECTED); if ( usb_reg & OUTPUTRDY_Msk ) tusb_hal_nrf_power_event(USB_EVT_READY); #endif + +#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 + max3421_init(); +#endif + } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ -void board_led_write(bool state) -{ - nrf_gpio_pin_write(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +void board_led_write(bool state) { + nrf_gpio_pin_write(LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == nrf_gpio_pin_read(BUTTON_PIN); } -int board_uart_read(uint8_t* buf, int len) -{ - (void) buf; (void) len; - return 0; -// return NRFX_SUCCESS == nrfx_uart_rx(&_uart_id, buf, (size_t) len) ? len : 0; +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + (void) max_len; + +#ifdef NRF5340_XXAA + uintptr_t did_addr = (uintptr_t) NRF_FICR->INFO.DEVICEID; +#else + uintptr_t did_addr = (uintptr_t) NRF_FICR->DEVICEID; +#endif + + const uint8_t* device_id = (const uint8_t*) did_addr; + for(uint8_t i=0; i<8; i++) { + id[i] = device_id[i]; + } + return 8; } -int board_uart_write(void const * buf, int len) -{ - return (NRFX_SUCCESS == nrfx_uarte_tx(&_uart_id, (uint8_t const*) buf, (size_t) len)) ? len : 0; +int board_uart_read(uint8_t* buf, int len) { + (void) buf; + (void) len; + return 0; +// nrfx_err_t err = nrfx_uarte_rx(&_uart_id, buf, (size_t) len); +// return NRFX_SUCCESS == err ? len : 0; +} + +int board_uart_write(void const* buf, int len) { + nrfx_err_t err = nrfx_uarte_tx(&_uart_id, (uint8_t const*) buf, (size_t) len + #if NRFX_VER > 2 + ,0 + #endif + ); + return (NRFX_SUCCESS == err) ? len : 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 +#ifndef __ICCARM__ +// Implement _start() since we use linker flag '-nostartfiles'. +// Requires defined __STARTUP_CLEAR_BSS, +extern int main(void); +TU_ATTR_UNUSED void _start(void) { + // called by startup code + main(); + while (1) {} +} +#endif + +//--------------------------------------------------------------------+ +// Softdevice running +//--------------------------------------------------------------------+ #ifdef SOFTDEVICE_PRESENT // process SOC event from SD -uint32_t proc_soc(void) -{ +uint32_t proc_soc(void) { uint32_t soc_evt; uint32_t err = sd_evt_get(&soc_evt); @@ -236,25 +311,137 @@ uint32_t proc_soc(void) return err; } -uint32_t proc_ble(void) -{ +uint32_t proc_ble(void) { // do nothing with ble return NRF_ERROR_NOT_FOUND; } -void SD_EVT_IRQHandler(void) -{ +void SD_EVT_IRQHandler(void) { // process BLE and SOC until there is no more events - while( (NRF_ERROR_NOT_FOUND != proc_ble()) || (NRF_ERROR_NOT_FOUND != proc_soc()) ) - { - + while( (NRF_ERROR_NOT_FOUND != proc_ble()) || (NRF_ERROR_NOT_FOUND != proc_soc()) ) { } } -void nrf_error_cb(uint32_t id, uint32_t pc, uint32_t info) -{ +void nrf_error_cb(uint32_t id, uint32_t pc, uint32_t info) { (void) id; (void) pc; (void) info; } #endif + +//--------------------------------------------------------------------+ +// API: SPI transfer with MAX3421E, must be implemented by application +//--------------------------------------------------------------------+ +#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 + +#if NRFX_VER <= 2 +void max3421_int_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action ) { + if (action != NRF_GPIOTE_POLARITY_HITOLO) return; +#else +void max3421_int_handler(nrfx_gpiote_pin_t pin, nrfx_gpiote_trigger_t action, void* p_context) { + (void) p_context; + if (action != NRFX_GPIOTE_TRIGGER_HITOLO) return; +#endif + + if (pin != MAX3421_INTR_PIN) return; + tuh_int_handler(1, true); +} + +static void max3421_init(void) { + // Somehow pca10056/95 is not working probably due to signal incompatible (1.8V 3v3) with MAC3421E !? + + // manually manage CS + nrf_gpio_cfg_output(MAX3421_CS_PIN); + nrf_gpio_pin_write(MAX3421_CS_PIN, 1); + + // USB host using max3421e usb controller via SPI + nrfx_spim_config_t cfg = { + .sck_pin = MAX3421_SCK_PIN, + .mosi_pin = MAX3421_MOSI_PIN, + .miso_pin = MAX3421_MISO_PIN, + #if NRFX_VER <= 2 + .ss_pin = NRFX_SPIM_PIN_NOT_USED, + .frequency = NRF_SPIM_FREQ_4M, + #else + .ss_pin = NRF_SPIM_PIN_NOT_CONNECTED, + .frequency = 4000000u, + #endif + .ss_active_high = false, + .irq_priority = 3, + .orc = 0xFF, + // default setting 4 Mhz, Mode 0, MSB first + .mode = NRF_SPIM_MODE_0, + .bit_order = NRF_SPIM_BIT_ORDER_MSB_FIRST, + .miso_pull = NRF_GPIO_PIN_NOPULL, + }; + + // no handler --> blocking + TU_ASSERT(NRFX_SUCCESS == nrfx_spim_init(&_spi, &cfg, NULL, NULL), ); + + // max3421e interrupt pin + #if NRFX_VER <= 2 + nrfx_gpiote_init(1); + nrfx_gpiote_in_config_t in_config = NRFX_GPIOTE_CONFIG_IN_SENSE_HITOLO(true); + in_config.pull = NRF_GPIO_PIN_PULLUP; + NVIC_SetPriority(GPIOTE_IRQn, 2); + nrfx_gpiote_in_init(MAX3421_INTR_PIN, &in_config, max3421_int_handler); + nrfx_gpiote_trigger_enable(MAX3421_INTR_PIN, true); + #else + nrf_gpio_pin_pull_t intr_pull = NRF_GPIO_PIN_PULLUP; + nrfx_gpiote_trigger_config_t intr_trigger = { + .trigger = NRFX_GPIOTE_TRIGGER_HITOLO, + .p_in_channel = NULL, // sensing mechanism + }; + nrfx_gpiote_handler_config_t intr_handler = { + .handler = max3421_int_handler, + .p_context = NULL, + }; + nrfx_gpiote_input_pin_config_t intr_config = { + .p_pull_config = &intr_pull, + .p_trigger_config = &intr_trigger, + .p_handler_config = &intr_handler, + }; + + nrfx_gpiote_init(&_gpiote, 1); + NVIC_SetPriority(GPIOTE_IRQn, 2); + + nrfx_gpiote_input_configure(&_gpiote, MAX3421_INTR_PIN, &intr_config); + nrfx_gpiote_trigger_enable(&_gpiote, MAX3421_INTR_PIN, true); + #endif +} + +// API to enable/disable MAX3421 INTR pin interrupt +void tuh_max3421_int_api(uint8_t rhport, bool enabled) { + (void) rhport; + + // use NVIC_Enable/Disable instead since nrfx_gpiote_trigger_enable/disable clear pending and can miss interrupt + // when disabled and re-enabled. + if (enabled) { + NVIC_EnableIRQ(GPIOTE_IRQn); + } else { + NVIC_DisableIRQ(GPIOTE_IRQn); + } +} + +// API to control MAX3421 SPI CS +void tuh_max3421_spi_cs_api(uint8_t rhport, bool active) { + (void) rhport; + nrf_gpio_pin_write(MAX3421_CS_PIN, active ? 0 : 1); +} + +// API to transfer data with MAX3421 SPI +// Either tx_buf or rx_buf can be NULL, which means transfer is write or read only +bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const* tx_buf, uint8_t* rx_buf, size_t xfer_bytes) { + (void) rhport; + + nrfx_spim_xfer_desc_t xfer = { + .p_tx_buffer = tx_buf, + .tx_length = tx_buf ? xfer_bytes : 0, + .p_rx_buffer = rx_buf, + .rx_length = rx_buf ? xfer_bytes : 0, + }; + + return nrfx_spim_xfer(&_spi, &xfer, 0) == NRFX_SUCCESS; +} + +#endif diff --git a/hw/bsp/nrf/family.cmake b/hw/bsp/nrf/family.cmake index 2b13249f4..5de69a8a3 100644 --- a/hw/bsp/nrf/family.cmake +++ b/hw/bsp/nrf/family.cmake @@ -1,9 +1,5 @@ include_guard() -if (NOT BOARD) - message(FATAL_ERROR "BOARD not specified") -endif () - set(NRFX_DIR ${TOP}/hw/mcu/nordic/nrfx) set(CMSIS_DIR ${TOP}/lib/CMSIS_5) @@ -19,7 +15,7 @@ else () set(JLINK_DEVICE ${MCU_VARIANT}_xxaa) endif () -set(CMAKE_TOOLCHAIN_FILE ${TOP}/tools/cmake/toolchain/arm_${TOOLCHAIN}.cmake) +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS NRF5X CACHE INTERNAL "") @@ -29,61 +25,75 @@ set(FAMILY_MCUS NRF5X 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 - # driver - ${NRFX_DIR}/drivers/src/nrfx_power.c - ${NRFX_DIR}/drivers/src/nrfx_uarte.c - # mcu - ${NRFX_DIR}/mdk/system_${MCU_VARIANT}.c + if (TARGET ${BOARD_TARGET}) + return() + endif () + + if (MCU_VARIANT STREQUAL "nrf5340_application") + set(MCU_VARIANT_XXAA "nrf5340_xxaa_application") + else () + set(MCU_VARIANT_XXAA "${MCU_VARIANT}_xxaa") + endif () + + if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/linker/${MCU_VARIANT_XXAA}.ld) + endif () + + if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) + set(STARTUP_FILE_GNU ${NRFX_DIR}/mdk/gcc_startup_${MCU_VARIANT}.S) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + endif () + + add_library(${BOARD_TARGET} STATIC + ${NRFX_DIR}/helpers/nrfx_flag32_allocator.c + ${NRFX_DIR}/drivers/src/nrfx_gpiote.c + ${NRFX_DIR}/drivers/src/nrfx_power.c + ${NRFX_DIR}/drivers/src/nrfx_spim.c + ${NRFX_DIR}/drivers/src/nrfx_uarte.c + ${NRFX_DIR}/mdk/system_${MCU_VARIANT}.c + ${NRFX_DIR}/soc/nrfx_atomic.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + string(TOUPPER "${MCU_VARIANT_XXAA}" MCU_VARIANT_XXAA_UPPER) + target_compile_definitions(${BOARD_TARGET} PUBLIC + __STARTUP_CLEAR_BSS + CONFIG_GPIO_AS_PINRESET + ${MCU_VARIANT_XXAA_UPPER} + ) + + if (TRACE_ETM STREQUAL "1") + # ENABLE_TRACE will cause system_nrf5x.c to set up ETM trace + target_compile_definitions(${BOARD_TARGET} PUBLIC ENABLE_TRACE) + endif () + + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${NRFX_DIR} + ${NRFX_DIR}/mdk + ${NRFX_DIR}/hal + ${NRFX_DIR}/drivers/include + ${NRFX_DIR}/drivers/src + ${CMSIS_DIR}/CMSIS/Core/Include + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -L${NRFX_DIR}/mdk + --specs=nosys.specs --specs=nano.specs + -nostartfiles ) - target_compile_definitions(${BOARD_TARGET} PUBLIC - CONFIG_GPIO_AS_PINRESET + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -L${NRFX_DIR}/mdk ) - - if (TRACE_ETM STREQUAL "1") - # ENABLE_TRACE will cause system_nrf5x.c to set up ETM trace - target_compile_definitions(${BOARD_TARGET} PUBLIC ENABLE_TRACE) - endif () - - target_include_directories(${BOARD_TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${NRFX_DIR} - ${NRFX_DIR}/mdk - ${NRFX_DIR}/hal - ${NRFX_DIR}/drivers/include - ${NRFX_DIR}/drivers/src - ${CMSIS_DIR}/CMSIS/Core/Include + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" ) - - update_board(${BOARD_TARGET}) - - if (NOT DEFINED LD_FILE_${CMAKE_C_COMPILER_ID}) - set(LD_FILE_GNU ${NRFX_DIR}/mdk/${MCU_VARIANT}_xxaa.ld) - endif () - - if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID}) - set(STARTUP_FILE_GNU ${NRFX_DIR}/mdk/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 file - "LINKER:--script=${LD_FILE_GNU}" - -L${NRFX_DIR}/mdk - # 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 () endif () endfunction() diff --git a/hw/bsp/nrf/family.mk b/hw/bsp/nrf/family.mk index cdcfe39bd..b3c05e6db 100644 --- a/hw/bsp/nrf/family.mk +++ b/hw/bsp/nrf/family.mk @@ -1,5 +1,6 @@ UF2_FAMILY_ID = 0xADA52840 -DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/nordic/nrfx + +NRFX_DIR = hw/mcu/nordic/nrfx include $(TOP)/$(BOARD_PATH)/board.mk @@ -7,31 +8,51 @@ include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m4 CFLAGS += \ - -flto \ -DCFG_TUSB_MCU=OPT_MCU_NRF5X \ - -DCONFIG_GPIO_AS_PINRESET + -DCONFIG_GPIO_AS_PINRESET \ + -D__STARTUP_CLEAR_BSS + +#CFLAGS += -nostdlib +#CFLAGS += -D__START=main # suppress warning caused by vendor mcu driver -CFLAGS += -Wno-error=undef -Wno-error=unused-parameter -Wno-error=cast-align -Wno-error=cast-qual -Wno-error=redundant-decls +CFLAGS_GCC += \ + -flto \ + -Wno-error=undef \ + -Wno-error=unused-parameter \ + -Wno-error=unused-variable \ + -Wno-error=cast-align \ + -Wno-error=cast-qual \ + -Wno-error=redundant-decls \ -LDFLAGS += -L$(TOP)/hw/mcu/nordic/nrfx/mdk +LDFLAGS_GCC += \ + -nostartfiles \ + --specs=nosys.specs --specs=nano.specs \ + -L$(TOP)/${NRFX_DIR}/mdk + +LDFLAGS_CLANG += \ + -L$(TOP)/${NRFX_DIR}/mdk \ SRC_C += \ src/portable/nordic/nrf5x/dcd_nrf5x.c \ - hw/mcu/nordic/nrfx/drivers/src/nrfx_power.c \ - hw/mcu/nordic/nrfx/drivers/src/nrfx_uarte.c \ - hw/mcu/nordic/nrfx/mdk/system_$(MCU_VARIANT).c + ${NRFX_DIR}/helpers/nrfx_flag32_allocator.c \ + ${NRFX_DIR}/drivers/src/nrfx_gpiote.c \ + ${NRFX_DIR}/drivers/src/nrfx_power.c \ + ${NRFX_DIR}/drivers/src/nrfx_spim.c \ + ${NRFX_DIR}/drivers/src/nrfx_uarte.c \ + ${NRFX_DIR}/mdk/system_$(MCU_VARIANT).c \ + ${NRFX_DIR}/soc/nrfx_atomic.c INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ - $(TOP)/hw/mcu/nordic/nrfx \ - $(TOP)/hw/mcu/nordic/nrfx/mdk \ - $(TOP)/hw/mcu/nordic/nrfx/hal \ - $(TOP)/hw/mcu/nordic/nrfx/drivers/include \ - $(TOP)/hw/mcu/nordic/nrfx/drivers/src \ + $(TOP)/${NRFX_DIR} \ + $(TOP)/${NRFX_DIR}/mdk \ + $(TOP)/${NRFX_DIR}/hal \ + $(TOP)/${NRFX_DIR}/drivers/include \ + $(TOP)/${NRFX_DIR}/drivers/src \ -SRC_S += hw/mcu/nordic/nrfx/mdk/gcc_startup_$(MCU_VARIANT).S +SRC_S += ${NRFX_DIR}/mdk/gcc_startup_$(MCU_VARIANT).S ASFLAGS += -D__HEAP_SIZE=0 diff --git a/hw/bsp/nrf/linker/nrf52833_xxaa.ld b/hw/bsp/nrf/linker/nrf52833_xxaa.ld new file mode 100644 index 000000000..ae4d0e5b3 --- /dev/null +++ b/hw/bsp/nrf/linker/nrf52833_xxaa.ld @@ -0,0 +1,20 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +/*GROUP(-lgcc -lc -lnosys) not compatible with clang*/ + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x80000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x20000 + CODE_RAM (rwx) : ORIGIN = 0x800000, LENGTH = 0x20000 +} + + +INCLUDE "nrf_common.ld" + +/* nrfx v2 linker does not define __tbss_start/end__ __sbss_start/end__*/ +__tbss_start__ = __tbss_start; +__tbss_end__ = __tbss_end; +__sbss_start__ = __sbss_start; +__sbss_end__ = __sbss_end; diff --git a/hw/bsp/nrf/linker/nrf52840_s140_v6.ld b/hw/bsp/nrf/linker/nrf52840_s140_v6.ld index e27fa1c91..037a14196 100644 --- a/hw/bsp/nrf/linker/nrf52840_s140_v6.ld +++ b/hw/bsp/nrf/linker/nrf52840_s140_v6.ld @@ -1,11 +1,11 @@ /* Linker script to configure memory regions. */ SEARCH_DIR(.) -GROUP(-lgcc -lc -lnosys) +/*GROUP(-lgcc -lc -lnosys) not compatible with clang*/ MEMORY { - FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0xED000 - 0x26000 + FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0xED000 - 0x26000 /* SRAM required by S132 depend on * - Attribute Table Size @@ -14,7 +14,7 @@ MEMORY * - Concurrent connection peripheral + central + secure links * - Event Len, HVN queue, Write CMD queue */ - RAM (rwx) : ORIGIN = 0x20003400, LENGTH = 0x20040000 - 0x20003400 + RAM (rwx) : ORIGIN = 0x20003400, LENGTH = 0x20040000 - 0x20003400 } SECTIONS @@ -36,3 +36,9 @@ SECTIONS } INSERT AFTER .data; INCLUDE "nrf_common.ld" + +/* nrfx v2 linker does not define __tbss_start/end__ __sbss_start/end__*/ +__tbss_start__ = __tbss_start; +__tbss_end__ = __tbss_end; +__sbss_start__ = __sbss_start; +__sbss_end__ = __sbss_end; diff --git a/hw/bsp/nrf/linker/nrf52840_xxaa.ld b/hw/bsp/nrf/linker/nrf52840_xxaa.ld new file mode 100644 index 000000000..2d20ba7ac --- /dev/null +++ b/hw/bsp/nrf/linker/nrf52840_xxaa.ld @@ -0,0 +1,20 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +/*GROUP(-lgcc -lc -lnosys) not compatible with clang*/ + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x100000 + EXTFLASH (rx) : ORIGIN = 0x12000000, LENGTH = 0x8000000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x40000 + CODE_RAM (rwx) : ORIGIN = 0x800000, LENGTH = 0x40000 +} + +INCLUDE "nrf_common.ld" + +/* nrfx v2 linker does not define __tbss_start/end__ __sbss_start/end__*/ +__tbss_start__ = __tbss_start; +__tbss_end__ = __tbss_end; +__sbss_start__ = __sbss_start; +__sbss_end__ = __sbss_end; diff --git a/hw/bsp/nrf/linker/nrf5340_xxaa_application.ld b/hw/bsp/nrf/linker/nrf5340_xxaa_application.ld new file mode 100644 index 000000000..31762d0b2 --- /dev/null +++ b/hw/bsp/nrf/linker/nrf5340_xxaa_application.ld @@ -0,0 +1,21 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +/*GROUP(-lgcc -lc) not compatible with clang*/ + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x100000 + EXTFLASH (rx) : ORIGIN = 0x10000000, LENGTH = 0x8000000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x40000 + RAM1 (rwx) : ORIGIN = 0x20040000, LENGTH = 0x3F000 +} + + +INCLUDE "nrf_common.ld" + +/* nrfx v2 linker does not define __tbss_start/end__ __sbss_start/end__*/ +__tbss_start__ = __tbss_start; +__tbss_end__ = __tbss_end; +__sbss_start__ = __sbss_start; +__sbss_end__ = __sbss_end; diff --git a/hw/bsp/nrf/nrfx_config.h b/hw/bsp/nrf/nrfx_config.h index 696a3fb04..fbec4192b 100644 --- a/hw/bsp/nrf/nrfx_config.h +++ b/hw/bsp/nrf/nrfx_config.h @@ -5,13 +5,14 @@ #define NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY 7 #define NRFX_CLOCK_ENABLED 0 +#define NRFX_GPIOTE_ENABLED 1 +#define NRFX_GPIOTE0_ENABLED 1 #define NRFX_UARTE_ENABLED 1 #define NRFX_UARTE0_ENABLED 1 -#define NRFX_UARTE1_ENABLED 0 -#define NRFX_UARTE2_ENABLED 0 -#define NRFX_UARTE3_ENABLED 0 +#define NRFX_SPIM_ENABLED 1 +#define NRFX_SPIM1_ENABLED 1 // use SPI1 since nrf5340 share uart with spi #define NRFX_PRS_ENABLED 0 #define NRFX_USBREG_ENABLED 1 @@ -42,5 +43,4 @@ #error "Unknown device." #endif - #endif // NRFX_CONFIG_H__ diff --git a/hw/bsp/nrf/nrfx_glue.h b/hw/bsp/nrf/nrfx_glue.h index cdf49b4ab..ef756c670 100644 --- a/hw/bsp/nrf/nrfx_glue.h +++ b/hw/bsp/nrf/nrfx_glue.h @@ -220,6 +220,75 @@ static inline bool _NRFX_IRQ_IS_PENDING(IRQn_Type irq_number) /** @} */ +//------------------------------------------------------------------------------ + +#include + +/** + * @brief Atomic 32 bit unsigned type. + */ +#define nrfx_atomic_t nrfx_atomic_u32_t + +/** + * @brief Stores value to an atomic object and returns previously stored value. + * + * @param[in] p_data Atomic memory pointer. + * @param[in] value Value to store. + * + * @return Old value stored into atomic object. + */ +#define NRFX_ATOMIC_FETCH_STORE(p_data, value) nrfx_atomic_u32_fetch_store(p_data, value) + +/** + * @brief Performs logical OR operation on an atomic object and returns previously stored value. + * + * @param[in] p_data Atomic memory pointer. + * @param[in] value Value of second operand of OR operation. + * + * @return Old value stored into atomic object. + */ +#define NRFX_ATOMIC_FETCH_OR(p_data, value) nrfx_atomic_u32_fetch_or(p_data, value) + +/** + * @brief Performs logical AND operation on an atomic object and returns previously stored value. + * + * @param[in] p_data Atomic memory pointer. + * @param[in] value Value of second operand of AND operation. + * + * @return Old value stored into atomic object. + */ +#define NRFX_ATOMIC_FETCH_AND(p_data, value) nrfx_atomic_u32_fetch_and(p_data, value) + +/** + * @brief Performs logical XOR operation on an atomic object and returns previously stored value. + * + * @param[in] p_data Atomic memory pointer. + * @param[in] value Value of second operand of XOR operation. + * + * @return Old value stored into atomic object. + */ +#define NRFX_ATOMIC_FETCH_XOR(p_data, value) nrfx_atomic_u32_fetch_xor(p_data, value) + +/** + * @brief Performs logical ADD operation on an atomic object and returns previously stored value. + * + * @param[in] p_data Atomic memory pointer. + * @param[in] value Value of second operand of ADD operation. + * + * @return Old value stored into atomic object. + */ +#define NRFX_ATOMIC_FETCH_ADD(p_data, value) nrfx_atomic_u32_fetch_add(p_data, value) + +/** + * @brief Performs logical SUB operation on an atomic object and returns previously stored value. + * + * @param[in] p_data Atomic memory pointer. + * @param[in] value Value of second operand of SUB operation. + * + * @return Old value stored into atomic object. + */ +#define NRFX_ATOMIC_FETCH_SUB(p_data, value) nrfx_atomic_u32_fetch_sub(p_data, value) + #ifdef __cplusplus } #endif diff --git a/hw/bsp/nutiny_nuc121s/board.mk b/hw/bsp/nutiny_nuc121s/board.mk index aa8f00e70..161ff9041 100644 --- a/hw/bsp/nutiny_nuc121s/board.mk +++ b/hw/bsp/nutiny_nuc121s/board.mk @@ -13,6 +13,8 @@ CFLAGS += \ # mcu driver cause following warnings CFLAGS += -Wno-error=redundant-decls +LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs + # All source paths should be relative to the top level. LD_FILE = hw/bsp/$(BOARD)/nuc121_flash.ld diff --git a/hw/bsp/nutiny_nuc125s/board.mk b/hw/bsp/nutiny_nuc125s/board.mk index bf7610a7b..081764fd3 100644 --- a/hw/bsp/nutiny_nuc125s/board.mk +++ b/hw/bsp/nutiny_nuc125s/board.mk @@ -13,6 +13,8 @@ CFLAGS += \ # mcu driver cause following warnings CFLAGS += -Wno-error=redundant-decls +LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs + # All source paths should be relative to the top level. LD_FILE = hw/bsp/$(BOARD)/nuc125_flash.ld diff --git a/hw/bsp/nutiny_nuc126v/board.mk b/hw/bsp/nutiny_nuc126v/board.mk index 46f53420c..2466b3a31 100644 --- a/hw/bsp/nutiny_nuc126v/board.mk +++ b/hw/bsp/nutiny_nuc126v/board.mk @@ -14,6 +14,8 @@ CFLAGS += \ # mcu driver cause following warnings CFLAGS += -Wno-error=redundant-decls +LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs + # All source paths should be relative to the top level. LD_FILE = hw/bsp/$(BOARD)/nuc126_flash.ld diff --git a/hw/bsp/nutiny_sdk_nuc120/board.mk b/hw/bsp/nutiny_sdk_nuc120/board.mk index b1f9245a6..b54895b58 100644 --- a/hw/bsp/nutiny_sdk_nuc120/board.mk +++ b/hw/bsp/nutiny_sdk_nuc120/board.mk @@ -9,6 +9,8 @@ CFLAGS += \ -DCFG_EXAMPLE_VIDEO_READONLY \ -DCFG_TUSB_MCU=OPT_MCU_NUC120 +LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs + # All source paths should be relative to the top level. LD_FILE = hw/bsp/nutiny_sdk_nuc120/nuc120_flash.ld diff --git a/hw/bsp/nutiny_sdk_nuc505/board.mk b/hw/bsp/nutiny_sdk_nuc505/board.mk index 3e48d3998..f3b389354 100644 --- a/hw/bsp/nutiny_sdk_nuc505/board.mk +++ b/hw/bsp/nutiny_sdk_nuc505/board.mk @@ -12,6 +12,8 @@ CFLAGS += \ # mcu driver cause following warnings CFLAGS += -Wno-error=redundant-decls +LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs + # All source paths should be relative to the top level. LD_FILE = hw/bsp/$(BOARD)/nuc505_flashtoram.ld diff --git a/hw/bsp/ra/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/ra/FreeRTOSConfig/FreeRTOSConfig.h index 4ef5dd883..b132e2559 100644 --- a/hw/bsp/ra/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/ra/FreeRTOSConfig/FreeRTOSConfig.h @@ -64,7 +64,11 @@ /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 -#define configENABLE_FPU 1 +#if defined(__ARM_FP) && __ARM_FP >= 4 + #define configENABLE_FPU 1 +#else + #define configENABLE_FPU 0 +#endif #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) @@ -88,14 +92,15 @@ #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 -#define configSUPPORT_STATIC_ALLOCATION 0 -#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 /* 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 +#define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 @@ -131,23 +136,6 @@ #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 diff --git a/hw/bsp/ra/boards/ra2a1_ek/board.cmake b/hw/bsp/ra/boards/ra2a1_ek/board.cmake new file mode 100644 index 000000000..4d083ca98 --- /dev/null +++ b/hw/bsp/ra/boards/ra2a1_ek/board.cmake @@ -0,0 +1,10 @@ +set(CMAKE_SYSTEM_PROCESSOR cortex-m23 CACHE INTERNAL "System Processor") +set(MCU_VARIANT ra2a1) + +set(JLINK_DEVICE R7FA2A1AB) + +function(update_board TARGET) +# target_compile_definitions(${TARGET} PUBLIC) +# target_sources(${TARGET} PRIVATE) +# target_include_directories(${BOARD_TARGET} PUBLIC) +endfunction() diff --git a/hw/bsp/ra/boards/ra2a1_ek/board.h b/hw/bsp/ra/boards/ra2a1_ek/board.h new file mode 100644 index 000000000..1c2b666d2 --- /dev/null +++ b/hw/bsp/ra/boards/ra2a1_ek/board.h @@ -0,0 +1,53 @@ +/* + * 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 _BOARD_H_ +#define _BOARD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define LED1 BSP_IO_PORT_02_PIN_05 +#define LED_STATE_ON 1 + +#define SW1 BSP_IO_PORT_02_PIN_06 +#define BUTTON_STATE_ACTIVE 0 + +static const ioport_pin_cfg_t board_pin_cfg[] = { + {.pin = LED1, .pin_cfg = IOPORT_CFG_PORT_DIRECTION_OUTPUT}, + {.pin = SW1, .pin_cfg = IOPORT_CFG_PORT_DIRECTION_INPUT}, + // USB FS D+, D-, VBus + {.pin = BSP_IO_PORT_04_PIN_07, .pin_cfg = IOPORT_CFG_PERIPHERAL_PIN | IOPORT_PERIPHERAL_USB_FS}, + {.pin = BSP_IO_PORT_09_PIN_14, .pin_cfg = IOPORT_CFG_PERIPHERAL_PIN | IOPORT_PERIPHERAL_USB_FS}, + {.pin = BSP_IO_PORT_09_PIN_15, .pin_cfg = IOPORT_CFG_PERIPHERAL_PIN | IOPORT_PERIPHERAL_USB_FS}, +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hw/bsp/ra/boards/ra2a1_ek/board.mk b/hw/bsp/ra/boards/ra2a1_ek/board.mk new file mode 100644 index 000000000..7a176418e --- /dev/null +++ b/hw/bsp/ra/boards/ra2a1_ek/board.mk @@ -0,0 +1,7 @@ +CPU_CORE = cortex-m23 +MCU_VARIANT = ra2a1 + +# For flash-jlink target +JLINK_DEVICE = R7FA2A1AB + +flash: flash-jlink diff --git a/hw/bsp/ra/boards/ra2a1_ek/fsp_cfg/bsp/bsp_cfg.h b/hw/bsp/ra/boards/ra2a1_ek/fsp_cfg/bsp/bsp_cfg.h new file mode 100644 index 000000000..30637c17b --- /dev/null +++ b/hw/bsp/ra/boards/ra2a1_ek/fsp_cfg/bsp/bsp_cfg.h @@ -0,0 +1,62 @@ +/* generated configuration header file - do not edit */ +#ifndef BSP_CFG_H_ +#define BSP_CFG_H_ +#ifdef __cplusplus + extern "C" { + #endif + +#include "bsp_clock_cfg.h" +#include "bsp_mcu_family_cfg.h" +#include "board_cfg.h" +#define RA_NOT_DEFINED 0 +#ifndef BSP_CFG_RTOS +#if (RA_NOT_DEFINED) != (RA_NOT_DEFINED) + #define BSP_CFG_RTOS (2) + #elif (RA_NOT_DEFINED) != (RA_NOT_DEFINED) + #define BSP_CFG_RTOS (1) + #else +#define BSP_CFG_RTOS (0) +#endif +#endif +#ifndef BSP_CFG_RTC_USED +#define BSP_CFG_RTC_USED (RA_NOT_DEFINED) +#endif +#undef RA_NOT_DEFINED +#if defined(_RA_BOOT_IMAGE) + #define BSP_CFG_BOOT_IMAGE (1) + #endif +#define BSP_CFG_MCU_VCC_MV (3300) +#define BSP_CFG_STACK_MAIN_BYTES (0x400) +#define BSP_CFG_HEAP_BYTES (0x400) +#define BSP_CFG_PARAM_CHECKING_ENABLE (1) +#define BSP_CFG_ASSERT (0) +#define BSP_CFG_ERROR_LOG (0) + +#define BSP_CFG_PFS_PROTECT ((1)) + +#define BSP_CFG_C_RUNTIME_INIT ((1)) +#define BSP_CFG_EARLY_INIT ((0)) + +#define BSP_CFG_STARTUP_CLOCK_REG_NOT_RESET ((0)) + +#ifndef BSP_CLOCK_CFG_MAIN_OSC_POPULATED +#define BSP_CLOCK_CFG_MAIN_OSC_POPULATED (1) +#endif + +#ifndef BSP_CLOCK_CFG_MAIN_OSC_CLOCK_SOURCE +#define BSP_CLOCK_CFG_MAIN_OSC_CLOCK_SOURCE (0) +#endif +#ifndef BSP_CLOCK_CFG_SUBCLOCK_DRIVE +#define BSP_CLOCK_CFG_SUBCLOCK_DRIVE (0) +#endif +#ifndef BSP_CLOCK_CFG_SUBCLOCK_POPULATED +#define BSP_CLOCK_CFG_SUBCLOCK_POPULATED (1) +#endif +#ifndef BSP_CLOCK_CFG_SUBCLOCK_STABILIZATION_MS +#define BSP_CLOCK_CFG_SUBCLOCK_STABILIZATION_MS 1000 +#endif + +#ifdef __cplusplus + } + #endif +#endif /* BSP_CFG_H_ */ diff --git a/hw/bsp/ra/boards/ra2a1_ek/fsp_cfg/bsp/bsp_mcu_device_cfg.h b/hw/bsp/ra/boards/ra2a1_ek/fsp_cfg/bsp/bsp_mcu_device_cfg.h new file mode 100644 index 000000000..eb82f4697 --- /dev/null +++ b/hw/bsp/ra/boards/ra2a1_ek/fsp_cfg/bsp/bsp_mcu_device_cfg.h @@ -0,0 +1,5 @@ +/* generated configuration header file - do not edit */ +#ifndef BSP_MCU_DEVICE_CFG_H_ +#define BSP_MCU_DEVICE_CFG_H_ +#define BSP_CFG_MCU_PART_SERIES (2) +#endif /* BSP_MCU_DEVICE_CFG_H_ */ diff --git a/hw/bsp/ra/boards/ra2a1_ek/fsp_cfg/bsp/bsp_mcu_device_pn_cfg.h b/hw/bsp/ra/boards/ra2a1_ek/fsp_cfg/bsp/bsp_mcu_device_pn_cfg.h new file mode 100644 index 000000000..710e85b28 --- /dev/null +++ b/hw/bsp/ra/boards/ra2a1_ek/fsp_cfg/bsp/bsp_mcu_device_pn_cfg.h @@ -0,0 +1,11 @@ +/* generated configuration header file - do not edit */ +#ifndef BSP_MCU_DEVICE_PN_CFG_H_ +#define BSP_MCU_DEVICE_PN_CFG_H_ +#define BSP_MCU_R7FA2A1AB3CFM +#define BSP_MCU_FEATURE_SET ('A') +#define BSP_ROM_SIZE_BYTES (262144) +#define BSP_RAM_SIZE_BYTES (32768) +#define BSP_DATA_FLASH_SIZE_BYTES (8192) +#define BSP_PACKAGE_LQFP +#define BSP_PACKAGE_PINS (64) +#endif /* BSP_MCU_DEVICE_PN_CFG_H_ */ diff --git a/hw/bsp/ra/boards/ra2a1_ek/fsp_cfg/bsp/bsp_mcu_family_cfg.h b/hw/bsp/ra/boards/ra2a1_ek/fsp_cfg/bsp/bsp_mcu_family_cfg.h new file mode 100644 index 000000000..6caef62cc --- /dev/null +++ b/hw/bsp/ra/boards/ra2a1_ek/fsp_cfg/bsp/bsp_mcu_family_cfg.h @@ -0,0 +1,84 @@ +/* generated configuration header file - do not edit */ +#ifndef BSP_MCU_FAMILY_CFG_H_ +#define BSP_MCU_FAMILY_CFG_H_ +#ifdef __cplusplus + extern "C" { + #endif + +#include "bsp_mcu_device_pn_cfg.h" +#include "bsp_mcu_device_cfg.h" +#include "../../../ra/fsp/src/bsp/mcu/ra2a1/bsp_mcu_info.h" +#include "bsp_clock_cfg.h" +#define BSP_MCU_GROUP_RA2A1 (1) +#define BSP_LOCO_HZ (32768) +#define BSP_MOCO_HZ (8000000) +#define BSP_SUB_CLOCK_HZ (32768) +#if BSP_CFG_HOCO_FREQUENCY == 0 +#define BSP_HOCO_HZ (24000000) +#elif BSP_CFG_HOCO_FREQUENCY == 2 + #define BSP_HOCO_HZ (32000000) + #elif BSP_CFG_HOCO_FREQUENCY == 4 + #define BSP_HOCO_HZ (48000000) + #elif BSP_CFG_HOCO_FREQUENCY == 5 + #define BSP_HOCO_HZ (64000000) + #else + #error "Invalid HOCO frequency chosen (BSP_CFG_HOCO_FREQUENCY) in bsp_clock_cfg.h" + #endif + +#define BSP_CORTEX_VECTOR_TABLE_ENTRIES (16U) +#define BSP_VECTOR_TABLE_MAX_ENTRIES (48U) + +#define OFS_SEQ1 0xA001A001 | (1 << 1) | (3 << 2) +#define OFS_SEQ2 (15 << 4) | (3 << 8) | (3 << 10) +#define OFS_SEQ3 (1 << 12) | (1 << 14) | (1 << 17) +#define OFS_SEQ4 (3 << 18) |(15 << 20) | (3 << 24) | (3 << 26) +#define OFS_SEQ5 (1 << 28) | (1 << 30) +#define BSP_CFG_USE_LOW_VOLTAGE_MODE ((0)) +#define BSP_CFG_ROM_REG_OFS0 (OFS_SEQ1 | OFS_SEQ2 | OFS_SEQ3 | OFS_SEQ4 | OFS_SEQ5) +#define BSP_CFG_ROM_REG_OFS1 (0xFFFFFEC3 | (1 << 2) | (3 << 3) | (0 << 8)) +#define BSP_CFG_ROM_REG_MPU_PC0_ENABLE (1) +#define BSP_CFG_ROM_REG_MPU_PC0_START (0x000FFFFC) +#define BSP_CFG_ROM_REG_MPU_PC0_END (0x000FFFFF) +#define BSP_CFG_ROM_REG_MPU_PC1_ENABLE (1) +#define BSP_CFG_ROM_REG_MPU_PC1_START (0x000FFFFC) +#define BSP_CFG_ROM_REG_MPU_PC1_END (0x000FFFFF) +#define BSP_CFG_ROM_REG_MPU_REGION0_ENABLE (1) +#define BSP_CFG_ROM_REG_MPU_REGION0_START (0x000FFFFC) +#define BSP_CFG_ROM_REG_MPU_REGION0_END (0x000FFFFF) +#define BSP_CFG_ROM_REG_MPU_REGION1_ENABLE (1) +#define BSP_CFG_ROM_REG_MPU_REGION1_START (0x200FFFFC) +#define BSP_CFG_ROM_REG_MPU_REGION1_END (0x200FFFFF) +#define BSP_CFG_ROM_REG_MPU_REGION2_ENABLE (1) +#define BSP_CFG_ROM_REG_MPU_REGION2_START (0x407FFFFC) +#define BSP_CFG_ROM_REG_MPU_REGION2_END (0x407FFFFF) +#define BSP_CFG_ROM_REG_MPU_REGION3_ENABLE (1) +#define BSP_CFG_ROM_REG_MPU_REGION3_START (0x400DFFFC) +#define BSP_CFG_ROM_REG_MPU_REGION3_END (0x400DFFFF) +#ifndef BSP_CLOCK_CFG_MAIN_OSC_WAIT +#define BSP_CLOCK_CFG_MAIN_OSC_WAIT (9) +#endif +/* Used to create IELS values for the interrupt initialization table g_interrupt_event_link_select. */ +#define BSP_PRV_IELS_ENUM(vector) (ELC_ ## vector) + +/* + ID Code + Note: To permanently lock and disable the debug interface define the BSP_ID_CODE_PERMANENTLY_LOCKED in the compiler settings. + WARNING: This will disable debug access to the part and cannot be reversed by a debug probe. + */ +#if defined(BSP_ID_CODE_PERMANENTLY_LOCKED) + #define BSP_CFG_ID_CODE_LONG_1 (0x00000000) + #define BSP_CFG_ID_CODE_LONG_2 (0x00000000) + #define BSP_CFG_ID_CODE_LONG_3 (0x00000000) + #define BSP_CFG_ID_CODE_LONG_4 (0x00000000) + #else +/* ID CODE: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF */ +#define BSP_CFG_ID_CODE_LONG_1 (0xFFFFFFFF) +#define BSP_CFG_ID_CODE_LONG_2 (0xFFFFFFFF) +#define BSP_CFG_ID_CODE_LONG_3 (0xFFFFFFFF) +#define BSP_CFG_ID_CODE_LONG_4 (0xffFFFFFF) +#endif + +#ifdef __cplusplus + } + #endif +#endif /* BSP_MCU_FAMILY_CFG_H_ */ diff --git a/hw/bsp/ra/boards/ra2a1_ek/fsp_cfg/bsp_clock_cfg.h b/hw/bsp/ra/boards/ra2a1_ek/fsp_cfg/bsp_clock_cfg.h new file mode 100644 index 000000000..cd9d135f7 --- /dev/null +++ b/hw/bsp/ra/boards/ra2a1_ek/fsp_cfg/bsp_clock_cfg.h @@ -0,0 +1,17 @@ +/* generated configuration header file - do not edit */ +#ifndef BSP_CLOCK_CFG_H_ +#define BSP_CLOCK_CFG_H_ +#define BSP_CFG_CLOCKS_SECURE (0) +#define BSP_CFG_CLOCKS_OVERRIDE (0) +#define BSP_CFG_XTAL_HZ (12000000) /* XTAL 12000000Hz */ +#define BSP_CFG_HOCO_FREQUENCY (4) /* HOCO 48MHz */ +#define BSP_CFG_CLOCK_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_HOCO) /* Clock Src: HOCO */ +#define BSP_CFG_ICLK_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* ICLK Div /1 */ +#define BSP_CFG_PCLKB_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_2) /* PCLKB Div /2 */ +#define BSP_CFG_PCLKD_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_2) /* PCLKD Div /2 */ +#define BSP_CFG_FCLK_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_2) /* FCLK Div /2 */ +#define BSP_CFG_SDADC_CLOCK_SOURCE (0) /* SDADCCLK Src: HOCO */ +#define BSP_CFG_SDADCCLK_DIV (7) /* SDADCCLK Div /12 */ +#define BSP_CFG_CLKOUT_SOURCE (BSP_CLOCKS_CLOCK_DISABLED) /* CLKOUT Disabled */ +#define BSP_CFG_CLKOUT_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* CLKOUT Div /1 */ +#endif /* BSP_CLOCK_CFG_H_ */ diff --git a/hw/bsp/ra/boards/ra4m1_ek/board.cmake b/hw/bsp/ra/boards/ra4m1_ek/board.cmake index 4188d3188..7bb48bf44 100644 --- a/hw/bsp/ra/boards/ra4m1_ek/board.cmake +++ b/hw/bsp/ra/boards/ra4m1_ek/board.cmake @@ -4,7 +4,9 @@ set(MCU_VARIANT ra4m1) set(JLINK_DEVICE R7FA4M1AB) function(update_board TARGET) -# target_compile_definitions(${TARGET} PUBLIC) + target_compile_definitions(${TARGET} PUBLIC + CFG_EXAMPLE_VIDEO_READONLY + ) # target_sources(${TARGET} PRIVATE) # target_include_directories(${BOARD_TARGET} PUBLIC) endfunction() diff --git a/hw/bsp/ra/boards/uno_r4/board.cmake b/hw/bsp/ra/boards/uno_r4/board.cmake index 34780d776..9d59bc4f7 100644 --- a/hw/bsp/ra/boards/uno_r4/board.cmake +++ b/hw/bsp/ra/boards/uno_r4/board.cmake @@ -5,7 +5,9 @@ set(JLINK_DEVICE R7FA4M1AB) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) function(update_board TARGET) -# target_compile_definitions(${TARGET} PUBLIC) + target_compile_definitions(${TARGET} PUBLIC + CFG_EXAMPLE_VIDEO_READONLY + ) # target_sources(${TARGET} PRIVATE) # target_include_directories(${BOARD_TARGET} PUBLIC) endfunction() diff --git a/hw/bsp/ra/family.c b/hw/bsp/ra/family.c index 0aa58d86d..db8988a36 100644 --- a/hw/bsp/ra/family.c +++ b/hw/bsp/ra/family.c @@ -64,8 +64,11 @@ BSP_DONT_REMOVE BSP_PLACE_IN_SECTION(BSP_SECTION_APPLICATION_VECTORS) const fsp_vector_t g_vector_table[BSP_ICU_VECTOR_MAX_ENTRIES] = { [0] = usbfs_interrupt_handler, /* USBFS INT (USBFS interrupt) */ [1] = usbfs_resume_handler, /* USBFS RESUME (USBFS resume interrupt) */ + +#ifndef BSP_MCU_GROUP_RA2A1 [2] = usbfs_d0fifo_handler, /* USBFS FIFO 0 (DMA transfer request 0) */ [3] = usbfs_d1fifo_handler, /* USBFS FIFO 1 (DMA transfer request 1) */ +#endif #ifdef BOARD_HAS_USB_HIGHSPEED [4] = usbhs_interrupt_handler, /* USBHS INT (USBHS interrupt) */ @@ -77,8 +80,11 @@ const fsp_vector_t g_vector_table[BSP_ICU_VECTOR_MAX_ENTRIES] = { const bsp_interrupt_event_t g_interrupt_event_link_select[BSP_ICU_VECTOR_MAX_ENTRIES] = { [0] = BSP_PRV_IELS_ENUM(EVENT_USBFS_INT), /* USBFS INT (USBFS interrupt) */ [1] = BSP_PRV_IELS_ENUM(EVENT_USBFS_RESUME), /* USBFS RESUME (USBFS resume interrupt) */ + +#ifndef BSP_MCU_GROUP_RA2A1 [2] = BSP_PRV_IELS_ENUM(EVENT_USBFS_FIFO_0), /* USBFS FIFO 0 (DMA transfer request 0) */ [3] = BSP_PRV_IELS_ENUM(EVENT_USBFS_FIFO_1), /* USBFS FIFO 1 (DMA transfer request 1) */ +#endif #ifdef BOARD_HAS_USB_HIGHSPEED [4] = BSP_PRV_IELS_ENUM(EVENT_USBHS_USB_INT_RESUME), /* USBHS USB INT RESUME (USBHS interrupt) */ @@ -188,7 +194,7 @@ void usbfs_interrupt_handler(void) { R_BSP_IrqStatusClear(irq); #if PORT_SUPPORT_HOST(0) - tuh_int_handler(0); + tuh_int_handler(0, true); #endif #if PORT_SUPPORT_DEVICE(0) @@ -201,7 +207,7 @@ void usbfs_resume_handler(void) { R_BSP_IrqStatusClear(irq); #if PORT_SUPPORT_HOST(0) - tuh_int_handler(0); + tuh_int_handler(0, true); #endif #if PORT_SUPPORT_DEVICE(0) @@ -229,7 +235,7 @@ void usbhs_interrupt_handler(void) { R_BSP_IrqStatusClear(irq); #if PORT_SUPPORT_HOST(1) - tuh_int_handler(1); + tuh_int_handler(1, true); #endif #if PORT_SUPPORT_DEVICE(1) diff --git a/hw/bsp/ra/family.cmake b/hw/bsp/ra/family.cmake index 11bc7c668..426e1ca8f 100644 --- a/hw/bsp/ra/family.cmake +++ b/hw/bsp/ra/family.cmake @@ -11,7 +11,7 @@ set(FSP_RA ${TOP}/hw/mcu/renesas/fsp/ra/fsp) include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) #set(FREERTOS_PORT A_CUSTOM_PORT CACHE INTERNAL "") -set(CMAKE_TOOLCHAIN_FILE ${TOP}/tools/cmake/toolchain/arm_${TOOLCHAIN}.cmake) +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS RAXXX ${MCU_VARIANT} CACHE INTERNAL "") diff --git a/hw/bsp/ra/family.mk b/hw/bsp/ra/family.mk index 9afb38e06..4447e8499 100644 --- a/hw/bsp/ra/family.mk +++ b/hw/bsp/ra/family.mk @@ -31,6 +31,8 @@ else $(info "Using PORT 0 FullSpeed") endif +LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs + SRC_C += \ src/portable/renesas/rusb2/dcd_rusb2.c \ src/portable/renesas/rusb2/hcd_rusb2.c \ diff --git a/hw/bsp/ra/linker/gcc/ra2a1.ld b/hw/bsp/ra/linker/gcc/ra2a1.ld new file mode 100644 index 000000000..218acbb2a --- /dev/null +++ b/hw/bsp/ra/linker/gcc/ra2a1.ld @@ -0,0 +1,22 @@ +RAM_START = 0x20000000; +RAM_LENGTH = 0x8000; +FLASH_START = 0x00000000; +FLASH_LENGTH = 0x40000; +DATA_FLASH_START = 0x40100000; +DATA_FLASH_LENGTH = 0x2000; +OPTION_SETTING_START = 0x00000000; +OPTION_SETTING_LENGTH = 0x0; +OPTION_SETTING_S_START = 0x80000000; +OPTION_SETTING_S_LENGTH = 0x0; +ID_CODE_START = 0x01010018; +ID_CODE_LENGTH = 0x20; +SDRAM_START = 0x80010000; +SDRAM_LENGTH = 0x0; +QSPI_FLASH_START = 0x60000000; +QSPI_FLASH_LENGTH = 0x0; +OSPI_DEVICE_0_START = 0x80020000; +OSPI_DEVICE_0_LENGTH = 0x0; +OSPI_DEVICE_1_START = 0x80030000; +OSPI_DEVICE_1_LENGTH = 0x0; + +INCLUDE fsp.ld diff --git a/hw/bsp/ra/vector_data.h b/hw/bsp/ra/vector_data.h index ca667faa3..2b3b7d837 100644 --- a/hw/bsp/ra/vector_data.h +++ b/hw/bsp/ra/vector_data.h @@ -9,8 +9,11 @@ extern "C" { /* ISR prototypes */ void usbfs_interrupt_handler(void); void usbfs_resume_handler(void); + +#ifndef BSP_MCU_GROUP_RA2A1 void usbfs_d0fifo_handler(void); void usbfs_d1fifo_handler(void); +#endif #ifdef BOARD_HAS_USB_HIGHSPEED void usbhs_interrupt_handler(void); diff --git a/hw/bsp/rp2040/board.h b/hw/bsp/rp2040/board.h index 063c9580e..3849894ce 100644 --- a/hw/bsp/rp2040/board.h +++ b/hw/bsp/rp2040/board.h @@ -74,6 +74,17 @@ #define PICO_DEFAULT_PIO_USB_VBUSEN_STATE 1 #endif +//-------------------------------------------------------------------- +// USB Host MAX3421E +//-------------------------------------------------------------------- + +#define MAX3421_SPI PICO_DEFAULT_SPI_INSTANCE +#define MAX3421_SCK_PIN PICO_DEFAULT_SPI_SCK_PIN +#define MAX3421_MOSI_PIN PICO_DEFAULT_SPI_TX_PIN +#define MAX3421_MISO_PIN PICO_DEFAULT_SPI_RX_PIN +#define MAX3421_CS_PIN 10 +#define MAX3421_INTR_PIN 9 + #ifdef __cplusplus } #endif diff --git a/hw/bsp/rp2040/boards/feather_rp2040_max3421/board.cmake b/hw/bsp/rp2040/boards/feather_rp2040_max3421/board.cmake new file mode 100644 index 000000000..b8e5890f3 --- /dev/null +++ b/hw/bsp/rp2040/boards/feather_rp2040_max3421/board.cmake @@ -0,0 +1,4 @@ +set(PICO_BOARD adafruit_feather_rp2040) + +# Enable MAX3421E USB Host +set(MAX3421_HOST 1) diff --git a/hw/bsp/rp2040/family.c b/hw/bsp/rp2040/family.c index aa9d00c23..cffb632f3 100644 --- a/hw/bsp/rp2040/family.c +++ b/hw/bsp/rp2040/family.c @@ -30,16 +30,26 @@ #include "pico/unique_id.h" #include "hardware/gpio.h" #include "hardware/sync.h" +#include "hardware/resets.h" #include "hardware/structs/ioqspi.h" #include "hardware/structs/sio.h" #include "bsp/board_api.h" #include "board.h" +#ifdef UART_DEV +static uart_inst_t *uart_inst; +#endif + #if CFG_TUH_RPI_PIO_USB || CFG_TUD_RPI_PIO_USB #include "pio_usb.h" #endif +#if CFG_TUH_ENABLED && CFG_TUH_MAX3421 +#include "hardware/spi.h" +static void max3421_init(void); +#endif + #ifdef BUTTON_BOOTSEL // This example blinks the Picoboard LED when the BOOTSEL button is pressed. // @@ -52,73 +62,66 @@ // This doesn't work if others are trying to access flash at the same time, // e.g. XIP streamer, or the other core. bool __no_inline_not_in_flash_func(get_bootsel_button)(void) { - const uint CS_PIN_INDEX = 1; + const uint CS_PIN_INDEX = 1; - // Must disable interrupts, as interrupt handlers may be in flash, and we - // are about to temporarily disable flash access! - uint32_t flags = save_and_disable_interrupts(); + // Must disable interrupts, as interrupt handlers may be in flash, and we + // are about to temporarily disable flash access! + uint32_t flags = save_and_disable_interrupts(); - // Set chip select to Hi-Z - hw_write_masked(&ioqspi_hw->io[CS_PIN_INDEX].ctrl, - GPIO_OVERRIDE_LOW << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB, - IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS); + // Set chip select to Hi-Z + hw_write_masked(&ioqspi_hw->io[CS_PIN_INDEX].ctrl, + GPIO_OVERRIDE_LOW << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB, + IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS); - // Note we can't call into any sleep functions in flash right now - for (volatile int i = 0; i < 1000; ++i); + // Note we can't call into any sleep functions in flash right now + for (volatile int i = 0; i < 1000; ++i); - // The HI GPIO registers in SIO can observe and control the 6 QSPI pins. - // Note the button pulls the pin *low* when pressed. - bool button_state = (sio_hw->gpio_hi_in & (1u << CS_PIN_INDEX)); + // The HI GPIO registers in SIO can observe and control the 6 QSPI pins. + // Note the button pulls the pin *low* when pressed. + bool button_state = (sio_hw->gpio_hi_in & (1u << CS_PIN_INDEX)); - // Need to restore the state of chip select, else we are going to have a - // bad time when we return to code in flash! - hw_write_masked(&ioqspi_hw->io[CS_PIN_INDEX].ctrl, - GPIO_OVERRIDE_NORMAL << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB, - IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS); + // Need to restore the state of chip select, else we are going to have a + // bad time when we return to code in flash! + hw_write_masked(&ioqspi_hw->io[CS_PIN_INDEX].ctrl, + GPIO_OVERRIDE_NORMAL << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB, + IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS); - restore_interrupts(flags); + restore_interrupts(flags); - return button_state; + return button_state; } #endif //------------- Segger RTT retarget -------------// #if defined(LOGGER_RTT) - // Logging with RTT // - If RTT Control Block is not found by 'Auto Detection` try to use 'Search Range` with '0x20000000 0x10000' // - SWD speed is rather slow around 1000Khz - #include "pico/stdio/driver.h" #include "SEGGER_RTT.h" -static void stdio_rtt_write (const char *buf, int length) -{ +static void stdio_rtt_write (const char *buf, int length) { SEGGER_RTT_Write(0, buf, (unsigned) length); } -static int stdio_rtt_read (char *buf, int len) -{ +static int stdio_rtt_read (char *buf, int len) { return (int) SEGGER_RTT_Read(0, buf, (unsigned) len); } -static stdio_driver_t stdio_rtt = -{ +static stdio_driver_t stdio_rtt = { .out_chars = stdio_rtt_write, .out_flush = NULL, .in_chars = stdio_rtt_read }; -void stdio_rtt_init(void) -{ +void stdio_rtt_init(void) { stdio_set_driver_enabled(&stdio_rtt, true); } - #endif -#ifdef UART_DEV -static uart_inst_t *uart_inst; -#endif +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ void board_init(void) { @@ -164,7 +167,15 @@ void board_init(void) #endif #if CFG_TUH_ENABLED - // set portfunc to host !!! + #if CFG_TUH_MAX3421 + max3421_init(); + #endif +#endif + +#if !CFG_TUD_ENABLED && !CFG_TUH_ENABLED + // board test exxample, reset usb controller + reset_block(RESETS_RESET_USBCTRL_BITS); + unreset_block_wait(RESETS_RESET_USBCTRL_BITS); #endif } @@ -235,3 +246,69 @@ int board_getchar(void) { // rp2040 implementation will install appropriate handler when initializing // tinyusb. There is no need to forward IRQ from application //--------------------------------------------------------------------+ + +//--------------------------------------------------------------------+ +// API: SPI transfer with MAX3421E, must be implemented by application +//--------------------------------------------------------------------+ +#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 + +void max3421_int_handler(uint gpio, uint32_t event_mask) { + if (!(gpio == MAX3421_INTR_PIN && event_mask & GPIO_IRQ_EDGE_FALL)) return; + tuh_int_handler(BOARD_TUH_RHPORT, true); +} + +static void max3421_init(void) { + // CS pin + gpio_init(MAX3421_CS_PIN); + gpio_set_dir(MAX3421_CS_PIN, GPIO_OUT); + gpio_put(MAX3421_CS_PIN, true); + + // Interrupt pin + gpio_init(MAX3421_INTR_PIN); + gpio_set_dir(MAX3421_INTR_PIN, GPIO_IN); + gpio_pull_up(MAX3421_INTR_PIN); + gpio_set_irq_enabled_with_callback(MAX3421_INTR_PIN, GPIO_IRQ_EDGE_FALL, true, max3421_int_handler); + + // SPI init + spi_init(MAX3421_SPI, 4*1000000ul); + gpio_set_function(MAX3421_SCK_PIN, GPIO_FUNC_SPI); + gpio_set_function(MAX3421_MOSI_PIN, GPIO_FUNC_SPI); + gpio_set_function(MAX3421_MISO_PIN, GPIO_FUNC_SPI); + spi_set_format(MAX3421_SPI, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST); +} + +//// API to enable/disable MAX3421 INTR pin interrupt +void tuh_max3421_int_api(uint8_t rhport, bool enabled) { + (void) rhport; + irq_set_enabled(IO_IRQ_BANK0, enabled); +} + +// API to control MAX3421 SPI CS +void tuh_max3421_spi_cs_api(uint8_t rhport, bool active) { + (void) rhport; + gpio_put(MAX3421_CS_PIN, !active); +} + +// API to transfer data with MAX3421 SPI +// Either tx_buf or rx_buf can be NULL, which means transfer is write or read only +bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const* tx_buf, uint8_t* rx_buf, size_t xfer_bytes) { + (void) rhport; + + if (tx_buf == NULL && rx_buf == NULL) { + return false; + } + + int ret; + + if (tx_buf == NULL) { + ret = spi_read_blocking(MAX3421_SPI, 0, rx_buf, xfer_bytes); + }else if (rx_buf == NULL) { + ret = spi_write_blocking(MAX3421_SPI, tx_buf, xfer_bytes); + }else { + ret = spi_write_read_blocking(spi0, tx_buf, rx_buf, xfer_bytes); + } + + return ret == (int) xfer_bytes; +} + +#endif diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index 53e2add56..b41d7fbea 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -6,12 +6,19 @@ if (NOT BOARD) set(BOARD pico_sdk) endif() +if (TOOLCHAIN STREQUAL "clang") + set(PICO_COMPILER "pico_arm_clang") +else() + set(PICO_COMPILER "pico_arm_gcc") +endif() + # add the SDK in case we are standalone tinyusb example (noop if already present) include(${CMAKE_CURRENT_LIST_DIR}/pico_sdk_import.cmake) # include basic family CMake functionality set(FAMILY_MCUS RP2040) set(JLINK_DEVICE rp2040_m0_0) +set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -f target/rp2040.cfg -c \"adapter speed 5000\"") include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) @@ -29,13 +36,13 @@ endif() add_library(tinyusb_common_base INTERFACE) target_sources(tinyusb_common_base INTERFACE - ${TOP}/src/tusb.c - ${TOP}/src/common/tusb_fifo.c - ) + ${TOP}/src/tusb.c + ${TOP}/src/common/tusb_fifo.c + ) target_include_directories(tinyusb_common_base INTERFACE - ${TOP}/src - ) + ${TOP}/src + ) if(DEFINED LOG) set(TINYUSB_DEBUG_LEVEL ${LOG}) @@ -47,9 +54,9 @@ else () endif() target_compile_definitions(tinyusb_common_base INTERFACE - CFG_TUSB_MCU=OPT_MCU_RP2040 - CFG_TUSB_OS=${TINYUSB_OPT_OS} - CFG_TUSB_DEBUG=${TINYUSB_DEBUG_LEVEL} + CFG_TUSB_MCU=OPT_MCU_RP2040 + CFG_TUSB_OS=${TINYUSB_OPT_OS} + CFG_TUSB_DEBUG=${TINYUSB_DEBUG_LEVEL} ) target_link_libraries(tinyusb_common_base INTERFACE @@ -102,6 +109,20 @@ target_compile_definitions(tinyusb_host_base INTERFACE RP2040_USB_HOST_MODE=1 ) +#------------------------------------ +# Host MAX3421 +#------------------------------------ +add_library(tinyusb_host_max3421 INTERFACE) +target_sources(tinyusb_host_max3421 INTERFACE + ${TOP}/src/portable/analog/max3421/hcd_max3421.c + ) +target_compile_definitions(tinyusb_host_max3421 INTERFACE + CFG_TUH_MAX3421=1 + ) +target_link_libraries(tinyusb_host_max3421 INTERFACE + hardware_spi + ) + #------------------------------------ # BSP & Additions #------------------------------------ @@ -125,7 +146,7 @@ target_compile_definitions(tinyusb_additions INTERFACE if(LOGGER STREQUAL "RTT" OR LOGGER STREQUAL "rtt") target_compile_definitions(tinyusb_additions INTERFACE LOGGER_RTT - SEGGER_RTT_MODE_DEFAULT=SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL + #SEGGER_RTT_MODE_DEFAULT=SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL ) target_sources(tinyusb_additions INTERFACE @@ -156,8 +177,9 @@ function(family_configure_target TARGET RTOS) pico_add_extra_outputs(${TARGET}) pico_enable_stdio_uart(${TARGET} 1) - target_link_libraries(${TARGET} PUBLIC pico_stdlib pico_bootsel_via_double_reset tinyusb_board${RTOS_SUFFIX} tinyusb_additions) + target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_board${RTOS_SUFFIX} tinyusb_additions) + family_flash_openocd(${TARGET}) family_flash_jlink(${TARGET}) endfunction() @@ -184,6 +206,7 @@ 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) @@ -207,6 +230,11 @@ function(family_configure_host_example TARGET RTOS) family_add_pico_pio_usb(${PROJECT}) endif() endif() + + # for max3421 host + if (MAX3421_HOST STREQUAL "1") + target_link_libraries(${TARGET} PUBLIC tinyusb_host_max3421) + endif() endfunction() diff --git a/hw/bsp/rx/boards/gr_citrus/gr_citrus.c b/hw/bsp/rx/boards/gr_citrus/gr_citrus.c index 5078c7569..26ad4a6aa 100644 --- a/hw/bsp/rx/boards/gr_citrus/gr_citrus.c +++ b/hw/bsp/rx/boards/gr_citrus/gr_citrus.c @@ -203,9 +203,10 @@ void board_init(void) IEN(SCI0, TEI0) = 1; /* Enable USB0 */ + unsigned short oldPRCR = SYSTEM.PRCR.WORD; SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY | SYSTEM_PRCR_PRC1; MSTP(USB0) = 0; - SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY; + SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY | oldPRCR; } //--------------------------------------------------------------------+ diff --git a/hw/bsp/rx/boards/rx65n_target/rx65n_target.c b/hw/bsp/rx/boards/rx65n_target/rx65n_target.c index 513eca678..66a319541 100644 --- a/hw/bsp/rx/boards/rx65n_target/rx65n_target.c +++ b/hw/bsp/rx/boards/rx65n_target/rx65n_target.c @@ -177,7 +177,7 @@ void INT_Excep_SCI5_RXI5(void) void INT_Excep_USB0_USBI0(void) { #if CFG_TUH_ENABLED - tuh_int_handler(0); + tuh_int_handler(0, true); #endif #if CFG_TUD_ENABLED tud_int_handler(0); @@ -249,9 +249,10 @@ void board_init(void) EN(SCI5, TEI5) = 1; /* Enable USB0 */ + unsigned short oldPRCR = SYSTEM.PRCR.WORD; SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY | SYSTEM_PRCR_PRC1; MSTP(USB0) = 0; - SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY; + SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY | oldPRCR; /* setup USBI0 interrupt. */ IR(USB0, USBI0) = 0; @@ -277,6 +278,7 @@ int board_uart_read(uint8_t* buf, int len) sci_buf[1].buf = buf; sci_buf[1].cnt = len; SCI5.SCR.BYTE |= SCI_SCR_RE | SCI_SCR_RIE; + // TODO change to non blocking, return -1 immediately if no data while (SCI5.SCR.BIT.RE) ; return len - sci_buf[1].cnt; } diff --git a/hw/bsp/rx/family.mk b/hw/bsp/rx/family.mk index 3044167b9..02ea0dfa4 100644 --- a/hw/bsp/rx/family.mk +++ b/hw/bsp/rx/family.mk @@ -16,6 +16,8 @@ CFLAGS += \ # suppress warning caused by vendor mcu driver CFLAGS += -Wno-error=redundant-decls +LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs + SRC_C += \ src/portable/renesas/rusb2/dcd_rusb2.c \ src/portable/renesas/rusb2/hcd_rusb2.c \ diff --git a/hw/bsp/samd11/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/samd11/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..6c9ecae2d --- /dev/null +++ b/hw/bsp/samd11/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,153 @@ +/* + * 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 "sam.h" +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#if defined(__ARM_FP) && __ARM_FP >= 4 + #define configENABLE_FPU 1 +#else + #define configENABLE_FPU 0 +#endif +#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 4 +#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 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* 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 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* 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 + +/* 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 2 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<= 4 + #define configENABLE_FPU 1 +#else + #define configENABLE_FPU 0 +#endif +#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 4 +#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 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* 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 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* 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 + +/* 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 2 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< rom + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + PROVIDE_HIDDEN (__exidx_start = .); + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > rom + PROVIDE_HIDDEN (__exidx_end = .); + + . = ALIGN(4); + _etext = .; + + .relocate : AT (_etext) + { + . = ALIGN(4); + _srelocate = .; + *(.ramfunc .ramfunc.*); + *(.data .data.*); + . = ALIGN(4); + _erelocate = .; + } > ram + + /* .bss section which is used for uninitialized data */ + .bss (NOLOAD) : + { + . = ALIGN(4); + _sbss = . ; + _szero = .; + *(.bss .bss.*) + *(COMMON) + . = ALIGN(4); + _ebss = . ; + _ezero = .; + end = .; + } > ram + + /* stack section */ + .stack (NOLOAD): + { + . = ALIGN(8); + _sstack = .; + . = . + STACK_SIZE; + . = ALIGN(8); + _estack = .; + } > ram + + . = ALIGN(4); + _end = . ; +} diff --git a/hw/bsp/samd21/boards/trinket_m0/board.cmake b/hw/bsp/samd21/boards/trinket_m0/board.cmake new file mode 100644 index 000000000..f6cd446dd --- /dev/null +++ b/hw/bsp/samd21/boards/trinket_m0/board.cmake @@ -0,0 +1,9 @@ +set(JLINK_DEVICE ATSAMD21E18) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAMD21E18A__ + CFG_EXAMPLE_VIDEO_READONLY + ) +endfunction() diff --git a/hw/bsp/samd21/boards/trinket_m0/board.h b/hw/bsp/samd21/boards/trinket_m0/board.h index 741f2a7f3..c94a3abb6 100644 --- a/hw/bsp/samd21/boards/trinket_m0/board.h +++ b/hw/bsp/samd21/boards/trinket_m0/board.h @@ -31,3 +31,5 @@ // UART #define UART_SERCOM 0 +#define UART_RX_PIN 7 +#define UART_TX_PIN 6 diff --git a/hw/bsp/samd21/boards/trinket_m0/trinket_m0.ld b/hw/bsp/samd21/boards/trinket_m0/trinket_m0.ld index f0c93340c..ce7aff80b 100644 --- a/hw/bsp/samd21/boards/trinket_m0/trinket_m0.ld +++ b/hw/bsp/samd21/boards/trinket_m0/trinket_m0.ld @@ -40,7 +40,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x2000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; ENTRY(Reset_Handler) diff --git a/hw/bsp/samd21/family.c b/hw/bsp/samd21/family.c index 46297f97f..7ca20c458 100644 --- a/hw/bsp/samd21/family.c +++ b/hw/bsp/samd21/family.c @@ -28,6 +28,12 @@ #include "bsp/board_api.h" #include "board.h" +// Suppress warning caused by mcu driver +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" +#endif + #include "hal/include/hal_gpio.h" #include "hal/include/hal_init.h" #include "hri/hri_nvmctrl_d21.h" @@ -36,18 +42,9 @@ #include "hpl_pm_config.h" #include "hpl/pm/hpl_pm_base.h" -//--------------------------------------------------------------------+ -// Forward USB interrupt events to TinyUSB IRQ Handler -//--------------------------------------------------------------------+ -void USB_Handler(void) -{ - tud_int_handler(0); -} - -//--------------------------------------------------------------------+ -// UART support -//--------------------------------------------------------------------+ -static void uart_init(void); +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION @@ -59,8 +56,26 @@ static void uart_init(void); /* Not referenced GCLKs, initialized last */ #define _GCLK_INIT_LAST (~_GCLK_INIT_1ST) -void board_init(void) -{ +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void USB_Handler(void) { + tud_int_handler(0); +} + +//--------------------------------------------------------------------+ +// Implementation +//--------------------------------------------------------------------+ +static void uart_init(void); + +#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 +#define MAX3421_SERCOM TU_XSTRCAT(SERCOM, MAX3421_SERCOM_ID) + +static void max3421_init(void); + +#endif + +void board_init(void) { // Clock init ( follow hpl_init.c ) hri_nvmctrl_set_CTRLB_RWS_bf(NVMCTRL, 2); @@ -75,7 +90,7 @@ void board_init(void) // Update SystemCoreClock since it is hard coded with asf4 and not correct // Init 1ms tick timer (samd SystemCoreClock may not correct) SystemCoreClock = CONF_CPU_FREQUENCY; -#if CFG_TUSB_OS == OPT_OS_NONE +#if CFG_TUSB_OS == OPT_OS_NONE SysTick_Config(CONF_CPU_FREQUENCY / 1000); #endif @@ -93,7 +108,7 @@ void board_init(void) uart_init(); -#if CFG_TUSB_OS == OPT_OS_FREERTOS +#if CFG_TUSB_OS == OPT_OS_FREERTOS // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif @@ -124,22 +139,24 @@ void board_init(void) gpio_set_pin_function(PIN_PA19, PINMUX_PA19F_TCC0_WO3); _gclk_enable_channel(TCC0_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK0_Val); + +#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 + max3421_init(); +#endif } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ -void board_led_write(bool state) -{ - (void)state; +void board_led_write(bool state) { + (void) state; #ifdef LED_PIN - gpio_set_pin_level(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); + gpio_set_pin_level(LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); #endif } -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { #ifdef BUTTON_PIN return BUTTON_STATE_ACTIVE == gpio_get_pin_level(BUTTON_PIN); #else @@ -155,8 +172,21 @@ uint32_t board_button_read(void) static void uart_init(void) { #if UART_SERCOM == 0 - gpio_set_pin_function(PIN_PA06, PINMUX_PA06D_SERCOM0_PAD2); - gpio_set_pin_function(PIN_PA07, PINMUX_PA07D_SERCOM0_PAD3); + #if UART_TX_PIN == 6 + gpio_set_pin_function(PIN_PA06, PINMUX_PA06D_SERCOM0_PAD2); + #elif UART_TX_PIN == 10 + gpio_set_pin_function(PIN_PA10, PINMUX_PA10C_SERCOM0_PAD2); + #else + #error "UART_TX_PIN not supported" + #endif + + #if UART_RX_PIN == 7 + gpio_set_pin_function(PIN_PA07, PINMUX_PA07D_SERCOM0_PAD3); + #elif UART_RX_PIN == 11 + gpio_set_pin_function(PIN_PA11, PINMUX_PA11C_SERCOM0_PAD3); + #else + #error "UART_RX_PIN not supported" +#endif // setup clock (48MHz) _pm_enable_bus_clock(PM_BUS_APBC, SERCOM0); @@ -177,6 +207,7 @@ static void uart_init(void) SERCOM_USART_CTRLB_TXEN | /* tx enabled */ SERCOM_USART_CTRLB_RXEN; /* rx enabled */ + /* 115200 */ SERCOM0->USART.BAUD.reg = SERCOM_USART_BAUD_FRAC_FP(0) | SERCOM_USART_BAUD_FRAC_BAUD(26); SERCOM0->USART.CTRLA.bit.ENABLE = 1; /* activate SERCOM */ @@ -217,33 +248,191 @@ int board_uart_write(void const * buf, int len) } #else // ! defined(UART_SERCOM) -static void uart_init(void) -{ +static void uart_init(void) { } -int board_uart_read(uint8_t* buf, int len) -{ - (void) buf; (void) len; +int board_uart_read(uint8_t* buf, int len) { + (void) buf; + (void) len; return 0; } -int board_uart_write(void const * buf, int len) -{ - (void) buf; (void) len; +int board_uart_write(void const* buf, int len) { + (void) buf; + (void) len; return 0; } + #endif -#if CFG_TUSB_OS == OPT_OS_NONE +#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 + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ +#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 + +static void max3421_init(void) { + //------------- SPI Init -------------// + // MAX3421E max SPI clock is 26MHz however SAMD can only work reliably at 12 Mhz + uint32_t const baudrate = 12000000u; + + // Enable the APB clock for SERCOM + PM->APBCMASK.reg |= 1u << (PM_APBCMASK_SERCOM0_Pos + MAX3421_SERCOM_ID); + + // Configure GCLK for SERCOM +// GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_SERCOM4_CORE | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_CLKEN; + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(GCLK_CLKCTRL_ID_SERCOM0_CORE_Val + MAX3421_SERCOM_ID) | + GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_CLKEN; + while (GCLK->STATUS.bit.SYNCBUSY); + + Sercom* sercom = MAX3421_SERCOM; + + // Disable the SPI module + sercom->SPI.CTRLA.bit.ENABLE = 0; + + // Reset the SPI module + sercom->SPI.CTRLA.bit.SWRST = 1; + while (sercom->SPI.SYNCBUSY.bit.SWRST); + + // Set up SPI in master mode, MSB first, SPI mode 0 + sercom->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_DOPO(MAX3421_TX_PAD) | SERCOM_SPI_CTRLA_DIPO(MAX3421_RX_PAD) | + SERCOM_SPI_CTRLA_MODE(3); + + sercom->SPI.CTRLB.reg = SERCOM_SPI_CTRLB_CHSIZE(0) | SERCOM_SPI_CTRLB_RXEN; + while (sercom->SPI.SYNCBUSY.bit.CTRLB == 1); + + // Set the baud rate + sercom->SPI.BAUD.reg = (uint8_t) (SystemCoreClock / (2 * baudrate) - 1); + + // Configure PA12 as MOSI (PAD0), PA13 as SCK (PAD1), PA14 as MISO (PAD2), function C (sercom) + gpio_set_pin_direction(MAX3421_SCK_PIN, GPIO_DIRECTION_OUT); + gpio_set_pin_pull_mode(MAX3421_SCK_PIN, GPIO_PULL_OFF); + gpio_set_pin_function(MAX3421_SCK_PIN, MAX3421_SERCOM_FUNCTION); + + gpio_set_pin_direction(MAX3421_MOSI_PIN, GPIO_DIRECTION_OUT); + gpio_set_pin_pull_mode(MAX3421_MOSI_PIN, GPIO_PULL_OFF); + gpio_set_pin_function(MAX3421_MOSI_PIN, MAX3421_SERCOM_FUNCTION); + + gpio_set_pin_direction(MAX3421_MISO_PIN, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(MAX3421_MISO_PIN, GPIO_PULL_OFF); + gpio_set_pin_function(MAX3421_MISO_PIN, MAX3421_SERCOM_FUNCTION); + + // CS pin + gpio_set_pin_direction(MAX3421_CS_PIN, GPIO_DIRECTION_OUT); + gpio_set_pin_level(MAX3421_CS_PIN, 1); + + // Enable the SPI module + sercom->SPI.CTRLA.bit.ENABLE = 1; + while (sercom->SPI.SYNCBUSY.bit.ENABLE); + + //------------- External Interrupt -------------// + + // Enable the APB clock for EIC (External Interrupt Controller) + PM->APBAMASK.reg |= PM_APBAMASK_EIC; + + // Configure GCLK for EIC + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_EIC | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_CLKEN; + while (GCLK->STATUS.bit.SYNCBUSY); + + // Configure PA20 as an input with function A (external interrupt) + gpio_set_pin_direction(MAX3421_INTR_PIN, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(MAX3421_INTR_PIN, GPIO_PULL_UP); + gpio_set_pin_function(MAX3421_INTR_PIN, 0); + + // Disable EIC + EIC->CTRL.bit.ENABLE = 0; + while (EIC->STATUS.bit.SYNCBUSY); + + // Configure EIC to trigger on falling edge + uint8_t const sense_shift = MAX3421_INTR_EIC_ID * 4; + EIC->CONFIG[0].reg &= ~(7 << sense_shift); + EIC->CONFIG[0].reg |= 2 << sense_shift; + +#if CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(EIC_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); +#endif + + // Enable External Interrupt + EIC->INTENSET.reg = EIC_INTENSET_EXTINT(1 << MAX3421_INTR_EIC_ID); + + // Enable EIC + EIC->CTRL.bit.ENABLE = 1; + while (EIC->STATUS.bit.SYNCBUSY); +} + +void EIC_Handler(void) { + // Clear the interrupt flag + EIC->INTFLAG.reg = EIC_INTFLAG_EXTINT(1 << MAX3421_INTR_EIC_ID); + + // Call the TinyUSB interrupt handler + tuh_int_handler(1, true); +} + +// API to enable/disable MAX3421 INTR pin interrupt +void tuh_max3421_int_api(uint8_t rhport, bool enabled) { + (void) rhport; + + if (enabled) { + NVIC_EnableIRQ(EIC_IRQn); + } else { + NVIC_DisableIRQ(EIC_IRQn); + } +} + +// API to control MAX3421 SPI CS +void tuh_max3421_spi_cs_api(uint8_t rhport, bool active) { + (void) rhport; + gpio_set_pin_level(MAX3421_CS_PIN, active ? 0 : 1); +} + +// API to transfer data with MAX3421 SPI +// Either tx_buf or rx_buf can be NULL, which means transfer is write or read only +bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const* tx_buf, uint8_t* rx_buf, size_t xfer_bytes) { + (void) rhport; + + Sercom* sercom = MAX3421_SERCOM; + + for (size_t count = 0; count < xfer_bytes; count++) { + // Wait for the transmit buffer to be empty + while (!sercom->SPI.INTFLAG.bit.DRE); + + // Write data to be transmitted + uint8_t data = 0x00; + if (tx_buf) { + data = tx_buf[count]; + } + + sercom->SPI.DATA.reg = (uint32_t) data; + + // Wait for the receive buffer to be filled + while (!sercom->SPI.INTFLAG.bit.RXC); + + // Read received data + data = (uint8_t) sercom->SPI.DATA.reg; + if (rx_buf) { + rx_buf[count] = data; + } + } + + // wait for bus idle and clear flags + while (!(sercom->SPI.INTFLAG.reg & (SERCOM_SPI_INTFLAG_TXC | SERCOM_SPI_INTFLAG_DRE))); + sercom->SPI.INTFLAG.reg = SERCOM_SPI_INTFLAG_TXC | SERCOM_SPI_INTFLAG_DRE; + + return true; +} + #endif diff --git a/hw/bsp/samd21/family.cmake b/hw/bsp/samd21/family.cmake new file mode 100644 index 000000000..c836b85d9 --- /dev/null +++ b/hw/bsp/samd21/family.cmake @@ -0,0 +1,112 @@ +include_guard() + +set(SDK_DIR ${TOP}/hw/mcu/microchip/samd21) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR cortex-m0plus CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS SAMD21 CACHE INTERNAL "") +set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -c \"transport select swd\" -f target/at91samdXX.cfg") + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif () + + set(LD_FILE_Clang ${LD_FILE_GNU}) + if (NOT DEFINED LD_FILE_${CMAKE_C_COMPILER_ID}) + message(FATAL_ERROR "LD_FILE_${CMAKE_C_COMPILER_ID} not defined") + endif () + + set(STARTUP_FILE_GNU ${SDK_DIR}/gcc/gcc/startup_samd21.c) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${SDK_DIR}/gcc/system_samd21.c + ${SDK_DIR}/hpl/gclk/hpl_gclk.c + ${SDK_DIR}/hpl/pm/hpl_pm.c + ${SDK_DIR}/hpl/sysctrl/hpl_sysctrl.c + ${SDK_DIR}/hal/src/hal_atomic.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_DIR} + ${SDK_DIR}/config + ${SDK_DIR}/include + ${SDK_DIR}/hal/include + ${SDK_DIR}/hal/utils/include + ${SDK_DIR}/hpl/pm + ${SDK_DIR}/hpl/port + ${SDK_DIR}/hri + ${SDK_DIR}/CMSIS/Include + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + CONF_DFLL_OVERWRITE_CALIBRATION=0 + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + 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_SAMD21 ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/microchip/samd/dcd_samd.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_add_bin_hex(${TARGET}) + family_flash_jlink(${TARGET}) + #family_flash_openocd(${TARGET}) +endfunction() diff --git a/hw/bsp/samd21/family.mk b/hw/bsp/samd21/family.mk index 49a1a781a..08c5c5b0e 100644 --- a/hw/bsp/samd21/family.mk +++ b/hw/bsp/samd21/family.mk @@ -1,12 +1,11 @@ UF2_FAMILY_ID = 0x68ed2b88 -DEPS_SUBMODULES += hw/mcu/microchip +SDK_DIR = hw/mcu/microchip/samd21 include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m0plus CFLAGS += \ -flto \ - -nostdlib -nostartfiles \ -DCONF_DFLL_OVERWRITE_CALIBRATION=0 \ -DCFG_TUSB_MCU=OPT_MCU_SAMD21 @@ -16,26 +15,32 @@ CFLAGS += -Wno-error=redundant-decls # SAM driver is flooded with -Wcast-qual which slow down complication significantly CFLAGS_SKIP += -Wcast-qual +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs \ + +LDFLAGS_CLANG += + SRC_C += \ src/portable/microchip/samd/dcd_samd.c \ - hw/mcu/microchip/samd21/gcc/gcc/startup_samd21.c \ - hw/mcu/microchip/samd21/gcc/system_samd21.c \ - hw/mcu/microchip/samd21/hpl/gclk/hpl_gclk.c \ - hw/mcu/microchip/samd21/hpl/pm/hpl_pm.c \ - hw/mcu/microchip/samd21/hpl/sysctrl/hpl_sysctrl.c \ - hw/mcu/microchip/samd21/hal/src/hal_atomic.c + ${SDK_DIR}/gcc/gcc/startup_samd21.c \ + ${SDK_DIR}/gcc/system_samd21.c \ + ${SDK_DIR}/hal/src/hal_atomic.c \ + ${SDK_DIR}/hpl/gclk/hpl_gclk.c \ + ${SDK_DIR}/hpl/pm/hpl_pm.c \ + ${SDK_DIR}/hpl/sysctrl/hpl_sysctrl.c \ INC += \ $(TOP)/$(BOARD_PATH) \ - $(TOP)/hw/mcu/microchip/samd21/ \ - $(TOP)/hw/mcu/microchip/samd21/config \ - $(TOP)/hw/mcu/microchip/samd21/include \ - $(TOP)/hw/mcu/microchip/samd21/hal/include \ - $(TOP)/hw/mcu/microchip/samd21/hal/utils/include \ - $(TOP)/hw/mcu/microchip/samd21/hpl/pm/ \ - $(TOP)/hw/mcu/microchip/samd21/hpl/port \ - $(TOP)/hw/mcu/microchip/samd21/hri \ - $(TOP)/hw/mcu/microchip/samd21/CMSIS/Include + $(TOP)/${SDK_DIR} \ + $(TOP)/${SDK_DIR}/config \ + $(TOP)/${SDK_DIR}/include \ + $(TOP)/${SDK_DIR}/hal/include \ + $(TOP)/${SDK_DIR}/hal/utils/include \ + $(TOP)/${SDK_DIR}/hpl/pm/ \ + $(TOP)/${SDK_DIR}/hpl/port \ + $(TOP)/${SDK_DIR}/hri \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ # flash using bossac at least version 1.8 # can be found in arduino15/packages/arduino/tools/bossac/ diff --git a/hw/bsp/samd51/family.c b/hw/bsp/samd51/family.c deleted file mode 100644 index 7ec208b30..000000000 --- a/hw/bsp/samd51/family.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2019 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. - */ - -#include "sam.h" -#include "bsp/board_api.h" -#include "board.h" - -#include "hal/include/hal_gpio.h" -#include "hal/include/hal_init.h" -#include "hpl/gclk/hpl_gclk_base.h" -#include "hpl_mclk_config.h" - -//--------------------------------------------------------------------+ -// Forward USB interrupt events to TinyUSB IRQ Handler -//--------------------------------------------------------------------+ -void USB_0_Handler (void) -{ - tud_int_handler(0); -} - -void USB_1_Handler (void) -{ - tud_int_handler(0); -} - -void USB_2_Handler (void) -{ - tud_int_handler(0); -} - -void USB_3_Handler (void) -{ - tud_int_handler(0); -} - -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM DECLARATION -//--------------------------------------------------------------------+ - -/* Referenced GCLKs, should be initialized firstly */ -#define _GCLK_INIT_1ST 0xFFFFFFFF - -/* Not referenced GCLKs, initialized last */ -#define _GCLK_INIT_LAST (~_GCLK_INIT_1ST) - -void board_init(void) -{ - // Clock init ( follow hpl_init.c ) - hri_nvmctrl_set_CTRLA_RWS_bf(NVMCTRL, 0); - - _osc32kctrl_init_sources(); - _oscctrl_init_sources(); - _mclk_init(); -#if _GCLK_INIT_1ST - _gclk_init_generators_by_fref(_GCLK_INIT_1ST); -#endif - _oscctrl_init_referenced_generators(); - _gclk_init_generators_by_fref(_GCLK_INIT_LAST); - - // Update SystemCoreClock since it is hard coded with asf4 and not correct - // Init 1ms tick timer (samd SystemCoreClock may not correct) - SystemCoreClock = CONF_CPU_FREQUENCY; - SysTick_Config(CONF_CPU_FREQUENCY / 1000); - - // Led init - gpio_set_pin_direction(LED_PIN, GPIO_DIRECTION_OUT); - gpio_set_pin_level(LED_PIN, 0); - - // Button init - gpio_set_pin_direction(BUTTON_PIN, GPIO_DIRECTION_IN); - gpio_set_pin_pull_mode(BUTTON_PIN, GPIO_PULL_UP); - -#if CFG_TUSB_OS == OPT_OS_FREERTOS - // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) - NVIC_SetPriority(USB_0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); - NVIC_SetPriority(USB_1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); - NVIC_SetPriority(USB_2_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); - NVIC_SetPriority(USB_3_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); -#endif - - /* USB Clock init - * The USB module requires a GCLK_USB of 48 MHz ~ 0.25% clock - * for low speed and full speed operation. */ - hri_gclk_write_PCHCTRL_reg(GCLK, USB_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | GCLK_PCHCTRL_CHEN); - hri_mclk_set_AHBMASK_USB_bit(MCLK); - hri_mclk_set_APBBMASK_USB_bit(MCLK); - - // USB Pin Init - gpio_set_pin_direction(PIN_PA24, GPIO_DIRECTION_OUT); - gpio_set_pin_level(PIN_PA24, false); - gpio_set_pin_pull_mode(PIN_PA24, GPIO_PULL_OFF); - gpio_set_pin_direction(PIN_PA25, GPIO_DIRECTION_OUT); - gpio_set_pin_level(PIN_PA25, false); - gpio_set_pin_pull_mode(PIN_PA25, GPIO_PULL_OFF); - - gpio_set_pin_function(PIN_PA24, PINMUX_PA24H_USB_DM); - gpio_set_pin_function(PIN_PA25, PINMUX_PA25H_USB_DP); -} - -//--------------------------------------------------------------------+ -// Board porting API -//--------------------------------------------------------------------+ - -void board_led_write(bool state) -{ - gpio_set_pin_level(LED_PIN, state); -} - -uint32_t board_button_read(void) -{ - // button is active low - return gpio_get_pin_level(BUTTON_PIN) ? 0 : 1; -} - -int board_uart_read(uint8_t* buf, int len) -{ - (void) buf; (void) len; - return 0; -} - -int board_uart_write(void const * buf, int len) -{ - (void) buf; (void) len; - return 0; -} - -#if CFG_TUSB_OS == OPT_OS_NONE -volatile uint32_t system_ticks = 0; - -void SysTick_Handler (void) -{ - system_ticks++; -} - -uint32_t board_millis(void) -{ - return system_ticks; -} -#endif diff --git a/hw/bsp/samd51/family.mk b/hw/bsp/samd51/family.mk deleted file mode 100644 index 9a6c67e1a..000000000 --- a/hw/bsp/samd51/family.mk +++ /dev/null @@ -1,43 +0,0 @@ -UF2_FAMILY_ID = 0x55114460 -DEPS_SUBMODULES += hw/mcu/microchip - -include $(TOP)/$(BOARD_PATH)/board.mk -CPU_CORE ?= cortex-m4 - -CFLAGS += \ - -flto \ - -nostdlib -nostartfiles \ - -DCFG_TUSB_MCU=OPT_MCU_SAMD51 - -# SAM driver is flooded with -Wcast-qual which slow down complication significantly -CFLAGS_SKIP += -Wcast-qual - -SRC_C += \ - src/portable/microchip/samd/dcd_samd.c \ - hw/mcu/microchip/samd51/gcc/gcc/startup_samd51.c \ - hw/mcu/microchip/samd51/gcc/system_samd51.c \ - hw/mcu/microchip/samd51/hpl/gclk/hpl_gclk.c \ - hw/mcu/microchip/samd51/hpl/mclk/hpl_mclk.c \ - hw/mcu/microchip/samd51/hpl/osc32kctrl/hpl_osc32kctrl.c \ - hw/mcu/microchip/samd51/hpl/oscctrl/hpl_oscctrl.c \ - hw/mcu/microchip/samd51/hal/src/hal_atomic.c - -INC += \ - $(TOP)/$(BOARD_PATH) \ - $(TOP)/hw/mcu/microchip/samd51/ \ - $(TOP)/hw/mcu/microchip/samd51/config \ - $(TOP)/hw/mcu/microchip/samd51/include \ - $(TOP)/hw/mcu/microchip/samd51/hal/include \ - $(TOP)/hw/mcu/microchip/samd51/hal/utils/include \ - $(TOP)/hw/mcu/microchip/samd51/hpl/port \ - $(TOP)/hw/mcu/microchip/samd51/hri \ - $(TOP)/hw/mcu/microchip/samd51/CMSIS/Include - -# flash using bossac at least version 1.8 -# can be found in arduino15/packages/arduino/tools/bossac/ -# Add it to your PATH or change BOSSAC variable to match your installation -BOSSAC = bossac - -flash-bossac: $(BUILD)/$(PROJECT).bin - @:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyACM0) - $(BOSSAC) --port=$(SERIAL) -U -i --offset=0x4000 -e -w $^ -R diff --git a/hw/bsp/samd5x_e5x/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/samd5x_e5x/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..a283560fe --- /dev/null +++ b/hw/bsp/samd5x_e5x/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,149 @@ +/* + * 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 "sam.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*6*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 4 +#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 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* 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 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* 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 + +/* 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 3 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<XOSCCTRL[1].reg = + OSCCTRL_XOSCCTRL_STARTUP(6) | // 1,953 ms + OSCCTRL_XOSCCTRL_RUNSTDBY | + OSCCTRL_XOSCCTRL_ENALC | + OSCCTRL_XOSCCTRL_IMULT(4) | + OSCCTRL_XOSCCTRL_IPTAT(3) | + OSCCTRL_XOSCCTRL_XTALEN | + OSCCTRL_XOSCCTRL_ENABLE; + while(0 == OSCCTRL->STATUS.bit.XOSCRDY1); + + OSCCTRL->Dpll[0].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_DIV(3) | OSCCTRL_DPLLCTRLB_REFCLK(OSCCTRL_DPLLCTRLB_REFCLK_XOSC1_Val); /* pre-scaler = 8, input = XOSC1 */ + OSCCTRL->Dpll[0].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0x0) | OSCCTRL_DPLLRATIO_LDR(39); /* multiply by 40 -> 80 MHz */ + OSCCTRL->Dpll[0].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_RUNSTDBY | OSCCTRL_DPLLCTRLA_ENABLE; + while(0 == OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY); /* wait for the PLL0 to be ready */ + + OSCCTRL->Dpll[1].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_DIV(7) | OSCCTRL_DPLLCTRLB_REFCLK(OSCCTRL_DPLLCTRLB_REFCLK_XOSC1_Val); /* pre-scaler = 16, input = XOSC1 */ + OSCCTRL->Dpll[1].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0x0) | OSCCTRL_DPLLRATIO_LDR(47); /* multiply by 48 -> 48 MHz */ + OSCCTRL->Dpll[1].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_RUNSTDBY | OSCCTRL_DPLLCTRLA_ENABLE; + while(0 == OSCCTRL->Dpll[1].DPLLSTATUS.bit.CLKRDY); /* wait for the PLL1 to be ready */ +#else // HWREV >= 1 + /* configure XOSC0 for a 16MHz crystal connected to XIN0/XOUT0 */ + OSCCTRL->XOSCCTRL[0].reg = + OSCCTRL_XOSCCTRL_STARTUP(6) | // 1,953 ms + OSCCTRL_XOSCCTRL_RUNSTDBY | + OSCCTRL_XOSCCTRL_ENALC | + OSCCTRL_XOSCCTRL_IMULT(4) | + OSCCTRL_XOSCCTRL_IPTAT(3) | + OSCCTRL_XOSCCTRL_XTALEN | + OSCCTRL_XOSCCTRL_ENABLE; + while (0 == OSCCTRL->STATUS.bit.XOSCRDY0); + + OSCCTRL->Dpll[0].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_DIV(3) | OSCCTRL_DPLLCTRLB_REFCLK( + OSCCTRL_DPLLCTRLB_REFCLK_XOSC0_Val); /* pre-scaler = 8, input = XOSC1 */ + OSCCTRL->Dpll[0].DPLLRATIO.reg = + OSCCTRL_DPLLRATIO_LDRFRAC(0x0) | OSCCTRL_DPLLRATIO_LDR(39); /* multiply by 40 -> 80 MHz */ + OSCCTRL->Dpll[0].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_RUNSTDBY | OSCCTRL_DPLLCTRLA_ENABLE; + while (0 == OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY); /* wait for the PLL0 to be ready */ + + OSCCTRL->Dpll[1].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_DIV(7) | OSCCTRL_DPLLCTRLB_REFCLK( + OSCCTRL_DPLLCTRLB_REFCLK_XOSC0_Val); /* pre-scaler = 16, input = XOSC1 */ + OSCCTRL->Dpll[1].DPLLRATIO.reg = + OSCCTRL_DPLLRATIO_LDRFRAC(0x0) | OSCCTRL_DPLLRATIO_LDR(47); /* multiply by 48 -> 48 MHz */ + OSCCTRL->Dpll[1].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_RUNSTDBY | OSCCTRL_DPLLCTRLA_ENABLE; + while (0 == OSCCTRL->Dpll[1].DPLLSTATUS.bit.CLKRDY); /* wait for the PLL1 to be ready */ +#endif // HWREV + + /* configure clock-generator 0 to use DPLL0 as source -> GCLK0 is used for the core */ + GCLK->GENCTRL[0].reg = + GCLK_GENCTRL_DIV(0) | + GCLK_GENCTRL_RUNSTDBY | + GCLK_GENCTRL_GENEN | + GCLK_GENCTRL_SRC_DPLL0 | /* DPLL0 */ + GCLK_GENCTRL_IDC; + while (1 == GCLK->SYNCBUSY.bit.GENCTRL0); /* wait for the synchronization between clock domains to be complete */ + + /* configure clock-generator 1 to use DPLL1 as source -> for use with some peripheral */ + GCLK->GENCTRL[1].reg = + GCLK_GENCTRL_DIV(0) | + GCLK_GENCTRL_RUNSTDBY | + GCLK_GENCTRL_GENEN | + GCLK_GENCTRL_SRC_DPLL1 | + GCLK_GENCTRL_IDC; + while (1 == GCLK->SYNCBUSY.bit.GENCTRL1); /* wait for the synchronization between clock domains to be complete */ + + /* configure clock-generator 2 to use DPLL0 as source -> for use with SERCOM */ + GCLK->GENCTRL[2].reg = + GCLK_GENCTRL_DIV(1) | /* 80MHz */ + GCLK_GENCTRL_RUNSTDBY | + GCLK_GENCTRL_GENEN | + GCLK_GENCTRL_SRC_DPLL0 | + GCLK_GENCTRL_IDC; + while (1 == GCLK->SYNCBUSY.bit.GENCTRL2); /* wait for the synchronization between clock domains to be complete */ +} + +static inline void uart_init(void) { +#if HWREV < 3 + /* configure SERCOM5 on PB02 */ + PORT->Group[1].WRCONFIG.reg = + PORT_WRCONFIG_WRPINCFG | + PORT_WRCONFIG_WRPMUX | + PORT_WRCONFIG_PMUX(3) | /* function D */ + PORT_WRCONFIG_DRVSTR | + PORT_WRCONFIG_PINMASK(0x0004) | /* PB02 */ + PORT_WRCONFIG_PMUXEN; + + MCLK->APBDMASK.bit.SERCOM5_ = 1; + GCLK->PCHCTRL[SERCOM5_GCLK_ID_CORE].reg = + GCLK_PCHCTRL_GEN_GCLK2 | GCLK_PCHCTRL_CHEN; /* setup SERCOM to use GLCK2 -> 80MHz */ + + SERCOM5->USART.CTRLA.reg = 0x00; /* disable SERCOM -> enable config */ + while (SERCOM5->USART.SYNCBUSY.bit.ENABLE); + + SERCOM5->USART.CTRLA.reg = /* CMODE = 0 -> async, SAMPA = 0, FORM = 0 -> USART frame, SMPR = 0 -> arithmetic baud rate */ + SERCOM_USART_CTRLA_SAMPR(1) | /* 0 = 16x / arithmetic baud rate, 1 = 16x / fractional baud rate */ + // SERCOM_USART_CTRLA_FORM(0) | /* 0 = USART Frame, 2 = LIN Master */ + SERCOM_USART_CTRLA_DORD | /* LSB first */ + SERCOM_USART_CTRLA_MODE(1) | /* 0 = Asynchronous, 1 = USART with internal clock */ + SERCOM_USART_CTRLA_RXPO(1) | /* SERCOM PAD[1] is used for data reception */ + SERCOM_USART_CTRLA_TXPO(0); /* SERCOM PAD[0] is used for data transmission */ + + SERCOM5->USART.CTRLB.reg = /* RXEM = 0 -> receiver disabled, LINCMD = 0 -> normal USART transmission, SFDE = 0 -> start-of-frame detection disabled, SBMODE = 0 -> one stop bit, CHSIZE = 0 -> 8 bits */ + SERCOM_USART_CTRLB_TXEN; /* transmitter enabled */ + SERCOM5->USART.CTRLC.reg = 0x00; + // 21.701388889 @ baud rate of 230400 bit/s, table 33-2, p 918 of DS60001507E + SERCOM5->USART.BAUD.reg = SERCOM_USART_BAUD_FRAC_FP(7) | SERCOM_USART_BAUD_FRAC_BAUD(21); + +// SERCOM5->USART.INTENSET.reg = SERCOM_USART_INTENSET_TXC; + SERCOM5->SPI.CTRLA.bit.ENABLE = 1; /* activate SERCOM */ + while (SERCOM5->USART.SYNCBUSY.bit.ENABLE); /* wait for SERCOM to be ready */ +#else + /* configure SERCOM0 on PA08 */ + PORT->Group[0].WRCONFIG.reg = + PORT_WRCONFIG_WRPINCFG | + PORT_WRCONFIG_WRPMUX | + PORT_WRCONFIG_PMUX(2) | /* function C */ + PORT_WRCONFIG_DRVSTR | + PORT_WRCONFIG_PINMASK(0x0100) | /* PA08 */ + PORT_WRCONFIG_PMUXEN; + + MCLK->APBAMASK.bit.SERCOM0_ = 1; + GCLK->PCHCTRL[SERCOM0_GCLK_ID_CORE].reg = GCLK_PCHCTRL_GEN_GCLK2 | GCLK_PCHCTRL_CHEN; /* setup SERCOM to use GLCK2 -> 80MHz */ + + SERCOM0->USART.CTRLA.reg = 0x00; /* disable SERCOM -> enable config */ + while(SERCOM0->USART.SYNCBUSY.bit.ENABLE); + + SERCOM0->USART.CTRLA.reg = /* CMODE = 0 -> async, SAMPA = 0, FORM = 0 -> USART frame, SMPR = 0 -> arithmetic baud rate */ + SERCOM_USART_CTRLA_SAMPR(1) | /* 0 = 16x / arithmetic baud rate, 1 = 16x / fractional baud rate */ + // SERCOM_USART_CTRLA_FORM(0) | /* 0 = USART Frame, 2 = LIN Master */ + SERCOM_USART_CTRLA_DORD | /* LSB first */ + SERCOM_USART_CTRLA_MODE(1) | /* 0 = Asynchronous, 1 = USART with internal clock */ + SERCOM_USART_CTRLA_RXPO(1) | /* SERCOM PAD[1] is used for data reception */ + SERCOM_USART_CTRLA_TXPO(0); /* SERCOM PAD[0] is used for data transmission */ + + SERCOM0->USART.CTRLB.reg = /* RXEM = 0 -> receiver disabled, LINCMD = 0 -> normal USART transmission, SFDE = 0 -> start-of-frame detection disabled, SBMODE = 0 -> one stop bit, CHSIZE = 0 -> 8 bits */ + SERCOM_USART_CTRLB_TXEN; /* transmitter enabled */ + SERCOM0->USART.CTRLC.reg = 0x00; + // 21.701388889 @ baud rate of 230400 bit/s, table 33-2, p 918 of DS60001507E + SERCOM0->USART.BAUD.reg = SERCOM_USART_BAUD_FRAC_FP(7) | SERCOM_USART_BAUD_FRAC_BAUD(21); + + // SERCOM0->USART.INTENSET.reg = SERCOM_USART_INTENSET_TXC; + SERCOM0->SPI.CTRLA.bit.ENABLE = 1; /* activate SERCOM */ + while(SERCOM0->USART.SYNCBUSY.bit.ENABLE); /* wait for SERCOM to be ready */ +#endif +} +#endif + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/same5x/boards/d5035_01/board.mk b/hw/bsp/samd5x_e5x/boards/d5035_01/board.mk similarity index 95% rename from hw/bsp/same5x/boards/d5035_01/board.mk rename to hw/bsp/samd5x_e5x/boards/d5035_01/board.mk index c53411bb8..4aa6b89fe 100644 --- a/hw/bsp/same5x/boards/d5035_01/board.mk +++ b/hw/bsp/samd5x_e5x/boards/d5035_01/board.mk @@ -1,4 +1,4 @@ -MCU = same51 +SAM_FAMILY = same51 HWREV ?= 1 diff --git a/hw/bsp/same5x/boards/d5035_01/same51j19a_flash.ld b/hw/bsp/samd5x_e5x/boards/d5035_01/same51j19a_flash.ld similarity index 97% rename from hw/bsp/same5x/boards/d5035_01/same51j19a_flash.ld rename to hw/bsp/samd5x_e5x/boards/d5035_01/same51j19a_flash.ld index a8dd44336..59afb604b 100644 --- a/hw/bsp/same5x/boards/d5035_01/same51j19a_flash.ld +++ b/hw/bsp/samd5x_e5x/boards/d5035_01/same51j19a_flash.ld @@ -42,7 +42,9 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x1000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x1000; + +ENTRY(Reset_Handler) /* Section Definitions */ SECTIONS diff --git a/hw/bsp/samd5x_e5x/boards/feather_m4_express/board.cmake b/hw/bsp/samd5x_e5x/boards/feather_m4_express/board.cmake new file mode 100644 index 000000000..86d12ca24 --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/feather_m4_express/board.cmake @@ -0,0 +1,10 @@ +set(SAM_FAMILY samd51) + +set(JLINK_DEVICE ATSAMD51J19) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAMD51J19A__ + ) +endfunction() diff --git a/hw/bsp/samd5x_e5x/boards/feather_m4_express/board.h b/hw/bsp/samd5x_e5x/boards/feather_m4_express/board.h new file mode 100644 index 000000000..83de04266 --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/feather_m4_express/board.h @@ -0,0 +1,67 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, 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 _PINNUM(port, pin) ((port)*32 + (pin)) + +// LED +#define LED_PIN 23 +#define LED_STATE_ON 1 + +// Button +#define BUTTON_PIN 16 // D5 +#define BUTTON_STATE_ACTIVE 0 + +// UART +#define UART_TX_PIN (32 + 17) +#define UART_RX_PIN (32 + 16) + +// SPI for USB host shield +#define MAX3421_SERCOM_ID 1 // SERCOM2 +#define MAX3421_SERCOM_FUNCTION 2 // function C + +#define MAX3421_SCK_PIN _PINNUM(0, 17) +#define MAX3421_MOSI_PIN _PINNUM(1, 23) +#define MAX3421_MISO_PIN _PINNUM(1, 22) +#define MAX3421_TX_PAD 2 // MOSI = PAD_3, SCK = PAD_1 +#define MAX3421_RX_PAD 2 // MISO = PAD_2 + +#define MAX3421_CS_PIN 20 // D10 + +#define MAX3421_INTR_PIN 19 // D9 +#define MAX3421_INTR_EIC_ID 3 // EIC3 + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/samd51/boards/pyportal/board.mk b/hw/bsp/samd5x_e5x/boards/feather_m4_express/board.mk similarity index 86% rename from hw/bsp/samd51/boards/pyportal/board.mk rename to hw/bsp/samd5x_e5x/boards/feather_m4_express/board.mk index a8a98a987..811c5f4e3 100644 --- a/hw/bsp/samd51/boards/pyportal/board.mk +++ b/hw/bsp/samd5x_e5x/boards/feather_m4_express/board.mk @@ -1,3 +1,5 @@ +SAM_FAMILY = samd51 + CFLAGS += -D__SAMD51J19A__ LD_FILE = $(BOARD_PATH)/$(BOARD).ld diff --git a/hw/bsp/samd51/boards/feather_m4_express/feather_m4_express.ld b/hw/bsp/samd5x_e5x/boards/feather_m4_express/feather_m4_express.ld similarity index 97% rename from hw/bsp/samd51/boards/feather_m4_express/feather_m4_express.ld rename to hw/bsp/samd5x_e5x/boards/feather_m4_express/feather_m4_express.ld index f1a021d75..1408c3018 100644 --- a/hw/bsp/samd51/boards/feather_m4_express/feather_m4_express.ld +++ b/hw/bsp/samd5x_e5x/boards/feather_m4_express/feather_m4_express.ld @@ -42,7 +42,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0xC000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0xC000; ENTRY(Reset_Handler) diff --git a/hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.cmake b/hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.cmake new file mode 100644 index 000000000..86d12ca24 --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.cmake @@ -0,0 +1,10 @@ +set(SAM_FAMILY samd51) + +set(JLINK_DEVICE ATSAMD51J19) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAMD51J19A__ + ) +endfunction() diff --git a/hw/bsp/samd51/boards/itsybitsy_m4/board.h b/hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.h similarity index 100% rename from hw/bsp/samd51/boards/itsybitsy_m4/board.h rename to hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.h diff --git a/hw/bsp/samd51/boards/itsybitsy_m4/board.mk b/hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.mk similarity index 90% rename from hw/bsp/samd51/boards/itsybitsy_m4/board.mk rename to hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.mk index 57a680e91..eba7070c1 100644 --- a/hw/bsp/samd51/boards/itsybitsy_m4/board.mk +++ b/hw/bsp/samd5x_e5x/boards/itsybitsy_m4/board.mk @@ -1,3 +1,5 @@ +SAM_FAMILY = samd51 + CFLAGS += -D__SAMD51J19A__ # All source paths should be relative to the top level. diff --git a/hw/bsp/samd51/boards/itsybitsy_m4/itsybitsy_m4.ld b/hw/bsp/samd5x_e5x/boards/itsybitsy_m4/itsybitsy_m4.ld similarity index 97% rename from hw/bsp/samd51/boards/itsybitsy_m4/itsybitsy_m4.ld rename to hw/bsp/samd5x_e5x/boards/itsybitsy_m4/itsybitsy_m4.ld index f1a021d75..1408c3018 100644 --- a/hw/bsp/samd51/boards/itsybitsy_m4/itsybitsy_m4.ld +++ b/hw/bsp/samd5x_e5x/boards/itsybitsy_m4/itsybitsy_m4.ld @@ -42,7 +42,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0xC000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0xC000; ENTRY(Reset_Handler) diff --git a/hw/bsp/samd5x_e5x/boards/metro_m4_express/board.cmake b/hw/bsp/samd5x_e5x/boards/metro_m4_express/board.cmake new file mode 100644 index 000000000..86d12ca24 --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/metro_m4_express/board.cmake @@ -0,0 +1,10 @@ +set(SAM_FAMILY samd51) + +set(JLINK_DEVICE ATSAMD51J19) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAMD51J19A__ + ) +endfunction() diff --git a/hw/bsp/samd5x_e5x/boards/metro_m4_express/board.h b/hw/bsp/samd5x_e5x/boards/metro_m4_express/board.h new file mode 100644 index 000000000..b3b80db89 --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/metro_m4_express/board.h @@ -0,0 +1,66 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, 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 + +// LED +#define LED_PIN 16 +#define LED_STATE_ON 1 + +// Button: D5 +#define BUTTON_PIN (32+14) +#define BUTTON_STATE_ACTIVE 0 + +// UART +#define UART_TX_PIN 23 +#define UART_RX_PIN 22 + +// SPI for USB host shield +#define MAX3421_SERCOM_ID 2 // SERCOM2 +#define MAX3421_SERCOM_FUNCTION 2 // function C + +#define MAX3421_SCK_PIN 13 +#define MAX3421_MOSI_PIN 12 +#define MAX3421_MISO_PIN 14 +#define MAX3421_TX_PAD 0 // MOSI = PAD_0, SCK = PAD_1 +#define MAX3421_RX_PAD 2 // MISO = PAD_2 + +#define MAX3421_CS_PIN 18 // D10 + +#define MAX3421_INTR_PIN 20 // D9 +#define MAX3421_INTR_EIC_ID 4 // EIC4 + + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/samd51/boards/metro_m4_express/board.mk b/hw/bsp/samd5x_e5x/boards/metro_m4_express/board.mk similarity index 90% rename from hw/bsp/samd51/boards/metro_m4_express/board.mk rename to hw/bsp/samd5x_e5x/boards/metro_m4_express/board.mk index 57a680e91..eba7070c1 100644 --- a/hw/bsp/samd51/boards/metro_m4_express/board.mk +++ b/hw/bsp/samd5x_e5x/boards/metro_m4_express/board.mk @@ -1,3 +1,5 @@ +SAM_FAMILY = samd51 + CFLAGS += -D__SAMD51J19A__ # All source paths should be relative to the top level. diff --git a/hw/bsp/samd51/boards/metro_m4_express/metro_m4_express.ld b/hw/bsp/samd5x_e5x/boards/metro_m4_express/metro_m4_express.ld similarity index 97% rename from hw/bsp/samd51/boards/metro_m4_express/metro_m4_express.ld rename to hw/bsp/samd5x_e5x/boards/metro_m4_express/metro_m4_express.ld index f1a021d75..1408c3018 100644 --- a/hw/bsp/samd51/boards/metro_m4_express/metro_m4_express.ld +++ b/hw/bsp/samd5x_e5x/boards/metro_m4_express/metro_m4_express.ld @@ -42,7 +42,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0xC000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0xC000; ENTRY(Reset_Handler) diff --git a/hw/bsp/samd5x_e5x/boards/pybadge/board.cmake b/hw/bsp/samd5x_e5x/boards/pybadge/board.cmake new file mode 100644 index 000000000..86d12ca24 --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/pybadge/board.cmake @@ -0,0 +1,10 @@ +set(SAM_FAMILY samd51) + +set(JLINK_DEVICE ATSAMD51J19) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAMD51J19A__ + ) +endfunction() diff --git a/hw/bsp/samd51/boards/feather_m4_express/board.h b/hw/bsp/samd5x_e5x/boards/pybadge/board.h similarity index 100% rename from hw/bsp/samd51/boards/feather_m4_express/board.h rename to hw/bsp/samd5x_e5x/boards/pybadge/board.h diff --git a/hw/bsp/samd51/boards/feather_m4_express/board.mk b/hw/bsp/samd5x_e5x/boards/pybadge/board.mk similarity index 86% rename from hw/bsp/samd51/boards/feather_m4_express/board.mk rename to hw/bsp/samd5x_e5x/boards/pybadge/board.mk index a8a98a987..811c5f4e3 100644 --- a/hw/bsp/samd51/boards/feather_m4_express/board.mk +++ b/hw/bsp/samd5x_e5x/boards/pybadge/board.mk @@ -1,3 +1,5 @@ +SAM_FAMILY = samd51 + CFLAGS += -D__SAMD51J19A__ LD_FILE = $(BOARD_PATH)/$(BOARD).ld diff --git a/hw/bsp/samd51/boards/pybadge/pybadge.ld b/hw/bsp/samd5x_e5x/boards/pybadge/pybadge.ld similarity index 97% rename from hw/bsp/samd51/boards/pybadge/pybadge.ld rename to hw/bsp/samd5x_e5x/boards/pybadge/pybadge.ld index f1a021d75..1408c3018 100644 --- a/hw/bsp/samd51/boards/pybadge/pybadge.ld +++ b/hw/bsp/samd5x_e5x/boards/pybadge/pybadge.ld @@ -42,7 +42,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0xC000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0xC000; ENTRY(Reset_Handler) diff --git a/hw/bsp/samd5x_e5x/boards/pyportal/board.cmake b/hw/bsp/samd5x_e5x/boards/pyportal/board.cmake new file mode 100644 index 000000000..86d12ca24 --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/pyportal/board.cmake @@ -0,0 +1,10 @@ +set(SAM_FAMILY samd51) + +set(JLINK_DEVICE ATSAMD51J19) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAMD51J19A__ + ) +endfunction() diff --git a/hw/bsp/samd51/boards/pyportal/board.h b/hw/bsp/samd5x_e5x/boards/pyportal/board.h similarity index 100% rename from hw/bsp/samd51/boards/pyportal/board.h rename to hw/bsp/samd5x_e5x/boards/pyportal/board.h diff --git a/hw/bsp/samd51/boards/pybadge/board.mk b/hw/bsp/samd5x_e5x/boards/pyportal/board.mk similarity index 86% rename from hw/bsp/samd51/boards/pybadge/board.mk rename to hw/bsp/samd5x_e5x/boards/pyportal/board.mk index a8a98a987..811c5f4e3 100644 --- a/hw/bsp/samd51/boards/pybadge/board.mk +++ b/hw/bsp/samd5x_e5x/boards/pyportal/board.mk @@ -1,3 +1,5 @@ +SAM_FAMILY = samd51 + CFLAGS += -D__SAMD51J19A__ LD_FILE = $(BOARD_PATH)/$(BOARD).ld diff --git a/hw/bsp/samd51/boards/pyportal/pyportal.ld b/hw/bsp/samd5x_e5x/boards/pyportal/pyportal.ld similarity index 97% rename from hw/bsp/samd51/boards/pyportal/pyportal.ld rename to hw/bsp/samd5x_e5x/boards/pyportal/pyportal.ld index f1a021d75..1408c3018 100644 --- a/hw/bsp/samd51/boards/pyportal/pyportal.ld +++ b/hw/bsp/samd5x_e5x/boards/pyportal/pyportal.ld @@ -42,7 +42,7 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0xC000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0xC000; ENTRY(Reset_Handler) diff --git a/hw/bsp/samd5x_e5x/boards/same54_xplained/board.cmake b/hw/bsp/samd5x_e5x/boards/same54_xplained/board.cmake new file mode 100644 index 000000000..4d98205bc --- /dev/null +++ b/hw/bsp/samd5x_e5x/boards/same54_xplained/board.cmake @@ -0,0 +1,10 @@ +set(SAM_FAMILY same54) + +set(JLINK_DEVICE ATSAME54P20) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/same54p20a_flash.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __SAME54P20A__ + ) +endfunction() diff --git a/hw/bsp/samd51/boards/metro_m4_express/board.h b/hw/bsp/samd5x_e5x/boards/same54_xplained/board.h similarity index 89% rename from hw/bsp/samd51/boards/metro_m4_express/board.h rename to hw/bsp/samd5x_e5x/boards/same54_xplained/board.h index 5d7734576..faaa52b8e 100644 --- a/hw/bsp/samd51/boards/metro_m4_express/board.h +++ b/hw/bsp/samd5x_e5x/boards/same54_xplained/board.h @@ -32,16 +32,16 @@ #endif // LED -#define LED_PIN 16 +#define LED_PIN PIN_PC18 #define LED_STATE_ON 1 // Button: D5 -#define BUTTON_PIN (32+14) +#define BUTTON_PIN PIN_PB31 #define BUTTON_STATE_ACTIVE 0 -// UART -#define UART_TX_PIN 23 -#define UART_RX_PIN 22 +// UART: SERCOM2 +//#define UART_TX_PIN 23 +//#define UART_RX_PIN 22 #ifdef __cplusplus } diff --git a/hw/bsp/same5x/boards/same54_xplained/board.mk b/hw/bsp/samd5x_e5x/boards/same54_xplained/board.mk similarity index 54% rename from hw/bsp/same5x/boards/same54_xplained/board.mk rename to hw/bsp/samd5x_e5x/boards/same54_xplained/board.mk index 41cf95bfc..d10e9e34c 100644 --- a/hw/bsp/same5x/boards/same54_xplained/board.mk +++ b/hw/bsp/samd5x_e5x/boards/same54_xplained/board.mk @@ -1,9 +1,6 @@ -MCU = same54 +SAM_FAMILY = same54 -CFLAGS += \ - -DCONF_CPU_FREQUENCY=48000000 \ - -D__SAME54P20A__ \ - -DBOARD_NAME="\"Microchip SAM E54 Xplained Pro\"" +CFLAGS += -D__SAME54P20A__ # All source paths should be relative to the top level. LD_FILE = $(BOARD_PATH)/same54p20a_flash.ld diff --git a/hw/bsp/same5x/boards/same54_xplained/same54p20a_flash.ld b/hw/bsp/samd5x_e5x/boards/same54_xplained/same54p20a_flash.ld similarity index 97% rename from hw/bsp/same5x/boards/same54_xplained/same54p20a_flash.ld rename to hw/bsp/samd5x_e5x/boards/same54_xplained/same54p20a_flash.ld index 1f427a066..8a9fd7d9f 100644 --- a/hw/bsp/same5x/boards/same54_xplained/same54p20a_flash.ld +++ b/hw/bsp/samd5x_e5x/boards/same54_xplained/same54p20a_flash.ld @@ -42,7 +42,9 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x10000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x10000; + +ENTRY(Reset_Handler) /* Section Definitions */ SECTIONS @@ -160,4 +162,5 @@ SECTIONS . = ALIGN(4); _end = . ; + end = .; } diff --git a/hw/bsp/same5x/boards/same54_xplained/same54p20a_sram.ld b/hw/bsp/samd5x_e5x/boards/same54_xplained/same54p20a_sram.ld similarity index 97% rename from hw/bsp/same5x/boards/same54_xplained/same54p20a_sram.ld rename to hw/bsp/samd5x_e5x/boards/same54_xplained/same54p20a_sram.ld index e6e33ec48..c88617729 100644 --- a/hw/bsp/same5x/boards/same54_xplained/same54p20a_sram.ld +++ b/hw/bsp/samd5x_e5x/boards/same54_xplained/same54p20a_sram.ld @@ -41,7 +41,9 @@ MEMORY } /* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x10000; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x10000; + +ENTRY(Reset_Handler) /* Section Definitions */ SECTIONS @@ -159,4 +161,5 @@ SECTIONS . = ALIGN(4); _end = . ; + end = .; } diff --git a/hw/bsp/samd5x_e5x/family.c b/hw/bsp/samd5x_e5x/family.c new file mode 100644 index 000000000..abaee353b --- /dev/null +++ b/hw/bsp/samd5x_e5x/family.c @@ -0,0 +1,448 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 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. + */ + +#include "sam.h" +#include "bsp/board_api.h" +#include "board.h" + +// Suppress warning caused by mcu driver +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" +#endif + +#include "hal_gpio.h" +#include "hal_init.h" +#include "hpl/gclk/hpl_gclk_base.h" +#include "hpl_mclk_config.h" + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ + +/* Referenced GCLKs, should be initialized firstly */ +#define _GCLK_INIT_1ST 0xFFFFFFFF + +/* Not referenced GCLKs, initialized last */ +#define _GCLK_INIT_LAST (~_GCLK_INIT_1ST) + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void USB_0_Handler(void) { + tud_int_handler(0); +} + +void USB_1_Handler(void) { + tud_int_handler(0); +} + +void USB_2_Handler(void) { + tud_int_handler(0); +} + +void USB_3_Handler(void) { + tud_int_handler(0); +} + +//--------------------------------------------------------------------+ +// Implementation +//--------------------------------------------------------------------+ + +#if CFG_TUH_ENABLED && CFG_TUH_MAX3421 + +#define MAX3421_SERCOM TU_XSTRCAT(SERCOM, MAX3421_SERCOM_ID) +#define MAX3421_EIC_Handler TU_XSTRCAT3(EIC_, MAX3421_INTR_EIC_ID, _Handler) + +static void max3421_init(void); +#endif + +void board_init(void) { + // Clock init ( follow hpl_init.c ) + hri_nvmctrl_set_CTRLA_RWS_bf(NVMCTRL, 0); + + _osc32kctrl_init_sources(); + _oscctrl_init_sources(); + _mclk_init(); +#if _GCLK_INIT_1ST + _gclk_init_generators_by_fref(_GCLK_INIT_1ST); +#endif + _oscctrl_init_referenced_generators(); + _gclk_init_generators_by_fref(_GCLK_INIT_LAST); + + // Update SystemCoreClock since it is hard coded with asf4 and not correct + // Init 1ms tick timer (samd SystemCoreClock may not correct) + SystemCoreClock = CONF_CPU_FREQUENCY; + SysTick_Config(CONF_CPU_FREQUENCY / 1000); + + // Led init + gpio_set_pin_direction(LED_PIN, GPIO_DIRECTION_OUT); + gpio_set_pin_level(LED_PIN, 0); + +#ifdef BUTTON_PIN + // Button init + gpio_set_pin_direction(BUTTON_PIN, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(BUTTON_PIN, GPIO_PULL_UP); +#endif + +#if CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(USB_0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); + NVIC_SetPriority(USB_1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); + NVIC_SetPriority(USB_2_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); + NVIC_SetPriority(USB_3_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); +#endif + + /* USB Clock init + * The USB module requires a GCLK_USB of 48 MHz ~ 0.25% clock + * for low speed and full speed operation. */ + hri_gclk_write_PCHCTRL_reg(GCLK, USB_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | GCLK_PCHCTRL_CHEN); + hri_mclk_set_AHBMASK_USB_bit(MCLK); + hri_mclk_set_APBBMASK_USB_bit(MCLK); + + // USB Pin Init + gpio_set_pin_direction(PIN_PA24, GPIO_DIRECTION_OUT); + gpio_set_pin_level(PIN_PA24, false); + gpio_set_pin_pull_mode(PIN_PA24, GPIO_PULL_OFF); + gpio_set_pin_direction(PIN_PA25, GPIO_DIRECTION_OUT); + gpio_set_pin_level(PIN_PA25, false); + gpio_set_pin_pull_mode(PIN_PA25, GPIO_PULL_OFF); + + gpio_set_pin_function(PIN_PA24, PINMUX_PA24H_USB_DM); + gpio_set_pin_function(PIN_PA25, PINMUX_PA25H_USB_DP); + +#if CFG_TUH_ENABLED && CFG_TUH_MAX3421 + max3421_init(); +#endif +} + +void board_init_after_tusb(void) { +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) { + gpio_set_pin_level(LED_PIN, state); +} + +uint32_t board_button_read(void) { + // button is active low + #ifdef BUTTON_PIN + return gpio_get_pin_level(BUTTON_PIN) ? 0 : 1; + #else + return 0; + #endif +} + +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + (void) max_len; + + uint32_t did_addr[4] = {0x008061FC, 0x00806010, 0x00806014, 0x00806018}; + + for (int i = 0; i < 4; i++) { + uint32_t did = *((uint32_t const*) did_addr[i]); + did = TU_BSWAP32(did); // swap endian to match samd51 uf2 bootloader + memcpy(id + i * 4, &did, 4); + } + + return 16; +} + +int board_uart_read(uint8_t* buf, int len) { + (void) buf; + (void) len; + return 0; +} + +int board_uart_write(void const* buf, int len) { + (void) buf; + (void) len; + return 0; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; + +void SysTick_Handler(void) { + system_ticks++; +} + +uint32_t board_millis(void) { + return system_ticks; +} + +#if 0 +/* Initialize SERCOM2 for 115200 bps 8N1 using a 48 MHz clock */ +static inline void uart_init(void) { + gpio_set_pin_function(PIN_PB24, PINMUX_PB24D_SERCOM2_PAD1); + gpio_set_pin_function(PIN_PB25, PINMUX_PB25D_SERCOM2_PAD0); + + MCLK->APBBMASK.bit.SERCOM2_ = 1; + GCLK->PCHCTRL[SERCOM2_GCLK_ID_CORE].reg = GCLK_PCHCTRL_GEN_GCLK0 | GCLK_PCHCTRL_CHEN; + + BOARD_SERCOM->USART.CTRLA.bit.SWRST = 1; /* reset and disable SERCOM -> enable configuration */ + while (BOARD_SERCOM->USART.SYNCBUSY.bit.SWRST); + + BOARD_SERCOM->USART.CTRLA.reg = + SERCOM_USART_CTRLA_SAMPR(0) | /* 0 = 16x / arithmetic baud rate, 1 = 16x / fractional baud rate */ + SERCOM_USART_CTRLA_SAMPA(0) | /* 16x over sampling */ + SERCOM_USART_CTRLA_FORM(0) | /* 0x0 USART frame, 0x1 USART frame with parity, ... */ + SERCOM_USART_CTRLA_DORD | /* LSB first */ + SERCOM_USART_CTRLA_MODE(1) | /* 0x0 USART with external clock, 0x1 USART with internal clock */ + SERCOM_USART_CTRLA_RXPO(1) | /* SERCOM PAD[1] is used for data reception */ + SERCOM_USART_CTRLA_TXPO(0); /* SERCOM PAD[0] is used for data transmission */ + + BOARD_SERCOM->USART.CTRLB.reg = /* RXEM = 0 -> receiver disabled, LINCMD = 0 -> normal USART transmission, SFDE = 0 -> start-of-frame detection disabled, SBMODE = 0 -> one stop bit, CHSIZE = 0 -> 8 bits */ + SERCOM_USART_CTRLB_TXEN | /* transmitter enabled */ + SERCOM_USART_CTRLB_RXEN; /* receiver enabled */ + // BOARD_SERCOM->USART.BAUD.reg = SERCOM_USART_BAUD_FRAC_FP(0) | SERCOM_USART_BAUD_FRAC_BAUD(26); /* 48000000/(16*115200) = 26.041666667 */ + BOARD_SERCOM->USART.BAUD.reg = SERCOM_USART_BAUD_BAUD(63019); /* 65536*(1−16*115200/48000000) */ + + BOARD_SERCOM->USART.CTRLA.bit.ENABLE = 1; /* activate SERCOM */ + while (BOARD_SERCOM->USART.SYNCBUSY.bit.ENABLE); /* wait for SERCOM to be ready */ +} + +static inline void uart_send_buffer(uint8_t const* text, size_t len) { + for (size_t i = 0; i < len; ++i) { + BOARD_SERCOM->USART.DATA.reg = text[i]; + while ((BOARD_SERCOM->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_TXC) == 0); + } +} + +static inline void uart_send_str(const char* text) { + while (*text) { + BOARD_SERCOM->USART.DATA.reg = *text++; + while ((BOARD_SERCOM->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_TXC) == 0); + } +} + +#endif + +#endif + +//--------------------------------------------------------------------+ +// API: SPI transfer with MAX3421E, must be implemented by application +//--------------------------------------------------------------------+ +#if CFG_TUH_ENABLED && CFG_TUH_MAX3421 + +static void max3421_init(void) { + //------------- SPI Init -------------// + + // MAX3421E max SPI clock is 26MHz however SAMD can only work reliably at 12 Mhz + uint32_t const baudrate = 12000000u; + + struct { + volatile uint32_t* mck_apb; + uint32_t mask; + uint8_t gclk_id_core; + uint8_t gclk_id_slow; + } const sercom_clock[] = { + { &MCLK->APBAMASK.reg, MCLK_APBAMASK_SERCOM0, SERCOM0_GCLK_ID_CORE, SERCOM0_GCLK_ID_SLOW }, + { &MCLK->APBAMASK.reg, MCLK_APBAMASK_SERCOM1, SERCOM1_GCLK_ID_CORE, SERCOM1_GCLK_ID_SLOW }, + { &MCLK->APBBMASK.reg, MCLK_APBBMASK_SERCOM2, SERCOM2_GCLK_ID_CORE, SERCOM2_GCLK_ID_SLOW }, + { &MCLK->APBBMASK.reg, MCLK_APBBMASK_SERCOM3, SERCOM3_GCLK_ID_CORE, SERCOM3_GCLK_ID_SLOW }, + { &MCLK->APBDMASK.reg, MCLK_APBDMASK_SERCOM4, SERCOM4_GCLK_ID_CORE, SERCOM4_GCLK_ID_SLOW }, + { &MCLK->APBDMASK.reg, MCLK_APBDMASK_SERCOM5, SERCOM5_GCLK_ID_CORE, SERCOM5_GCLK_ID_SLOW }, + #ifdef SERCOM6_GCLK_ID_CORE + { &MCLK->APBDMASK.reg, MCLK_APBDMASK_SERCOM6, SERCOM6_GCLK_ID_CORE, SERCOM6_GCLK_ID_SLOW }, + #endif + #ifdef SERCOM7_GCLK_ID_CORE + { &MCLK->APBDMASK.reg, MCLK_APBDMASK_SERCOM7, SERCOM7_GCLK_ID_CORE, SERCOM7_GCLK_ID_SLOW }, + #endif + }; + + Sercom* sercom = MAX3421_SERCOM; + + // Enable the APB clock for SERCOM + *sercom_clock[MAX3421_SERCOM_ID].mck_apb |= sercom_clock[MAX3421_SERCOM_ID].mask; + + // Configure GCLK for SERCOM + GCLK->PCHCTRL[sercom_clock[MAX3421_SERCOM_ID].gclk_id_core].reg = + GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); + GCLK->PCHCTRL[sercom_clock[MAX3421_SERCOM_ID].gclk_id_slow].reg = + GCLK_PCHCTRL_GEN_GCLK3_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); + + // Disable the SPI module + sercom->SPI.CTRLA.bit.ENABLE = 0; + + // Reset the SPI module + sercom->SPI.CTRLA.bit.SWRST = 1; + while (sercom->SPI.SYNCBUSY.bit.SWRST); + + // Set up SPI in master mode, MSB first, SPI mode 0 + sercom->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_DOPO(MAX3421_TX_PAD) | SERCOM_SPI_CTRLA_DIPO(MAX3421_RX_PAD) | + SERCOM_SPI_CTRLA_MODE(3); + + sercom->SPI.CTRLB.reg = SERCOM_SPI_CTRLB_CHSIZE(0) | SERCOM_SPI_CTRLB_RXEN; + while (sercom->SPI.SYNCBUSY.bit.CTRLB == 1); + + // Set the baud rate + uint8_t baud_reg = (uint8_t) (SystemCoreClock / (2 * baudrate)); + if (baud_reg) { + baud_reg--; + } + + sercom->SPI.BAUD.reg = baud_reg; + + // Configure PA12 as MOSI (PAD0), PA13 as SCK (PAD1), PA14 as MISO (PAD2), function C (sercom) + gpio_set_pin_direction(MAX3421_SCK_PIN, GPIO_DIRECTION_OUT); + gpio_set_pin_pull_mode(MAX3421_SCK_PIN, GPIO_PULL_OFF); + gpio_set_pin_function(MAX3421_SCK_PIN, MAX3421_SERCOM_FUNCTION); + + gpio_set_pin_direction(MAX3421_MOSI_PIN, GPIO_DIRECTION_OUT); + gpio_set_pin_pull_mode(MAX3421_MOSI_PIN, GPIO_PULL_OFF); + gpio_set_pin_function(MAX3421_MOSI_PIN, MAX3421_SERCOM_FUNCTION); + + gpio_set_pin_direction(MAX3421_MISO_PIN, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(MAX3421_MISO_PIN, GPIO_PULL_OFF); + gpio_set_pin_function(MAX3421_MISO_PIN, MAX3421_SERCOM_FUNCTION); + + // CS pin + gpio_set_pin_direction(MAX3421_CS_PIN, GPIO_DIRECTION_OUT); + gpio_set_pin_level(MAX3421_CS_PIN, 1); + + // Enable the SPI module + sercom->SPI.CTRLA.bit.ENABLE = 1; + while (sercom->SPI.SYNCBUSY.bit.ENABLE) {} + + //------------- External Interrupt -------------// + + // Enable the APB clock for EIC (External Interrupt Controller) + MCLK->APBAMASK.reg |= MCLK_APBAMASK_EIC; + + // Configure GCLK for EIC + GCLK->PCHCTRL[EIC_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); + + // Configure PA20 as an input with function A (external interrupt) + gpio_set_pin_direction(MAX3421_INTR_PIN, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(MAX3421_INTR_PIN, GPIO_PULL_UP); + gpio_set_pin_function(MAX3421_INTR_PIN, 0); + + // Disable EIC + EIC->CTRLA.bit.ENABLE = 0; + while (EIC->SYNCBUSY.bit.ENABLE); + + // Configure EIC to trigger on falling edge + volatile uint32_t* eic_config; + uint8_t sense_shift; + if (MAX3421_INTR_EIC_ID < 8) { + eic_config = &EIC->CONFIG[0].reg; + sense_shift = MAX3421_INTR_EIC_ID * 4; + } else { + eic_config = &EIC->CONFIG[1].reg; + sense_shift = (MAX3421_INTR_EIC_ID - 8) * 4; + } + + *eic_config &= ~(7 << sense_shift); + *eic_config |= 2 << sense_shift; + +#if CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(EIC_0_IRQn + MAX3421_INTR_EIC_ID, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); +#endif + + // Enable External Interrupt + EIC->INTENSET.reg = EIC_INTENSET_EXTINT(1 << MAX3421_INTR_EIC_ID); + + // Enable EIC + EIC->CTRLA.bit.ENABLE = 1; + while (EIC->SYNCBUSY.bit.ENABLE); +} + +void MAX3421_EIC_Handler(void) { + // Clear the interrupt flag + EIC->INTFLAG.reg = EIC_INTFLAG_EXTINT(1 << MAX3421_INTR_EIC_ID); + + // Call the TinyUSB interrupt handler + tuh_int_handler(1, true); +} + +// API to enable/disable MAX3421 INTR pin interrupt +void tuh_max3421_int_api(uint8_t rhport, bool enabled) { + (void) rhport; + + const IRQn_Type irq = EIC_0_IRQn + MAX3421_INTR_EIC_ID; + if (enabled) { + NVIC_EnableIRQ(irq); + } else { + NVIC_DisableIRQ(irq); + } +} + +// API to control MAX3421 SPI CS +void tuh_max3421_spi_cs_api(uint8_t rhport, bool active) { + (void) rhport; + gpio_set_pin_level(MAX3421_CS_PIN, active ? 0 : 1); +} + +// API to transfer data with MAX3421 SPI +// Either tx_buf or rx_buf can be NULL, which means transfer is write or read only +bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const* tx_buf, uint8_t* rx_buf, size_t xfer_bytes) { + (void) rhport; + + Sercom* sercom = MAX3421_SERCOM; + + for (size_t count = 0; count < xfer_bytes; count++) { + // Wait for the transmit buffer to be empty + while (!sercom->SPI.INTFLAG.bit.DRE); + + // Write data to be transmitted + uint8_t data = 0x00; + if (tx_buf) { + data = tx_buf[count]; + } + + sercom->SPI.DATA.reg = (uint32_t) data; + + // Wait for the receive buffer to be filled + while (!sercom->SPI.INTFLAG.bit.RXC); + + // Read received data + data = (uint8_t) sercom->SPI.DATA.reg; + if (rx_buf) { + rx_buf[count] = data; + } + } + + // wait for bus idle and clear flags + while (!(sercom->SPI.INTFLAG.reg & (SERCOM_SPI_INTFLAG_TXC | SERCOM_SPI_INTFLAG_DRE))); + sercom->SPI.INTFLAG.reg = SERCOM_SPI_INTFLAG_TXC | SERCOM_SPI_INTFLAG_DRE; + + return true; +} + +#endif + +void HardFault_Handler(void) { + __BKPT(0); + while (1); +} diff --git a/hw/bsp/samd5x_e5x/family.cmake b/hw/bsp/samd5x_e5x/family.cmake new file mode 100644 index 000000000..fd95ce10e --- /dev/null +++ b/hw/bsp/samd5x_e5x/family.cmake @@ -0,0 +1,109 @@ +include_guard() + +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +set(SDK_DIR ${TOP}/hw/mcu/microchip/${SAM_FAMILY}) +set(CMSIS_5 ${TOP}/lib/CMSIS_5) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR cortex-m4 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS SAMD51 SAME54 CACHE INTERNAL "") +set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -c \"transport select swd\" -c \"set CHIPNAME samd51\" -f target/atsame5x.cfg") + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif () + + set(LD_FILE_Clang ${LD_FILE_GNU}) + if (NOT DEFINED LD_FILE_${CMAKE_C_COMPILER_ID}) + message(FATAL_ERROR "LD_FILE_${CMAKE_C_COMPILER_ID} not defined") + endif () + + set(STARTUP_FILE_GNU ${SDK_DIR}/gcc/gcc/startup_${SAM_FAMILY}.c) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${SDK_DIR}/gcc/system_${SAM_FAMILY}.c + ${SDK_DIR}/hal/src/hal_atomic.c + ${SDK_DIR}/hpl/gclk/hpl_gclk.c + ${SDK_DIR}/hpl/mclk/hpl_mclk.c + ${SDK_DIR}/hpl/osc32kctrl/hpl_osc32kctrl.c + ${SDK_DIR}/hpl/oscctrl/hpl_oscctrl.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_DIR} + ${SDK_DIR}/config + ${SDK_DIR}/include + ${SDK_DIR}/hal/include + ${SDK_DIR}/hal/utils/include + ${SDK_DIR}/hpl/port + ${SDK_DIR}/hri + ${CMSIS_5}/CMSIS/Core/Include + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + 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_SAMD51 ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/microchip/samd/dcd_samd.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_add_bin_hex(${TARGET}) + family_flash_jlink(${TARGET}) + #family_flash_openocd(${TARGET}) +endfunction() diff --git a/hw/bsp/samd5x_e5x/family.mk b/hw/bsp/samd5x_e5x/family.mk new file mode 100644 index 000000000..9b1a23db4 --- /dev/null +++ b/hw/bsp/samd5x_e5x/family.mk @@ -0,0 +1,51 @@ +UF2_FAMILY_ID = 0x55114460 + +include $(TOP)/$(BOARD_PATH)/board.mk +CPU_CORE ?= cortex-m4 + +SDK_DIR = hw/mcu/microchip/${SAM_FAMILY} + +CFLAGS += \ + -flto \ + -DCFG_TUSB_MCU=OPT_MCU_SAMD51 + +# SAM driver is flooded with -Wcast-qual which slow down complication significantly +CFLAGS_SKIP += -Wcast-qual + +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs + +SRC_C += \ + src/portable/microchip/samd/dcd_samd.c \ + ${SDK_DIR}/gcc/gcc/startup_${SAM_FAMILY}.c \ + ${SDK_DIR}/gcc/system_${SAM_FAMILY}.c \ + ${SDK_DIR}/hpl/gclk/hpl_gclk.c \ + ${SDK_DIR}/hpl/mclk/hpl_mclk.c \ + ${SDK_DIR}/hpl/osc32kctrl/hpl_osc32kctrl.c \ + ${SDK_DIR}/hpl/oscctrl/hpl_oscctrl.c \ + ${SDK_DIR}/hal/src/hal_atomic.c + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/${SDK_DIR} \ + $(TOP)/${SDK_DIR}/config \ + $(TOP)/${SDK_DIR}/include \ + $(TOP)/${SDK_DIR}/hal/include \ + $(TOP)/${SDK_DIR}/hal/utils/include \ + $(TOP)/${SDK_DIR}/hpl/port \ + $(TOP)/${SDK_DIR}/hri \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + +# flash using bossac at least version 1.8 +# can be found in arduino15/packages/arduino/tools/bossac/ +# Add it to your PATH or change BOSSAC variable to match your installation +BOSSAC = bossac + +flash-bossac: $(BUILD)/$(PROJECT).bin + @:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyACM0) + $(BOSSAC) --port=$(SERIAL) -U -i --offset=0x4000 -e -w $^ -R + +# flash using edbg from https://github.com/ataradov/edbg +flash-edbg: $(BUILD)/$(PROJECT).bin + edbg --verbose -t $(MCU) -pv -f $< diff --git a/hw/bsp/same5x/boards/d5035_01/d5035_01.c b/hw/bsp/same5x/boards/d5035_01/d5035_01.c deleted file mode 100644 index eb5768d0d..000000000 --- a/hw/bsp/same5x/boards/d5035_01/d5035_01.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Jean Gressmann - * - * 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. - * - */ - -#include -#include "bsp/board_api.h" - -#include - -#if CONF_CPU_FREQUENCY != 80000000 -# error "CONF_CPU_FREQUENCY" must 80000000 -#endif - -#if CONF_GCLK_USB_FREQUENCY != 48000000 -# error "CONF_GCLK_USB_FREQUENCY" must 48000000 -#endif - -#if !defined(HWREV) -# error Define "HWREV" -#endif - -//--------------------------------------------------------------------+ -// Forward USB interrupt events to TinyUSB IRQ Handler -//--------------------------------------------------------------------+ -void USB_0_Handler (void) -{ - tud_int_handler(0); -} - -void USB_1_Handler (void) -{ - tud_int_handler(0); -} - -void USB_2_Handler (void) -{ - tud_int_handler(0); -} - -void USB_3_Handler (void) -{ - tud_int_handler(0); -} - -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM DECLARATION -//--------------------------------------------------------------------+ -#define LED_PIN PIN_PA02 - -#if HWREV < 3 -# define BOARD_SERCOM SERCOM5 -#else -# define BOARD_SERCOM SERCOM0 -#endif - -static inline void init_clock(void) -{ - /* AUTOWS is enabled by default in REG_NVMCTRL_CTRLA - no need to change the number of wait states when changing the core clock */ -#if HWREV == 1 - /* configure XOSC1 for a 16MHz crystal connected to XIN1/XOUT1 */ - OSCCTRL->XOSCCTRL[1].reg = - OSCCTRL_XOSCCTRL_STARTUP(6) | // 1,953 ms - OSCCTRL_XOSCCTRL_RUNSTDBY | - OSCCTRL_XOSCCTRL_ENALC | - OSCCTRL_XOSCCTRL_IMULT(4) | - OSCCTRL_XOSCCTRL_IPTAT(3) | - OSCCTRL_XOSCCTRL_XTALEN | - OSCCTRL_XOSCCTRL_ENABLE; - while(0 == OSCCTRL->STATUS.bit.XOSCRDY1); - - OSCCTRL->Dpll[0].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_DIV(3) | OSCCTRL_DPLLCTRLB_REFCLK(OSCCTRL_DPLLCTRLB_REFCLK_XOSC1_Val); /* pre-scaler = 8, input = XOSC1 */ - OSCCTRL->Dpll[0].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0x0) | OSCCTRL_DPLLRATIO_LDR(39); /* multiply by 40 -> 80 MHz */ - OSCCTRL->Dpll[0].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_RUNSTDBY | OSCCTRL_DPLLCTRLA_ENABLE; - while(0 == OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY); /* wait for the PLL0 to be ready */ - - OSCCTRL->Dpll[1].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_DIV(7) | OSCCTRL_DPLLCTRLB_REFCLK(OSCCTRL_DPLLCTRLB_REFCLK_XOSC1_Val); /* pre-scaler = 16, input = XOSC1 */ - OSCCTRL->Dpll[1].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0x0) | OSCCTRL_DPLLRATIO_LDR(47); /* multiply by 48 -> 48 MHz */ - OSCCTRL->Dpll[1].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_RUNSTDBY | OSCCTRL_DPLLCTRLA_ENABLE; - while(0 == OSCCTRL->Dpll[1].DPLLSTATUS.bit.CLKRDY); /* wait for the PLL1 to be ready */ -#else // HWREV >= 1 - /* configure XOSC0 for a 16MHz crystal connected to XIN0/XOUT0 */ - OSCCTRL->XOSCCTRL[0].reg = - OSCCTRL_XOSCCTRL_STARTUP(6) | // 1,953 ms - OSCCTRL_XOSCCTRL_RUNSTDBY | - OSCCTRL_XOSCCTRL_ENALC | - OSCCTRL_XOSCCTRL_IMULT(4) | - OSCCTRL_XOSCCTRL_IPTAT(3) | - OSCCTRL_XOSCCTRL_XTALEN | - OSCCTRL_XOSCCTRL_ENABLE; - while(0 == OSCCTRL->STATUS.bit.XOSCRDY0); - - OSCCTRL->Dpll[0].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_DIV(3) | OSCCTRL_DPLLCTRLB_REFCLK(OSCCTRL_DPLLCTRLB_REFCLK_XOSC0_Val); /* pre-scaler = 8, input = XOSC1 */ - OSCCTRL->Dpll[0].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0x0) | OSCCTRL_DPLLRATIO_LDR(39); /* multiply by 40 -> 80 MHz */ - OSCCTRL->Dpll[0].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_RUNSTDBY | OSCCTRL_DPLLCTRLA_ENABLE; - while(0 == OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY); /* wait for the PLL0 to be ready */ - - OSCCTRL->Dpll[1].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_DIV(7) | OSCCTRL_DPLLCTRLB_REFCLK(OSCCTRL_DPLLCTRLB_REFCLK_XOSC0_Val); /* pre-scaler = 16, input = XOSC1 */ - OSCCTRL->Dpll[1].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0x0) | OSCCTRL_DPLLRATIO_LDR(47); /* multiply by 48 -> 48 MHz */ - OSCCTRL->Dpll[1].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_RUNSTDBY | OSCCTRL_DPLLCTRLA_ENABLE; - while(0 == OSCCTRL->Dpll[1].DPLLSTATUS.bit.CLKRDY); /* wait for the PLL1 to be ready */ -#endif // HWREV - - /* configure clock-generator 0 to use DPLL0 as source -> GCLK0 is used for the core */ - GCLK->GENCTRL[0].reg = - GCLK_GENCTRL_DIV(0) | - GCLK_GENCTRL_RUNSTDBY | - GCLK_GENCTRL_GENEN | - GCLK_GENCTRL_SRC_DPLL0 | /* DPLL0 */ - GCLK_GENCTRL_IDC ; - while(1 == GCLK->SYNCBUSY.bit.GENCTRL0); /* wait for the synchronization between clock domains to be complete */ - - /* configure clock-generator 1 to use DPLL1 as source -> for use with some peripheral */ - GCLK->GENCTRL[1].reg = - GCLK_GENCTRL_DIV(0) | - GCLK_GENCTRL_RUNSTDBY | - GCLK_GENCTRL_GENEN | - GCLK_GENCTRL_SRC_DPLL1 | - GCLK_GENCTRL_IDC ; - while(1 == GCLK->SYNCBUSY.bit.GENCTRL1); /* wait for the synchronization between clock domains to be complete */ - - /* configure clock-generator 2 to use DPLL0 as source -> for use with SERCOM */ - GCLK->GENCTRL[2].reg = - GCLK_GENCTRL_DIV(1) | /* 80MHz */ - GCLK_GENCTRL_RUNSTDBY | - GCLK_GENCTRL_GENEN | - GCLK_GENCTRL_SRC_DPLL0 | - GCLK_GENCTRL_IDC ; - while(1 == GCLK->SYNCBUSY.bit.GENCTRL2); /* wait for the synchronization between clock domains to be complete */ -} - -static inline void uart_init(void) -{ -#if HWREV < 3 - /* configure SERCOM5 on PB02 */ - PORT->Group[1].WRCONFIG.reg = - PORT_WRCONFIG_WRPINCFG | - PORT_WRCONFIG_WRPMUX | - PORT_WRCONFIG_PMUX(3) | /* function D */ - PORT_WRCONFIG_DRVSTR | - PORT_WRCONFIG_PINMASK(0x0004) | /* PB02 */ - PORT_WRCONFIG_PMUXEN; - - MCLK->APBDMASK.bit.SERCOM5_ = 1; - GCLK->PCHCTRL[SERCOM5_GCLK_ID_CORE].reg = GCLK_PCHCTRL_GEN_GCLK2 | GCLK_PCHCTRL_CHEN; /* setup SERCOM to use GLCK2 -> 80MHz */ - - SERCOM5->USART.CTRLA.reg = 0x00; /* disable SERCOM -> enable config */ - while(SERCOM5->USART.SYNCBUSY.bit.ENABLE); - - SERCOM5->USART.CTRLA.reg = /* CMODE = 0 -> async, SAMPA = 0, FORM = 0 -> USART frame, SMPR = 0 -> arithmetic baud rate */ - SERCOM_USART_CTRLA_SAMPR(1) | /* 0 = 16x / arithmetic baud rate, 1 = 16x / fractional baud rate */ -// SERCOM_USART_CTRLA_FORM(0) | /* 0 = USART Frame, 2 = LIN Master */ - SERCOM_USART_CTRLA_DORD | /* LSB first */ - SERCOM_USART_CTRLA_MODE(1) | /* 0 = Asynchronous, 1 = USART with internal clock */ - SERCOM_USART_CTRLA_RXPO(1) | /* SERCOM PAD[1] is used for data reception */ - SERCOM_USART_CTRLA_TXPO(0); /* SERCOM PAD[0] is used for data transmission */ - - SERCOM5->USART.CTRLB.reg = /* RXEM = 0 -> receiver disabled, LINCMD = 0 -> normal USART transmission, SFDE = 0 -> start-of-frame detection disabled, SBMODE = 0 -> one stop bit, CHSIZE = 0 -> 8 bits */ - SERCOM_USART_CTRLB_TXEN; /* transmitter enabled */ - SERCOM5->USART.CTRLC.reg = 0x00; - // 21.701388889 @ baud rate of 230400 bit/s, table 33-2, p 918 of DS60001507E - SERCOM5->USART.BAUD.reg = SERCOM_USART_BAUD_FRAC_FP(7) | SERCOM_USART_BAUD_FRAC_BAUD(21); - -// SERCOM5->USART.INTENSET.reg = SERCOM_USART_INTENSET_TXC; - SERCOM5->SPI.CTRLA.bit.ENABLE = 1; /* activate SERCOM */ - while(SERCOM5->USART.SYNCBUSY.bit.ENABLE); /* wait for SERCOM to be ready */ -#else -/* configure SERCOM0 on PA08 */ - PORT->Group[0].WRCONFIG.reg = - PORT_WRCONFIG_WRPINCFG | - PORT_WRCONFIG_WRPMUX | - PORT_WRCONFIG_PMUX(2) | /* function C */ - PORT_WRCONFIG_DRVSTR | - PORT_WRCONFIG_PINMASK(0x0100) | /* PA08 */ - PORT_WRCONFIG_PMUXEN; - - MCLK->APBAMASK.bit.SERCOM0_ = 1; - GCLK->PCHCTRL[SERCOM0_GCLK_ID_CORE].reg = GCLK_PCHCTRL_GEN_GCLK2 | GCLK_PCHCTRL_CHEN; /* setup SERCOM to use GLCK2 -> 80MHz */ - - SERCOM0->USART.CTRLA.reg = 0x00; /* disable SERCOM -> enable config */ - while(SERCOM0->USART.SYNCBUSY.bit.ENABLE); - - SERCOM0->USART.CTRLA.reg = /* CMODE = 0 -> async, SAMPA = 0, FORM = 0 -> USART frame, SMPR = 0 -> arithmetic baud rate */ - SERCOM_USART_CTRLA_SAMPR(1) | /* 0 = 16x / arithmetic baud rate, 1 = 16x / fractional baud rate */ -// SERCOM_USART_CTRLA_FORM(0) | /* 0 = USART Frame, 2 = LIN Master */ - SERCOM_USART_CTRLA_DORD | /* LSB first */ - SERCOM_USART_CTRLA_MODE(1) | /* 0 = Asynchronous, 1 = USART with internal clock */ - SERCOM_USART_CTRLA_RXPO(1) | /* SERCOM PAD[1] is used for data reception */ - SERCOM_USART_CTRLA_TXPO(0); /* SERCOM PAD[0] is used for data transmission */ - - SERCOM0->USART.CTRLB.reg = /* RXEM = 0 -> receiver disabled, LINCMD = 0 -> normal USART transmission, SFDE = 0 -> start-of-frame detection disabled, SBMODE = 0 -> one stop bit, CHSIZE = 0 -> 8 bits */ - SERCOM_USART_CTRLB_TXEN; /* transmitter enabled */ - SERCOM0->USART.CTRLC.reg = 0x00; - // 21.701388889 @ baud rate of 230400 bit/s, table 33-2, p 918 of DS60001507E - SERCOM0->USART.BAUD.reg = SERCOM_USART_BAUD_FRAC_FP(7) | SERCOM_USART_BAUD_FRAC_BAUD(21); - -// SERCOM0->USART.INTENSET.reg = SERCOM_USART_INTENSET_TXC; - SERCOM0->SPI.CTRLA.bit.ENABLE = 1; /* activate SERCOM */ - while(SERCOM0->USART.SYNCBUSY.bit.ENABLE); /* wait for SERCOM to be ready */ -#endif -} - -static inline void uart_send_buffer(uint8_t const *text, size_t len) -{ - for (size_t i = 0; i < len; ++i) { - BOARD_SERCOM->USART.DATA.reg = text[i]; - while((BOARD_SERCOM->USART.INTFLAG.reg & SERCOM_SPI_INTFLAG_TXC) == 0); - } -} - -static inline void uart_send_str(const char* text) -{ - while (*text) { - BOARD_SERCOM->USART.DATA.reg = *text++; - while((BOARD_SERCOM->USART.INTFLAG.reg & SERCOM_SPI_INTFLAG_TXC) == 0); - } -} - - -void board_init(void) -{ - init_clock(); - - SystemCoreClock = CONF_CPU_FREQUENCY; - -#if CFG_TUSB_OS == OPT_OS_NONE - SysTick_Config(CONF_CPU_FREQUENCY / 1000); -#endif - - uart_init(); -#if CFG_TUSB_DEBUG >= 2 - uart_send_str(BOARD_NAME " UART initialized\n"); - tu_printf(BOARD_NAME " reset cause %#02x\n", RSTC->RCAUSE.reg); -#endif - - // Led init - gpio_set_pin_direction(LED_PIN, GPIO_DIRECTION_OUT); - gpio_set_pin_level(LED_PIN, 0); - -#if CFG_TUSB_DEBUG >= 2 - uart_send_str(BOARD_NAME " LED pin configured\n"); -#endif - -#if CFG_TUSB_OS == OPT_OS_FREERTOS - // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) - NVIC_SetPriority(USB_0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); - NVIC_SetPriority(USB_1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); - NVIC_SetPriority(USB_2_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); - NVIC_SetPriority(USB_3_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); -#endif - - -#if CFG_TUD_ENABLED -#if CFG_TUSB_DEBUG >= 2 - uart_send_str(BOARD_NAME " USB device enabled\n"); -#endif - - /* USB clock init - * The USB module requires a GCLK_USB of 48 MHz ~ 0.25% clock - * for low speed and full speed operation. */ - hri_gclk_write_PCHCTRL_reg(GCLK, USB_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | GCLK_PCHCTRL_CHEN); - hri_mclk_set_AHBMASK_USB_bit(MCLK); - hri_mclk_set_APBBMASK_USB_bit(MCLK); - - // USB pin init - gpio_set_pin_direction(PIN_PA24, GPIO_DIRECTION_OUT); - gpio_set_pin_level(PIN_PA24, false); - gpio_set_pin_pull_mode(PIN_PA24, GPIO_PULL_OFF); - gpio_set_pin_direction(PIN_PA25, GPIO_DIRECTION_OUT); - gpio_set_pin_level(PIN_PA25, false); - gpio_set_pin_pull_mode(PIN_PA25, GPIO_PULL_OFF); - - gpio_set_pin_function(PIN_PA24, PINMUX_PA24H_USB_DM); - gpio_set_pin_function(PIN_PA25, PINMUX_PA25H_USB_DP); - - -#if CFG_TUSB_DEBUG >= 2 - uart_send_str(BOARD_NAME " USB device configured\n"); -#endif -#endif -} - -//--------------------------------------------------------------------+ -// Board porting API -//--------------------------------------------------------------------+ - -void board_led_write(bool state) -{ - gpio_set_pin_level(LED_PIN, state); -} - -uint32_t board_button_read(void) -{ - // this board has no button - return 0; -} - -int board_uart_read(uint8_t* buf, int len) -{ - (void) buf; (void) len; - return 0; -} - -int board_uart_write(void const * buf, int len) -{ - if (len < 0) { - uart_send_str(buf); - } else { - uart_send_buffer(buf, len); - } - return len; -} - -#if CFG_TUSB_OS == OPT_OS_NONE -volatile uint32_t system_ticks = 0; - -void SysTick_Handler(void) -{ - system_ticks++; -} - -uint32_t board_millis(void) -{ - return system_ticks; -} -#endif - -// Required by __libc_init_array in startup code if we are compiling using -// -nostdlib/-nostartfiles. -void _init(void) -{ - -} diff --git a/hw/bsp/same5x/boards/same54_xplained/same54_xplained.c b/hw/bsp/same5x/boards/same54_xplained/same54_xplained.c deleted file mode 100644 index 93adea63e..000000000 --- a/hw/bsp/same5x/boards/same54_xplained/same54_xplained.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2021 Jean Gressmann - * - * 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. - * - */ - -#include -#include "bsp/board_api.h" - -#include - - -//--------------------------------------------------------------------+ -// Forward USB interrupt events to TinyUSB IRQ Handler -//--------------------------------------------------------------------+ -void USB_0_Handler(void) -{ - tud_int_handler(0); -} - -void USB_1_Handler(void) -{ - tud_int_handler(0); -} - -void USB_2_Handler(void) -{ - tud_int_handler(0); -} - -void USB_3_Handler(void) -{ - tud_int_handler(0); -} - -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM DECLARATION -//--------------------------------------------------------------------+ -#define LED_PIN PIN_PC18 -#define BUTTON_PIN PIN_PB31 -#define BOARD_SERCOM SERCOM2 - -/** Initializes the clocks from the external 12 MHz crystal - * - * The goal of this setup is to preserve the second PLL - * for the application code while still having a reasonable - * 48 MHz clock for USB / UART. - * - * GCLK0: CONF_CPU_FREQUENCY (default 120 MHz) from PLL0 - * GCLK1: unused - * GCLK2: 12 MHz from XOSC1 - * DFLL48M: closed loop from GLCK2 - * GCLK3: 48 MHz - */ -static inline void init_clock_xtal(void) -{ - /* configure for a 12MHz crystal connected to XIN1/XOUT1 */ - OSCCTRL->XOSCCTRL[1].reg = - OSCCTRL_XOSCCTRL_STARTUP(6) | // 1.953 ms - OSCCTRL_XOSCCTRL_RUNSTDBY | - OSCCTRL_XOSCCTRL_ENALC | - OSCCTRL_XOSCCTRL_IMULT(4) | OSCCTRL_XOSCCTRL_IPTAT(3) | // 8MHz to 16MHz - OSCCTRL_XOSCCTRL_XTALEN | - OSCCTRL_XOSCCTRL_ENABLE; - while(0 == OSCCTRL->STATUS.bit.XOSCRDY1); - - OSCCTRL->Dpll[0].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_DIV(2) | OSCCTRL_DPLLCTRLB_REFCLK_XOSC1; /* 12MHz / 6 = 2Mhz, input = XOSC1 */ - OSCCTRL->Dpll[0].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0x0) | OSCCTRL_DPLLRATIO_LDR((CONF_CPU_FREQUENCY / 1000000 / 2) - 1); /* multiply to get CONF_CPU_FREQUENCY (default = 120MHz) */ - OSCCTRL->Dpll[0].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_RUNSTDBY | OSCCTRL_DPLLCTRLA_ENABLE; - while(0 == OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY); /* wait for the PLL0 to be ready */ - - /* configure clock-generator 0 to use DPLL0 as source -> GCLK0 is used for the core */ - GCLK->GENCTRL[0].reg = - GCLK_GENCTRL_DIV(0) | - GCLK_GENCTRL_RUNSTDBY | - GCLK_GENCTRL_GENEN | - GCLK_GENCTRL_SRC_DPLL0 | - GCLK_GENCTRL_IDC; - while(1 == GCLK->SYNCBUSY.bit.GENCTRL0); /* wait for the synchronization between clock domains to be complete */ - - // configure GCLK2 for 12MHz from XOSC1 - GCLK->GENCTRL[2].reg = - GCLK_GENCTRL_DIV(0) | - GCLK_GENCTRL_RUNSTDBY | - GCLK_GENCTRL_GENEN | - GCLK_GENCTRL_SRC_XOSC1 | - GCLK_GENCTRL_IDC; - while(1 == GCLK->SYNCBUSY.bit.GENCTRL2); /* wait for the synchronization between clock domains to be complete */ - - /* setup DFLL48M to use GLCK2 */ - GCLK->PCHCTRL[OSCCTRL_GCLK_ID_DFLL48].reg = GCLK_PCHCTRL_GEN_GCLK2 | GCLK_PCHCTRL_CHEN; - - OSCCTRL->DFLLCTRLA.reg = 0; - while(1 == OSCCTRL->DFLLSYNC.bit.ENABLE); - - OSCCTRL->DFLLCTRLB.reg = OSCCTRL_DFLLCTRLB_MODE | OSCCTRL_DFLLCTRLB_WAITLOCK; - OSCCTRL->DFLLMUL.bit.MUL = 4; // 4 * 12MHz -> 48MHz - - OSCCTRL->DFLLCTRLA.reg = - OSCCTRL_DFLLCTRLA_ENABLE | - OSCCTRL_DFLLCTRLA_RUNSTDBY; - while(1 == OSCCTRL->DFLLSYNC.bit.ENABLE); - - // setup 48 MHz GCLK3 from DFLL48M - GCLK->GENCTRL[3].reg = - GCLK_GENCTRL_DIV(0) | - GCLK_GENCTRL_RUNSTDBY | - GCLK_GENCTRL_GENEN | - GCLK_GENCTRL_SRC_DFLL | - GCLK_GENCTRL_IDC; - while(1 == GCLK->SYNCBUSY.bit.GENCTRL3); -} - -/* Initialize SERCOM2 for 115200 bps 8N1 using a 48 MHz clock */ -static inline void uart_init(void) -{ - gpio_set_pin_function(PIN_PB24, PINMUX_PB24D_SERCOM2_PAD1); - gpio_set_pin_function(PIN_PB25, PINMUX_PB25D_SERCOM2_PAD0); - - MCLK->APBBMASK.bit.SERCOM2_ = 1; - GCLK->PCHCTRL[SERCOM2_GCLK_ID_CORE].reg = GCLK_PCHCTRL_GEN_GCLK0 | GCLK_PCHCTRL_CHEN; - - BOARD_SERCOM->USART.CTRLA.bit.SWRST = 1; /* reset and disable SERCOM -> enable configuration */ - while (BOARD_SERCOM->USART.SYNCBUSY.bit.SWRST); - - BOARD_SERCOM->USART.CTRLA.reg = - SERCOM_USART_CTRLA_SAMPR(0) | /* 0 = 16x / arithmetic baud rate, 1 = 16x / fractional baud rate */ - SERCOM_USART_CTRLA_SAMPA(0) | /* 16x over sampling */ - SERCOM_USART_CTRLA_FORM(0) | /* 0x0 USART frame, 0x1 USART frame with parity, ... */ - SERCOM_USART_CTRLA_DORD | /* LSB first */ - SERCOM_USART_CTRLA_MODE(1) | /* 0x0 USART with external clock, 0x1 USART with internal clock */ - SERCOM_USART_CTRLA_RXPO(1) | /* SERCOM PAD[1] is used for data reception */ - SERCOM_USART_CTRLA_TXPO(0); /* SERCOM PAD[0] is used for data transmission */ - - BOARD_SERCOM->USART.CTRLB.reg = /* RXEM = 0 -> receiver disabled, LINCMD = 0 -> normal USART transmission, SFDE = 0 -> start-of-frame detection disabled, SBMODE = 0 -> one stop bit, CHSIZE = 0 -> 8 bits */ - SERCOM_USART_CTRLB_TXEN | /* transmitter enabled */ - SERCOM_USART_CTRLB_RXEN; /* receiver enabled */ - // BOARD_SERCOM->USART.BAUD.reg = SERCOM_USART_BAUD_FRAC_FP(0) | SERCOM_USART_BAUD_FRAC_BAUD(26); /* 48000000/(16*115200) = 26.041666667 */ - BOARD_SERCOM->USART.BAUD.reg = SERCOM_USART_BAUD_BAUD(63019); /* 65536*(1−16*115200/48000000) */ - - BOARD_SERCOM->USART.CTRLA.bit.ENABLE = 1; /* activate SERCOM */ - while (BOARD_SERCOM->USART.SYNCBUSY.bit.ENABLE); /* wait for SERCOM to be ready */ -} - -static inline void uart_send_buffer(uint8_t const *text, size_t len) -{ - for (size_t i = 0; i < len; ++i) { - BOARD_SERCOM->USART.DATA.reg = text[i]; - while((BOARD_SERCOM->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_TXC) == 0); - } -} - -static inline void uart_send_str(const char* text) -{ - while (*text) { - BOARD_SERCOM->USART.DATA.reg = *text++; - while((BOARD_SERCOM->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_TXC) == 0); - } -} - - -void board_init(void) -{ - // Uncomment this line and change the GCLK for UART/USB to run off the XTAL. - // init_clock_xtal(); - - SystemCoreClock = CONF_CPU_FREQUENCY; - -#if CFG_TUSB_OS == OPT_OS_NONE - SysTick_Config(CONF_CPU_FREQUENCY / 1000); -#endif - - uart_init(); - -#if CFG_TUSB_DEBUG >= 2 - uart_send_str(BOARD_NAME " UART initialized\n"); - tu_printf(BOARD_NAME " reset cause %#02x\n", RSTC->RCAUSE.reg); -#endif - - // LED0 init - gpio_set_pin_function(LED_PIN, GPIO_PIN_FUNCTION_OFF); - gpio_set_pin_direction(LED_PIN, GPIO_DIRECTION_OUT); - board_led_write(0); - -#if CFG_TUSB_DEBUG >= 2 - uart_send_str(BOARD_NAME " LED pin configured\n"); -#endif - - // BTN0 init - gpio_set_pin_function(BUTTON_PIN, GPIO_PIN_FUNCTION_OFF); - gpio_set_pin_direction(BUTTON_PIN, GPIO_DIRECTION_IN); - gpio_set_pin_pull_mode(BUTTON_PIN, GPIO_PULL_UP); - -#if CFG_TUSB_DEBUG >= 2 - uart_send_str(BOARD_NAME " Button pin configured\n"); -#endif - -#if CFG_TUSB_OS == OPT_OS_FREERTOS - // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) - NVIC_SetPriority(USB_0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); - NVIC_SetPriority(USB_1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); - NVIC_SetPriority(USB_2_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); - NVIC_SetPriority(USB_3_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); -#endif - - -#if CFG_TUD_ENABLED -#if CFG_TUSB_DEBUG >= 2 - uart_send_str(BOARD_NAME " USB device enabled\n"); -#endif - - /* USB clock init - * The USB module requires a GCLK_USB of 48 MHz ~ 0.25% clock - * for low speed and full speed operation. - */ - hri_gclk_write_PCHCTRL_reg(GCLK, USB_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK0_Val | GCLK_PCHCTRL_CHEN); - hri_mclk_set_AHBMASK_USB_bit(MCLK); - hri_mclk_set_APBBMASK_USB_bit(MCLK); - - // USB pin init - gpio_set_pin_direction(PIN_PA24, GPIO_DIRECTION_OUT); - gpio_set_pin_level(PIN_PA24, false); - gpio_set_pin_pull_mode(PIN_PA24, GPIO_PULL_OFF); - gpio_set_pin_direction(PIN_PA25, GPIO_DIRECTION_OUT); - gpio_set_pin_level(PIN_PA25, false); - gpio_set_pin_pull_mode(PIN_PA25, GPIO_PULL_OFF); - - gpio_set_pin_function(PIN_PA24, PINMUX_PA24H_USB_DM); - gpio_set_pin_function(PIN_PA25, PINMUX_PA25H_USB_DP); - - -#if CFG_TUSB_DEBUG >= 2 - uart_send_str(BOARD_NAME " USB device configured\n"); -#endif -#endif -} - -//--------------------------------------------------------------------+ -// Board porting API -//--------------------------------------------------------------------+ - -void board_led_write(bool state) -{ - gpio_set_pin_level(LED_PIN, !state); -} - -uint32_t board_button_read(void) -{ - return (PORT->Group[1].IN.reg & 0x80000000) != 0x80000000; -} - -int board_uart_read(uint8_t* buf, int len) -{ - (void) buf; (void) len; - return 0; -} - -int board_uart_write(void const * buf, int len) -{ - if (len < 0) { - uart_send_str(buf); - } else { - uart_send_buffer(buf, len); - } - return len; -} - -#if CFG_TUSB_OS == OPT_OS_NONE -volatile uint32_t system_ticks = 0; - -void SysTick_Handler(void) -{ - system_ticks++; -} - -uint32_t board_millis(void) -{ - return system_ticks; -} -#endif - -// Required by __libc_init_array in startup code if we are compiling using -// -nostdlib/-nostartfiles. -void _init(void) -{ - -} diff --git a/hw/bsp/same5x/family.mk b/hw/bsp/same5x/family.mk deleted file mode 100644 index 691863f11..000000000 --- a/hw/bsp/same5x/family.mk +++ /dev/null @@ -1,36 +0,0 @@ -DEPS_SUBMODULES += hw/mcu/microchip - -SDK_DIR = hw/mcu/microchip/$(MCU) -include $(TOP)/$(BOARD_PATH)/board.mk -CPU_CORE ?= cortex-m4 - -CFLAGS += \ - -mthumb \ - -mlong-calls \ - -nostdlib -nostartfiles \ - -DCFG_TUSB_MCU=OPT_MCU_SAME5X - -# SAM driver is flooded with -Wcast-qual which slow down complication significantly -CFLAGS_SKIP += -Wcast-qual - -SRC_C += \ - src/portable/microchip/samd/dcd_samd.c \ - $(SDK_DIR)/gcc/gcc/startup_$(MCU).c \ - $(SDK_DIR)/gcc/system_$(MCU).c \ - $(SDK_DIR)/hal/utils/src/utils_syscalls.c - -INC += \ - $(TOP)/$(SDK_DIR) \ - $(TOP)/$(SDK_DIR)/config \ - $(TOP)/$(SDK_DIR)/include \ - $(TOP)/$(SDK_DIR)/hal/include \ - $(TOP)/$(SDK_DIR)/hal/utils/include \ - $(TOP)/$(SDK_DIR)/hpl/port \ - $(TOP)/$(SDK_DIR)/hri \ - $(TOP)/$(SDK_DIR)/CMSIS/Include - -# flash using edbg from https://github.com/ataradov/edbg -flash-edbg: $(BUILD)/$(PROJECT).bin - edbg --verbose -t $(MCU) -pv -f $< - -flash: flash-edbg diff --git a/hw/bsp/same70_qmtech/board.mk b/hw/bsp/same70_qmtech/board.mk index ad5af2020..281a947f3 100644 --- a/hw/bsp/same70_qmtech/board.mk +++ b/hw/bsp/same70_qmtech/board.mk @@ -1,4 +1,5 @@ DEPS_SUBMODULES += hw/mcu/microchip +ASF_DIR = hw/mcu/microchip/same70 CFLAGS += \ -mthumb \ @@ -16,7 +17,7 @@ CFLAGS += -Wno-error=unused-parameter -Wno-error=cast-align -Wno-error=redundant # SAM driver is flooded with -Wcast-qual which slow down complication significantly CFLAGS_SKIP += -Wcast-qual -ASF_DIR = hw/mcu/microchip/same70 +LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs # All source paths should be relative to the top level. LD_FILE = $(ASF_DIR)/same70b/gcc/gcc/same70q21b_flash.ld diff --git a/hw/bsp/same70_xplained/board.mk b/hw/bsp/same70_xplained/board.mk index 769d03e21..3edc128a5 100644 --- a/hw/bsp/same70_xplained/board.mk +++ b/hw/bsp/same70_xplained/board.mk @@ -1,4 +1,5 @@ DEPS_SUBMODULES += hw/mcu/microchip +ASF_DIR = hw/mcu/microchip/same70 CFLAGS += \ -mthumb \ @@ -16,7 +17,7 @@ CFLAGS += -Wno-error=unused-parameter -Wno-error=cast-align -Wno-error=redundant # SAM driver is flooded with -Wcast-qual which slow down complication significantly CFLAGS_SKIP += -Wcast-qual -ASF_DIR = hw/mcu/microchip/same70 +LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs # All source paths should be relative to the top level. LD_FILE = $(ASF_DIR)/same70b/gcc/gcc/same70q21b_flash.ld diff --git a/hw/bsp/samg/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/samg/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..02223f766 --- /dev/null +++ b/hw/bsp/samg/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,149 @@ +/* + * 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__ + extern uint32_t SystemCoreClock; +#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*6*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 4 +#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 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* 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 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* 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 + +/* 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 4 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< USB Clock Source // <0=> USB Clock Controller (USB_48M) diff --git a/hw/bsp/samg55xplained/board.mk b/hw/bsp/samg55xplained/board.mk deleted file mode 100644 index ed0d59772..000000000 --- a/hw/bsp/samg55xplained/board.mk +++ /dev/null @@ -1,55 +0,0 @@ -DEPS_SUBMODULES += hw/mcu/microchip - -CFLAGS += \ - -flto \ - -mthumb \ - -mabi=aapcs \ - -mcpu=cortex-m4 \ - -mfloat-abi=hard \ - -mfpu=fpv4-sp-d16 \ - -nostdlib -nostartfiles \ - -D__SAMG55J19__ \ - -DCFG_TUSB_MCU=OPT_MCU_SAMG - -# suppress following warnings from mcu driver -CFLAGS += -Wno-error=undef -Wno-error=null-dereference -Wno-error=redundant-decls - -# SAM driver is flooded with -Wcast-qual which slow down complication significantly -CFLAGS_SKIP += -Wcast-qual - -ASF_DIR = hw/mcu/microchip/samg55 - -# All source paths should be relative to the top level. -LD_FILE = hw/bsp/$(BOARD)/samg55j19_flash.ld - -SRC_C += \ - src/portable/microchip/samg/dcd_samg.c \ - $(ASF_DIR)/samg55/gcc/gcc/startup_samg55.c \ - $(ASF_DIR)/samg55/gcc/system_samg55.c \ - $(ASF_DIR)/hpl/core/hpl_init.c \ - $(ASF_DIR)/hpl/usart/hpl_usart.c \ - $(ASF_DIR)/hpl/pmc/hpl_pmc.c \ - $(ASF_DIR)/hal/src/hal_atomic.c - -INC += \ - $(TOP)/hw/bsp/$(BOARD) \ - $(TOP)/$(ASF_DIR) \ - $(TOP)/$(ASF_DIR)/config \ - $(TOP)/$(ASF_DIR)/samg55/include \ - $(TOP)/$(ASF_DIR)/hal/include \ - $(TOP)/$(ASF_DIR)/hal/utils/include \ - $(TOP)/$(ASF_DIR)/hpl/core \ - $(TOP)/$(ASF_DIR)/hpl/pio \ - $(TOP)/$(ASF_DIR)/hpl/pmc \ - $(TOP)/$(ASF_DIR)/hri \ - $(TOP)/$(ASF_DIR)/CMSIS/Core/Include - -# For freeRTOS port source -FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/ARM_CM4F - -# For flash-jlink target -JLINK_DEVICE = ATSAMG55J19 - -# flash using edbg from https://github.com/ataradov/edbg -flash: $(BUILD)/$(PROJECT).bin - edbg --verbose -t samg55 -pv -f $< diff --git a/hw/bsp/saml2x/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/saml2x/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..6c9ecae2d --- /dev/null +++ b/hw/bsp/saml2x/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,153 @@ +/* + * 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 "sam.h" +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#if defined(__ARM_FP) && __ARM_FP >= 4 + #define configENABLE_FPU 1 +#else + #define configENABLE_FPU 0 +#endif +#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 4 +#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 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* 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 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* 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 + +/* 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 2 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<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 diff --git a/hw/bsp/stm32f0/boards/stm32f072eval/STM32F072VBTx_FLASH.ld b/hw/bsp/stm32f0/boards/stm32f072eval/STM32F072VBTx_FLASH.ld index 581613a5f..0eaf15186 100644 --- a/hw/bsp/stm32f0/boards/stm32f072eval/STM32F072VBTx_FLASH.ld +++ b/hw/bsp/stm32f0/boards/stm32f072eval/STM32F072VBTx_FLASH.ld @@ -27,12 +27,6 @@ /* Entry Point */ ENTRY(Reset_Handler) -/* Highest address of the user mode stack */ -_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ - -_Min_Heap_Size = 0x200 ; /* required amount of heap */ -_Min_Stack_Size = 0x400 ; /* required amount of stack */ - /* Memories definition */ MEMORY { @@ -40,6 +34,12 @@ MEMORY FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K } +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200 ; /* required amount of heap */ +_Min_Stack_Size = 0x400 ; /* required amount of stack */ + /* Sections */ SECTIONS { diff --git a/hw/bsp/stm32f0/family.cmake b/hw/bsp/stm32f0/family.cmake index e0fc705f8..0af200dd5 100644 --- a/hw/bsp/stm32f0/family.cmake +++ b/hw/bsp/stm32f0/family.cmake @@ -1,9 +1,5 @@ include_guard() -if (NOT BOARD) - message(FATAL_ERROR "BOARD not specified") -endif () - set(ST_FAMILY f0) set(ST_PREFIX stm32${ST_FAMILY}xx) @@ -16,7 +12,7 @@ include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_PROCESSOR cortex-m0 CACHE INTERNAL "System Processor") -set(CMAKE_TOOLCHAIN_FILE ${TOP}/tools/cmake/toolchain/arm_${TOOLCHAIN}.cmake) +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS STM32F0 CACHE INTERNAL "") @@ -26,50 +22,56 @@ set(FAMILY_MCUS STM32F0 CACHE INTERNAL "") #------------------------------------ # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) - if (NOT TARGET ${BOARD_TARGET}) - # Startup & Linker script - set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) - set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) - set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + if (TARGET ${BOARD_TARGET}) + return() + endif() - add_library(${BOARD_TARGET} STATIC - ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} - ) - target_include_directories(${BOARD_TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMSIS_5}/CMSIS/Core/Include - ${ST_CMSIS}/Include - ${ST_HAL_DRIVER}/Inc - ) - target_compile_options(${BOARD_TARGET} PUBLIC - ) - target_compile_definitions(${BOARD_TARGET} PUBLIC - CFG_EXAMPLE_MSC_READONLY - ) + # Startup & Linker script + set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) - update_board(${BOARD_TARGET}) + set(LD_FILE_Clang ${LD_FILE_GNU}) + set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - -nostartfiles - # 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 () + add_library(${BOARD_TARGET} STATIC + ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_5}/CMSIS/Core/Include + ${ST_CMSIS}/Include + ${ST_HAL_DRIVER}/Inc + ) + #target_compile_options(${BOARD_TARGET} PUBLIC) + target_compile_definitions(${BOARD_TARGET} PUBLIC + CFG_EXAMPLE_MSC_READONLY + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) endif () endfunction() @@ -109,5 +111,5 @@ function(family_configure_example TARGET RTOS) # Flashing family_flash_stlink(${TARGET}) - #family_flash_jlink(${TARGET}) + family_flash_jlink(${TARGET}) endfunction() diff --git a/hw/bsp/stm32f0/family.mk b/hw/bsp/stm32f0/family.mk index 129a3b73a..431709de0 100644 --- a/hw/bsp/stm32f0/family.mk +++ b/hw/bsp/stm32f0/family.mk @@ -18,11 +18,14 @@ CFLAGS += \ # GCC Flags CFLAGS_GCC += \ -flto \ - -nostdlib -nostartfiles \ # suppress warning caused by vendor mcu driver CFLAGS_GCC += -Wno-error=unused-parameter -Wno-error=cast-align +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs + # ------------------------ # All source paths should be relative to the top level. # ------------------------ diff --git a/hw/bsp/stm32f1/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/stm32f1/FreeRTOSConfig/FreeRTOSConfig.h index 580fe02bb..c08a590a7 100644 --- a/hw/bsp/stm32f1/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/stm32f1/FreeRTOSConfig/FreeRTOSConfig.h @@ -49,7 +49,7 @@ /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 -#define configENABLE_FPU 1 +#define configENABLE_FPU 0 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) @@ -73,14 +73,15 @@ #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 -#define configSUPPORT_STATIC_ALLOCATION 0 -#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 /* 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 +#define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 @@ -116,23 +117,6 @@ #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 diff --git a/hw/bsp/stm32f1/boards/stm32f103_bluepill/board.h b/hw/bsp/stm32f1/boards/stm32f103_bluepill/board.h index 8fa8f4ffa..2f30a09d4 100644 --- a/hw/bsp/stm32f1/boards/stm32f103_bluepill/board.h +++ b/hw/bsp/stm32f1/boards/stm32f103_bluepill/board.h @@ -42,12 +42,12 @@ #define BUTTON_STATE_ACTIVE 1 // UART -//#define UART_DEV USART1 -//#define UART_CLK_EN __HAL_RCC_USART1_CLK_ENABLE -//#define UART_GPIO_PORT GPIOA +#define UART_DEV USART1 +#define UART_CLK_EN __HAL_RCC_USART1_CLK_ENABLE +#define UART_GPIO_PORT GPIOA //#define UART_GPIO_AF GPIO_AF1_USART1 -//#define UART_TX_PIN GPIO_PIN_9 -//#define UART_RX_PIN GPIO_PIN_10 +#define UART_TX_PIN GPIO_PIN_9 +#define UART_RX_PIN GPIO_PIN_10 //--------------------------------------------------------------------+ // RCC Clock diff --git a/hw/bsp/stm32f1/family.c b/hw/bsp/stm32f1/family.c index 3b1c5796b..0c1b362ab 100644 --- a/hw/bsp/stm32f1/family.c +++ b/hw/bsp/stm32f1/family.c @@ -46,6 +46,7 @@ void USBWakeUp_IRQHandler(void) { //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ +UART_HandleTypeDef UartHandle; void board_init(void) { board_stm32f1_clock_init(); @@ -82,6 +83,30 @@ void board_init(void) { GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); +#ifdef UART_DEV + // UART + UART_CLK_EN(); + + GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + //GPIO_InitStruct.Alternate = UART_GPIO_AF; + HAL_GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); + + UartHandle = (UART_HandleTypeDef) { + .Instance = UART_DEV, + .Init.BaudRate = CFG_BOARD_UART_BAUDRATE, + .Init.WordLength = UART_WORDLENGTH_8B, + .Init.StopBits = UART_STOPBITS_1, + .Init.Parity = UART_PARITY_NONE, + .Init.HwFlowCtl = UART_HWCONTROL_NONE, + .Init.Mode = UART_MODE_TX_RX, + .Init.OverSampling = UART_OVERSAMPLING_16 + }; + HAL_UART_Init(&UartHandle); +#endif + // USB Pins // Configure USB DM and DP pins. GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); @@ -127,9 +152,8 @@ int board_uart_read(uint8_t *buf, int len) { } int board_uart_write(void const *buf, int len) { - (void) buf; - (void) len; - return 0; + HAL_UART_Transmit(&UartHandle, (uint8_t *) (uintptr_t) buf, len, 0xffff); + return len; } #if CFG_TUSB_OS == OPT_OS_NONE diff --git a/hw/bsp/stm32f1/family.cmake b/hw/bsp/stm32f1/family.cmake index 53af35862..e8cc4db1f 100644 --- a/hw/bsp/stm32f1/family.cmake +++ b/hw/bsp/stm32f1/family.cmake @@ -1,9 +1,5 @@ include_guard() -if (NOT BOARD) - message(FATAL_ERROR "BOARD not specified") -endif () - set(ST_FAMILY f1) set(ST_PREFIX stm32${ST_FAMILY}xx) @@ -16,7 +12,7 @@ include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_PROCESSOR cortex-m3 CACHE INTERNAL "System Processor") -set(CMAKE_TOOLCHAIN_FILE ${TOP}/tools/cmake/toolchain/arm_${TOOLCHAIN}.cmake) +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS STM32F1 CACHE INTERNAL "") @@ -26,47 +22,55 @@ set(FAMILY_MCUS STM32F1 CACHE INTERNAL "") #------------------------------------ # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) - if (NOT TARGET ${BOARD_TARGET}) - # Startup & Linker script - set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) - set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) + if (TARGET ${BOARD_TARGET}) + return() + endif() - add_library(${BOARD_TARGET} STATIC - ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} - ) - target_include_directories(${BOARD_TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMSIS_5}/CMSIS/Core/Include - ${ST_CMSIS}/Include - ${ST_HAL_DRIVER}/Inc - ) - target_compile_options(${BOARD_TARGET} PUBLIC - ) - target_compile_definitions(${BOARD_TARGET} PUBLIC - ) +# Startup & Linker script + set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) - update_board(${BOARD_TARGET}) + set(LD_FILE_Clang ${LD_FILE_GNU}) + if (NOT DEFINED LD_FILE_IAR) + set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + endif () - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - -nostartfiles - # 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 () + add_library(${BOARD_TARGET} STATIC + ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_5}/CMSIS/Core/Include + ${ST_CMSIS}/Include + ${ST_HAL_DRIVER}/Inc + ) + #target_compile_options(${BOARD_TARGET} PUBLIC) + #target_compile_definitions(${BOARD_TARGET} PUBLIC) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) endif () endfunction() @@ -106,5 +110,5 @@ function(family_configure_example TARGET RTOS) # Flashing family_flash_stlink(${TARGET}) - #family_flash_jlink(${TARGET}) + family_flash_jlink(${TARGET}) endfunction() diff --git a/hw/bsp/stm32f1/family.mk b/hw/bsp/stm32f1/family.mk index c9321c3cb..03fbf4010 100644 --- a/hw/bsp/stm32f1/family.mk +++ b/hw/bsp/stm32f1/family.mk @@ -16,7 +16,13 @@ CFLAGS += \ # GCC Flags CFLAGS_GCC += \ -flto \ + +# mcu driver cause following warnings +CFLAGS_GCC += -Wno-error=cast-align + +LDFLAGS_GCC += \ -nostdlib -nostartfiles \ + -specs=nosys.specs -specs=nano.specs # ------------------------ # All source paths should be relative to the top level. @@ -28,7 +34,8 @@ SRC_C += \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ - $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c INC += \ $(TOP)/$(BOARD_PATH) \ @@ -40,6 +47,5 @@ INC += \ SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_$(MCU_VARIANT).s SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_$(MCU_VARIANT).s -# flash target ROM bootloader -flash-dfu-util: $(BUILD)/$(PROJECT).bin - dfu-util -R -a 0 --dfuse-address 0x08000000 -D $< +# flash target ROM bootloader: flash-dfu-util +DFU_UTIL_OPTION = -a 0 --dfuse-address 0x08000000 diff --git a/hw/bsp/stm32f1/stm32f1xx_hal_conf.h b/hw/bsp/stm32f1/stm32f1xx_hal_conf.h index 45ef993da..0fce774e1 100644 --- a/hw/bsp/stm32f1/stm32f1xx_hal_conf.h +++ b/hw/bsp/stm32f1/stm32f1xx_hal_conf.h @@ -38,7 +38,7 @@ /* #define HAL_ADC_MODULE_ENABLED */ /* #define HAL_CAN_MODULE_ENABLED */ /* #define HAL_CAN_LEGACY_MODULE_ENABLED */ -#define HAL_CORTEX_MODULE_ENABLED */ +#define HAL_CORTEX_MODULE_ENABLED /* #define HAL_CRC_MODULE_ENABLED */ /* #define HAL_DAC_MODULE_ENABLED */ #define HAL_DMA_MODULE_ENABLED diff --git a/hw/bsp/stm32f2/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/stm32f2/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..edbdba4b5 --- /dev/null +++ b/hw/bsp/stm32f2/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,149 @@ +/* + * 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 "stm32f2xx.h" +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#define configENABLE_FPU 0 +#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 4 +#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 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* 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 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* 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 + +/* 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 4 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<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 diff --git a/hw/bsp/stm32f4/boards/feather_stm32f405/board.cmake b/hw/bsp/stm32f4/boards/feather_stm32f405/board.cmake index 4910d3a88..fff6c502d 100644 --- a/hw/bsp/stm32f4/boards/feather_stm32f405/board.cmake +++ b/hw/bsp/stm32f4/boards/feather_stm32f405/board.cmake @@ -6,5 +6,6 @@ set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F405RGTx_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F405xx + BOARD_TUD_RHPORT=0 ) endfunction() diff --git a/hw/bsp/stm32f4/boards/pyboardv11/board.cmake b/hw/bsp/stm32f4/boards/pyboardv11/board.cmake index 4910d3a88..fff6c502d 100644 --- a/hw/bsp/stm32f4/boards/pyboardv11/board.cmake +++ b/hw/bsp/stm32f4/boards/pyboardv11/board.cmake @@ -6,5 +6,6 @@ set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F405RGTx_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F405xx + BOARD_TUD_RHPORT=0 ) endfunction() diff --git a/hw/bsp/stm32f4/boards/stm32f401blackpill/board.cmake b/hw/bsp/stm32f4/boards/stm32f401blackpill/board.cmake index fab6a42d2..bf2bef38b 100644 --- a/hw/bsp/stm32f4/boards/stm32f401blackpill/board.cmake +++ b/hw/bsp/stm32f4/boards/stm32f401blackpill/board.cmake @@ -6,5 +6,6 @@ set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F401VCTx_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F405xx + BOARD_TUD_RHPORT=0 ) endfunction() diff --git a/hw/bsp/stm32f4/boards/stm32f407blackvet/STM32F407VETx_FLASH.ld b/hw/bsp/stm32f4/boards/stm32f407blackvet/STM32F407VETx_FLASH.ld index 6dec5543a..2e97c633a 100644 --- a/hw/bsp/stm32f4/boards/stm32f407blackvet/STM32F407VETx_FLASH.ld +++ b/hw/bsp/stm32f4/boards/stm32f407blackvet/STM32F407VETx_FLASH.ld @@ -28,12 +28,6 @@ /* Entry Point */ ENTRY(Reset_Handler) -/* Highest address of the user mode stack */ -_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ - -_Min_Heap_Size = 0x200 ; /* required amount of heap */ -_Min_Stack_Size = 0x400 ; /* required amount of stack */ - /* Memories definition */ MEMORY { @@ -42,6 +36,12 @@ MEMORY FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K } +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200 ; /* required amount of heap */ +_Min_Stack_Size = 0x400 ; /* required amount of stack */ + /* Sections */ SECTIONS { diff --git a/hw/bsp/stm32f4/boards/stm32f407disco/board.cmake b/hw/bsp/stm32f4/boards/stm32f407disco/board.cmake index c8f0330ed..b2514dc5e 100644 --- a/hw/bsp/stm32f4/boards/stm32f407disco/board.cmake +++ b/hw/bsp/stm32f4/boards/stm32f407disco/board.cmake @@ -6,5 +6,6 @@ set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F407VGTx_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F407xx + BOARD_TUD_RHPORT=0 ) endfunction() diff --git a/hw/bsp/stm32f4/boards/stm32f411blackpill/board.cmake b/hw/bsp/stm32f4/boards/stm32f411blackpill/board.cmake index d16db508f..185507d7f 100644 --- a/hw/bsp/stm32f4/boards/stm32f411blackpill/board.cmake +++ b/hw/bsp/stm32f4/boards/stm32f411blackpill/board.cmake @@ -6,5 +6,6 @@ set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F411CEUx_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F411xE + BOARD_TUD_RHPORT=0 ) endfunction() diff --git a/hw/bsp/stm32f4/boards/stm32f411disco/board.cmake b/hw/bsp/stm32f4/boards/stm32f411disco/board.cmake index d7c32c27d..80cf94160 100644 --- a/hw/bsp/stm32f4/boards/stm32f411disco/board.cmake +++ b/hw/bsp/stm32f4/boards/stm32f411disco/board.cmake @@ -6,5 +6,6 @@ set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F411VETx_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F411xE + BOARD_TUD_RHPORT=0 ) endfunction() diff --git a/hw/bsp/stm32f4/boards/stm32f412disco/board.cmake b/hw/bsp/stm32f4/boards/stm32f412disco/board.cmake index 805332db8..f9e834409 100644 --- a/hw/bsp/stm32f4/boards/stm32f412disco/board.cmake +++ b/hw/bsp/stm32f4/boards/stm32f412disco/board.cmake @@ -6,5 +6,6 @@ set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F412ZGTx_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F412Zx + BOARD_TUD_RHPORT=0 ) endfunction() diff --git a/hw/bsp/stm32f4/boards/stm32f412nucleo/board.cmake b/hw/bsp/stm32f4/boards/stm32f412nucleo/board.cmake index 805332db8..f9e834409 100644 --- a/hw/bsp/stm32f4/boards/stm32f412nucleo/board.cmake +++ b/hw/bsp/stm32f4/boards/stm32f412nucleo/board.cmake @@ -6,5 +6,6 @@ set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F412ZGTx_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F412Zx + BOARD_TUD_RHPORT=0 ) endfunction() diff --git a/hw/bsp/stm32f4/boards/stm32f439nucleo/STM32F439ZITX_FLASH.ld b/hw/bsp/stm32f4/boards/stm32f439nucleo/STM32F439ZITX_FLASH.ld index 2dc277c77..cc098b533 100644 --- a/hw/bsp/stm32f4/boards/stm32f439nucleo/STM32F439ZITX_FLASH.ld +++ b/hw/bsp/stm32f4/boards/stm32f439nucleo/STM32F439ZITX_FLASH.ld @@ -36,12 +36,6 @@ /* Entry Point */ ENTRY(Reset_Handler) -/* Highest address of the user mode stack */ -_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ - -_Min_Heap_Size = 0x200; /* required amount of heap */ -_Min_Stack_Size = 0x400; /* required amount of stack */ - /* Memories definition */ MEMORY { @@ -50,6 +44,12 @@ MEMORY FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K } +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + /* Sections */ SECTIONS { diff --git a/hw/bsp/stm32f4/boards/stm32f439nucleo/board.cmake b/hw/bsp/stm32f4/boards/stm32f439nucleo/board.cmake index 31ec6f700..524ff8786 100644 --- a/hw/bsp/stm32f4/boards/stm32f439nucleo/board.cmake +++ b/hw/bsp/stm32f4/boards/stm32f439nucleo/board.cmake @@ -6,5 +6,6 @@ set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F439ZITX_FLASH.ld) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC STM32F439xx + BOARD_TUD_RHPORT=0 ) endfunction() diff --git a/hw/bsp/stm32f4/family.c b/hw/bsp/stm32f4/family.c index 2a599e5c4..fb0347aba 100644 --- a/hw/bsp/stm32f4/family.c +++ b/hw/bsp/stm32f4/family.c @@ -99,6 +99,7 @@ void board_init(void) { HAL_UART_Init(&UartHandle); #endif +#if BOARD_TUD_RHPORT == 0 /* Configure USB FS GPIOs */ __HAL_RCC_GPIOA_CLK_ENABLE(); @@ -124,6 +125,38 @@ void board_init(void) { GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + // Enable USB OTG clock + __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); +#else + /* Configure USB HS GPIOs */ + __HAL_RCC_GPIOB_CLK_ENABLE(); + + /* Configure USB D+ D- Pins */ + GPIO_InitStruct.Pin = GPIO_PIN_14 | GPIO_PIN_15; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Alternate = GPIO_AF12_OTG_HS_FS; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* Configure VBUS Pin */ + GPIO_InitStruct.Pin = GPIO_PIN_13; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* ID Pin */ + GPIO_InitStruct.Pin = GPIO_PIN_12; + GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF12_OTG_HS_FS; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + // Enable USB OTG clock + __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); +#endif + #ifdef STM32F412Zx /* Configure POWER_SWITCH IO pin */ __HAL_RCC_GPIOG_CLK_ENABLE(); @@ -133,11 +166,6 @@ void board_init(void) { HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); #endif - // Enable USB OTG clock - __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); - -// __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); - board_vbus_sense_init(); } diff --git a/hw/bsp/stm32f4/family.cmake b/hw/bsp/stm32f4/family.cmake index cad504bac..f24ef366e 100644 --- a/hw/bsp/stm32f4/family.cmake +++ b/hw/bsp/stm32f4/family.cmake @@ -1,9 +1,5 @@ include_guard() -if (NOT BOARD) - message(FATAL_ERROR "BOARD not specified") -endif () - set(ST_FAMILY f4) set(ST_PREFIX stm32${ST_FAMILY}xx) @@ -16,7 +12,7 @@ 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(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS STM32F4 CACHE INTERNAL "") @@ -32,7 +28,10 @@ function(add_board_target BOARD_TARGET) # Startup & Linker script set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) + + set(LD_FILE_Clang ${LD_FILE_GNU}) set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) add_library(${BOARD_TARGET} STATIC @@ -53,10 +52,8 @@ function(add_board_target BOARD_TARGET) ${ST_CMSIS}/Include ${ST_HAL_DRIVER}/Inc ) - target_compile_options(${BOARD_TARGET} PUBLIC - ) - target_compile_definitions(${BOARD_TARGET} PUBLIC - ) + # target_compile_options(${BOARD_TARGET} PUBLIC) + # target_compile_definitions(${BOARD_TARGET} PUBLIC) update_board(${BOARD_TARGET}) @@ -64,9 +61,11 @@ function(add_board_target BOARD_TARGET) target_link_options(${BOARD_TARGET} PUBLIC "LINKER:--script=${LD_FILE_GNU}" -nostartfiles - # nanolib - --specs=nosys.specs - --specs=nano.specs + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" ) elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") target_link_options(${BOARD_TARGET} PUBLIC diff --git a/hw/bsp/stm32f4/family.mk b/hw/bsp/stm32f4/family.mk index 38592ecb0..523a1cb04 100644 --- a/hw/bsp/stm32f4/family.mk +++ b/hw/bsp/stm32f4/family.mk @@ -8,20 +8,26 @@ ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m4 +PORT ?= 0 + # -------------- # Compiler Flags # -------------- CFLAGS += \ - -DCFG_TUSB_MCU=OPT_MCU_STM32F4 + -DCFG_TUSB_MCU=OPT_MCU_STM32F4 \ + -DBOARD_TUD_RHPORT=$(PORT) # GCC Flags CFLAGS_GCC += \ -flto \ - -nostdlib -nostartfiles # suppress warning caused by vendor mcu driver CFLAGS_GCC += -Wno-error=cast-align +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs + # ----------------- # Sources & Include # ----------------- diff --git a/hw/bsp/stm32f7/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/stm32f7/FreeRTOSConfig/FreeRTOSConfig.h index 4615640ed..31fb7942f 100644 --- a/hw/bsp/stm32f7/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/stm32f7/FreeRTOSConfig/FreeRTOSConfig.h @@ -73,14 +73,15 @@ #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 -#define configSUPPORT_STATIC_ALLOCATION 0 -#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 /* 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 +#define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 @@ -116,23 +117,6 @@ #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 diff --git a/hw/bsp/stm32f7/boards/stm32f769disco/board.cmake b/hw/bsp/stm32f7/boards/stm32f769disco/board.cmake index 62a157c58..329ada093 100644 --- a/hw/bsp/stm32f7/boards/stm32f769disco/board.cmake +++ b/hw/bsp/stm32f7/boards/stm32f769disco/board.cmake @@ -1,5 +1,5 @@ set(MCU_VARIANT stm32f769xx) -set(JLINK_DEVICE stm32f769xx) +set(JLINK_DEVICE stm32f769ni) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32F769ZITx_FLASH.ld) diff --git a/hw/bsp/stm32f7/boards/stm32f769disco/board.mk b/hw/bsp/stm32f7/boards/stm32f769disco/board.mk index a45af8cc0..705f1a633 100644 --- a/hw/bsp/stm32f7/boards/stm32f769disco/board.mk +++ b/hw/bsp/stm32f7/boards/stm32f769disco/board.mk @@ -11,5 +11,7 @@ CFLAGS += \ # Linker LD_FILE_GCC = $(BOARD_PATH)/STM32F769ZITx_FLASH.ld +JLINK_DEVICE = stm32f769ni + # flash target using on-board stlink flash: flash-stlink diff --git a/hw/bsp/stm32f7/family.c b/hw/bsp/stm32f7/family.c index b504c435a..61f1d2a7f 100644 --- a/hw/bsp/stm32f7/family.c +++ b/hw/bsp/stm32f7/family.c @@ -182,7 +182,7 @@ void board_init(void) { GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; + GPIO_InitStruct.Alternate = GPIO_AF12_OTG_HS_FS; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); // Enable HS VBUS sense (B device) via pin PB13 @@ -192,14 +192,14 @@ void board_init(void) { GPIO_InitStruct.Pin = GPIO_PIN_13; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; - GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; - HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); + GPIO_InitStruct.Alternate = GPIO_AF12_OTG_HS_FS; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* Enable PHYC Clocks */ __HAL_RCC_OTGPHYC_CLK_ENABLE(); #else - // MUC with external ULPI PHY + // MCU with external ULPI PHY /* ULPI CLK */ GPIO_InitStruct.Pin = GPIO_PIN_5; diff --git a/hw/bsp/stm32f7/family.cmake b/hw/bsp/stm32f7/family.cmake index 48dd9c7ca..938c2697a 100644 --- a/hw/bsp/stm32f7/family.cmake +++ b/hw/bsp/stm32f7/family.cmake @@ -1,9 +1,5 @@ include_guard() -if (NOT BOARD) - message(FATAL_ERROR "BOARD not specified") -endif () - set(ST_FAMILY f7) set(ST_PREFIX stm32${ST_FAMILY}xx) @@ -15,8 +11,8 @@ set(CMSIS_5 ${TOP}/lib/CMSIS_5) include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up -set(CMAKE_SYSTEM_PROCESSOR cortex-m7 CACHE INTERNAL "System Processor") -set(CMAKE_TOOLCHAIN_FILE ${TOP}/tools/cmake/toolchain/arm_${TOOLCHAIN}.cmake) +set(CMAKE_SYSTEM_PROCESSOR cortex-m7-fpsp CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS STM32F7 CACHE INTERNAL "") @@ -26,52 +22,57 @@ set(FAMILY_MCUS STM32F7 CACHE INTERNAL "") #------------------------------------ # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) - if (NOT TARGET ${BOARD_TARGET}) - # Startup & Linker script - set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) - set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) - set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + if (TARGET ${BOARD_TARGET}) + return() + endif() - add_library(${BOARD_TARGET} STATIC - ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_dma.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} - ) - target_include_directories(${BOARD_TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMSIS_5}/CMSIS/Core/Include - ${ST_CMSIS}/Include - ${ST_HAL_DRIVER}/Inc - ) - target_compile_options(${BOARD_TARGET} PUBLIC - ) - target_compile_definitions(${BOARD_TARGET} PUBLIC - ) + # Startup & Linker script + set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) - update_board(${BOARD_TARGET}) + set(LD_FILE_Clang ${LD_FILE_GNU}) + set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - -nostartfiles - # 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 () + add_library(${BOARD_TARGET} STATIC + ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_dma.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_5}/CMSIS/Core/Include + ${ST_CMSIS}/Include + ${ST_HAL_DRIVER}/Inc + ) + #target_compile_options(${BOARD_TARGET} PUBLIC) + #target_compile_definitions(${BOARD_TARGET} PUBLIC) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) endif () endfunction() diff --git a/hw/bsp/stm32f7/family.mk b/hw/bsp/stm32f7/family.mk index 7f37a7e40..e261b0467 100644 --- a/hw/bsp/stm32f7/family.mk +++ b/hw/bsp/stm32f7/family.mk @@ -6,7 +6,7 @@ ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver include $(TOP)/$(BOARD_PATH)/board.mk -CPU_CORE ?= cortex-m7 +CPU_CORE ?= cortex-m7-fpsp # -------------- # Compiler Flags @@ -30,11 +30,14 @@ endif # GCC Flags CFLAGS_GCC += \ -flto \ - -nostdlib -nostartfiles # mcu driver cause following warnings CFLAGS_GCC += -Wno-error=cast-align +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs + # ----------------- # Sources & Include # ----------------- diff --git a/hw/bsp/stm32g0/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/stm32g0/FreeRTOSConfig/FreeRTOSConfig.h index 02bfaf97a..82cb0cdb3 100644 --- a/hw/bsp/stm32g0/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/stm32g0/FreeRTOSConfig/FreeRTOSConfig.h @@ -49,7 +49,7 @@ /* Cortex M23/M33 port configuration. */ #define configENABLE_MPU 0 -#define configENABLE_FPU 1 +#define configENABLE_FPU 0 #define configENABLE_TRUSTZONE 0 #define configMINIMAL_SECURE_STACK_SIZE (1024) @@ -73,14 +73,15 @@ #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 -#define configSUPPORT_STATIC_ALLOCATION 0 -#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 /* 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 +#define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 @@ -116,23 +117,6 @@ #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 diff --git a/hw/bsp/stm32g0/boards/stm32g0b1nucleo/STM32G0B1RETx_FLASH.ld b/hw/bsp/stm32g0/boards/stm32g0b1nucleo/STM32G0B1RETx_FLASH.ld index 0f3fed096..b6fab16cf 100644 --- a/hw/bsp/stm32g0/boards/stm32g0b1nucleo/STM32G0B1RETx_FLASH.ld +++ b/hw/bsp/stm32g0/boards/stm32g0b1nucleo/STM32G0B1RETx_FLASH.ld @@ -52,12 +52,6 @@ /* Entry Point */ ENTRY(Reset_Handler) -/* Highest address of the user mode stack */ -_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of RAM */ -/* Generate a link error if heap and stack don't fit into RAM */ -_Min_Heap_Size = 0x200; /* required amount of heap */ -_Min_Stack_Size = 0x400; /* required amount of stack */ - /* Specify the memory areas */ MEMORY { @@ -65,6 +59,13 @@ RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 144K FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K } +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of RAM */ + +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + /* Define output sections */ SECTIONS { diff --git a/hw/bsp/stm32g0/boards/stm32g0b1nucleo/board.h b/hw/bsp/stm32g0/boards/stm32g0b1nucleo/board.h index ae0820529..9ebaf73f0 100644 --- a/hw/bsp/stm32g0/boards/stm32g0b1nucleo/board.h +++ b/hw/bsp/stm32g0/boards/stm32g0b1nucleo/board.h @@ -2,7 +2,7 @@ * The MIT License (MIT) * * Copyright (c) 2020, Ha Thach (tinyusb.org) - * Copyright (c) 2034, HiFiPhile + * Copyright (c) 2023, HiFiPhile * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/hw/bsp/stm32g0/family.c b/hw/bsp/stm32g0/family.c index 3730e44aa..d1635be12 100644 --- a/hw/bsp/stm32g0/family.c +++ b/hw/bsp/stm32g0/family.c @@ -179,7 +179,6 @@ void SysTick_Handler(void) { uint32_t board_millis(void) { return system_ticks; } - #endif void HardFault_Handler(void) { diff --git a/hw/bsp/stm32g0/family.cmake b/hw/bsp/stm32g0/family.cmake index cf52a6324..b6838c619 100644 --- a/hw/bsp/stm32g0/family.cmake +++ b/hw/bsp/stm32g0/family.cmake @@ -1,9 +1,5 @@ include_guard() -if (NOT BOARD) - message(FATAL_ERROR "BOARD not specified") -endif () - set(ST_FAMILY g0) set(ST_PREFIX stm32${ST_FAMILY}xx) @@ -16,7 +12,7 @@ include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_PROCESSOR cortex-m0plus CACHE INTERNAL "System Processor") -set(CMAKE_TOOLCHAIN_FILE ${TOP}/tools/cmake/toolchain/arm_${TOOLCHAIN}.cmake) +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS STM32G0 CACHE INTERNAL "") @@ -26,52 +22,57 @@ set(FAMILY_MCUS STM32G0 CACHE INTERNAL "") #------------------------------------ # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) - if (NOT TARGET ${BOARD_TARGET}) - # Startup & Linker script - set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) - set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) - set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + if (TARGET ${BOARD_TARGET}) + return() + endif () - add_library(${BOARD_TARGET} STATIC - ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_dma.c - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} - ) - target_include_directories(${BOARD_TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMSIS_5}/CMSIS/Core/Include - ${ST_CMSIS}/Include - ${ST_HAL_DRIVER}/Inc - ) - target_compile_options(${BOARD_TARGET} PUBLIC - ) - target_compile_definitions(${BOARD_TARGET} PUBLIC - ) + # Startup & Linker script + set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) - update_board(${BOARD_TARGET}) + set(LD_FILE_Clang ${LD_FILE_GNU}) + set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - -nostartfiles - # 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 () + add_library(${BOARD_TARGET} STATIC + ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_dma.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_5}/CMSIS/Core/Include + ${ST_CMSIS}/Include + ${ST_HAL_DRIVER}/Inc + ) +# target_compile_options(${BOARD_TARGET} PUBLIC) +# target_compile_definitions(${BOARD_TARGET} PUBLIC) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) endif () endfunction() @@ -112,5 +113,5 @@ function(family_configure_example TARGET RTOS) # Flashing family_flash_stlink(${TARGET}) - #family_flash_jlink(${TARGET}) + family_flash_jlink(${TARGET}) endfunction() diff --git a/hw/bsp/stm32g0/family.mk b/hw/bsp/stm32g0/family.mk index 6b199f21a..95b8e537d 100644 --- a/hw/bsp/stm32g0/family.mk +++ b/hw/bsp/stm32g0/family.mk @@ -16,11 +16,14 @@ CFLAGS += \ # GCC Flags CFLAGS_GCC += \ -flto \ - -nostdlib -nostartfiles # suppress warning caused by vendor mcu driver CFLAGS_GCC += -Wno-error=cast-align +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs + # ----------------- # Sources & Include # ----------------- diff --git a/hw/bsp/stm32g4/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/stm32g4/FreeRTOSConfig/FreeRTOSConfig.h index 17c2a0c5c..fa3f0ac33 100644 --- a/hw/bsp/stm32g4/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/stm32g4/FreeRTOSConfig/FreeRTOSConfig.h @@ -73,14 +73,15 @@ #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 -#define configSUPPORT_STATIC_ALLOCATION 0 -#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 /* 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 +#define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 @@ -116,23 +117,6 @@ #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 diff --git a/hw/bsp/stm32g4/boards/b_g474e_dpow1/STM32G474RETx_FLASH.ld b/hw/bsp/stm32g4/boards/b_g474e_dpow1/STM32G474RETx_FLASH.ld index 8ba23a5b8..25a104bc2 100644 --- a/hw/bsp/stm32g4/boards/b_g474e_dpow1/STM32G474RETx_FLASH.ld +++ b/hw/bsp/stm32g4/boards/b_g474e_dpow1/STM32G474RETx_FLASH.ld @@ -52,12 +52,6 @@ /* Entry Point */ ENTRY(Reset_Handler) -/* Highest address of the user mode stack */ -_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ - -_Min_Heap_Size = 0x1000 ; /* required amount of heap */ -_Min_Stack_Size = 0x1000 ; /* required amount of stack */ - /* Memories definition */ MEMORY { @@ -65,6 +59,12 @@ MEMORY FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K } +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x1000 ; /* required amount of heap */ +_Min_Stack_Size = 0x1000 ; /* required amount of stack */ + /* Sections */ SECTIONS { diff --git a/hw/bsp/stm32g4/boards/stm32g474nucleo/STM32G474RETx_FLASH.ld b/hw/bsp/stm32g4/boards/stm32g474nucleo/STM32G474RETx_FLASH.ld index 8ba23a5b8..25a104bc2 100644 --- a/hw/bsp/stm32g4/boards/stm32g474nucleo/STM32G474RETx_FLASH.ld +++ b/hw/bsp/stm32g4/boards/stm32g474nucleo/STM32G474RETx_FLASH.ld @@ -52,12 +52,6 @@ /* Entry Point */ ENTRY(Reset_Handler) -/* Highest address of the user mode stack */ -_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ - -_Min_Heap_Size = 0x1000 ; /* required amount of heap */ -_Min_Stack_Size = 0x1000 ; /* required amount of stack */ - /* Memories definition */ MEMORY { @@ -65,6 +59,12 @@ MEMORY FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K } +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x1000 ; /* required amount of heap */ +_Min_Stack_Size = 0x1000 ; /* required amount of stack */ + /* Sections */ SECTIONS { diff --git a/hw/bsp/stm32g4/boards/stm32g491nucleo/STM32G491RETX_FLASH.ld b/hw/bsp/stm32g4/boards/stm32g491nucleo/STM32G491RETX_FLASH.ld new file mode 100644 index 000000000..88ef666c7 --- /dev/null +++ b/hw/bsp/stm32g4/boards/stm32g491nucleo/STM32G491RETX_FLASH.ld @@ -0,0 +1,185 @@ +/* +****************************************************************************** +** +** @file : LinkerScript.ld +** +** @author : Auto-generated by STM32CubeIDE +** +** Abstract : Linker script for NUCLEO-G491RE Board embedding STM32G491RETx Device from stm32g4 series +** 512KBytes FLASH +** 112KBytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +****************************************************************************** +** @attention +** +** Copyright (c) 2023 STMicroelectronics. +** All rights reserved. +** +** This software is licensed under terms that can be found in the LICENSE file +** in the root directory of this software component. +** If no LICENSE file comes with this software, it is provided AS-IS. +** +****************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 112K + FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + + .ARM : { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32g4/boards/stm32g491nucleo/board.cmake b/hw/bsp/stm32g4/boards/stm32g491nucleo/board.cmake new file mode 100644 index 000000000..e37544499 --- /dev/null +++ b/hw/bsp/stm32g4/boards/stm32g491nucleo/board.cmake @@ -0,0 +1,11 @@ +set(MCU_VARIANT stm32g491xx) +set(JLINK_DEVICE stm32g491re) + +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32G491RETX_FLASH.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + STM32G491xx + HSE_VALUE=24000000 + ) +endfunction() diff --git a/hw/bsp/stm32g4/boards/stm32g491nucleo/board.h b/hw/bsp/stm32g4/boards/stm32g491nucleo/board.h new file mode 100644 index 000000000..7dd4ed9ae --- /dev/null +++ b/hw/bsp/stm32g4/boards/stm32g491nucleo/board.h @@ -0,0 +1,104 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, 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 + +// G474RE Nucleo does not has usb connection. We need to manually connect +// - PA12 for D+, CN10.12 +// - PA11 for D-, CN10.14 + +// LED +#define LED_PORT GPIOA +#define LED_PIN GPIO_PIN_5 +#define LED_STATE_ON 0 + +// Button +#define BUTTON_PORT GPIOC +#define BUTTON_PIN GPIO_PIN_13 +#define BUTTON_STATE_ACTIVE 1 + +// UART Enable for STLink VCOM +#define UART_DEV LPUART1 +#define UART_CLK_EN __HAL_RCC_LPUART1_CLK_ENABLE +#define UART_GPIO_PORT GPIOA +#define UART_GPIO_AF GPIO_AF12_LPUART1 +#define UART_TX_PIN GPIO_PIN_2 +#define UART_RX_PIN GPIO_PIN_3 + + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_clock_init(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + + // Configure the main internal regulator output voltage + HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST); + + // Initializes the CPU, AHB and APB buses clocks + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48 | RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV6; + RCC_OscInitStruct.PLL.PLLN = 85; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; + RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + // Initializes the CPU, AHB and APB buses clocks + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4); + + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB; + PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) ; +} + +static inline void board_vbus_sense_init(void) +{ + // Enable VBUS sense (B device) via pin PA9 +} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/stm32g4/boards/stm32g491nucleo/board.mk b/hw/bsp/stm32g4/boards/stm32g491nucleo/board.mk new file mode 100644 index 000000000..c0f876331 --- /dev/null +++ b/hw/bsp/stm32g4/boards/stm32g491nucleo/board.mk @@ -0,0 +1,11 @@ +MCU_VARIANT = stm32g491xx + +CFLAGS += \ + -DSTM32G491xx \ + -DHSE_VALUE=24000000 + +# Linker +LD_FILE_GCC = $(BOARD_PATH)/STM32G491RETX_FLASH.ld + +# For flash-jlink target +JLINK_DEVICE = stm32g491re diff --git a/hw/bsp/stm32g4/family.c b/hw/bsp/stm32g4/family.c index 39be0249a..2259cb9e2 100644 --- a/hw/bsp/stm32g4/family.c +++ b/hw/bsp/stm32g4/family.c @@ -209,7 +209,6 @@ void SysTick_Handler(void) { uint32_t board_millis(void) { return system_ticks; } - #endif void HardFault_Handler(void) { diff --git a/hw/bsp/stm32g4/family.cmake b/hw/bsp/stm32g4/family.cmake index 675a96c74..4217e4be6 100644 --- a/hw/bsp/stm32g4/family.cmake +++ b/hw/bsp/stm32g4/family.cmake @@ -1,9 +1,5 @@ include_guard() -if (NOT BOARD) - message(FATAL_ERROR "BOARD not specified") -endif () - set(ST_FAMILY g4) set(ST_PREFIX stm32${ST_FAMILY}xx) @@ -16,7 +12,7 @@ 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(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS STM32G4 CACHE INTERNAL "") @@ -26,50 +22,53 @@ set(FAMILY_MCUS STM32G4 CACHE INTERNAL "") #------------------------------------ # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) - if (NOT TARGET ${BOARD_TARGET}) - # Startup & Linker script - set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) - set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) - set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + if (TARGET ${BOARD_TARGET}) + return() + endif () - add_library(${BOARD_TARGET} STATIC - ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} - ) - target_include_directories(${BOARD_TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMSIS_5}/CMSIS/Core/Include - ${ST_CMSIS}/Include - ${ST_HAL_DRIVER}/Inc - ) - target_compile_options(${BOARD_TARGET} PUBLIC - ) - target_compile_definitions(${BOARD_TARGET} PUBLIC - ) + # Startup & Linker script + set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) - update_board(${BOARD_TARGET}) + set(LD_FILE_Clang ${LD_FILE_GNU}) + set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - -nostartfiles - # 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 () + add_library(${BOARD_TARGET} STATIC + ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_5}/CMSIS/Core/Include + ${ST_CMSIS}/Include + ${ST_HAL_DRIVER}/Inc + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) endif () endfunction() diff --git a/hw/bsp/stm32g4/family.mk b/hw/bsp/stm32g4/family.mk index 2efe91449..0abd73532 100644 --- a/hw/bsp/stm32g4/family.mk +++ b/hw/bsp/stm32g4/family.mk @@ -1,7 +1,5 @@ UF2_FAMILY_ID = 0x4c71240a ST_FAMILY = g4 -DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/st/cmsis_device_$(ST_FAMILY) hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver - ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver @@ -17,11 +15,14 @@ CFLAGS += \ # GCC Flags CFLAGS_GCC += \ -flto \ - -nostdlib -nostartfiles \ # suppress warning caused by vendor mcu driver CFLAGS_GCC += -Wno-error=cast-align +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs + # ----------------- # Sources & Include # ----------------- diff --git a/hw/bsp/stm32h5/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/stm32h5/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..cf6e23c1b --- /dev/null +++ b/hw/bsp/stm32h5/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,166 @@ +/* + * 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 "stm32h5xx.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 4 +#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 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* 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 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* 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 4 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<CTRL &= ~1U; + + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(USB_DRD_FS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); + #endif + + GPIO_InitTypeDef GPIO_InitStruct; + + // LED + GPIO_InitStruct.Pin = LED_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct); + + board_led_write(false); + + // Button + GPIO_InitStruct.Pin = BUTTON_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = BUTTON_STATE_ACTIVE ? GPIO_PULLDOWN : GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); + + #ifdef UART_DEV + // UART + GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = UART_GPIO_AF; + HAL_GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); + + UartHandle = (UART_HandleTypeDef) { + .Instance = UART_DEV, + .Init.BaudRate = CFG_BOARD_UART_BAUDRATE, + .Init.WordLength = UART_WORDLENGTH_8B, + .Init.StopBits = UART_STOPBITS_1, + .Init.Parity = UART_PARITY_NONE, + .Init.HwFlowCtl = UART_HWCONTROL_NONE, + .Init.Mode = UART_MODE_TX_RX, + .Init.OverSampling = UART_OVERSAMPLING_16, + .AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT + }; + HAL_UART_Init(&UartHandle); + #endif + + // USB Pins TODO double check USB clock and pin setup + // Configure USB DM and DP pins. This is optional, and maintained only for user guidance. + GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Peripheral clock enable */ + __HAL_RCC_USB_CLK_ENABLE(); + + /* Enable VDDUSB */ + #if defined (PWR_USBSCR_USB33DEN) + HAL_PWREx_EnableVddUSB(); + #endif +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) { + GPIO_PinState pin_state = (GPIO_PinState) (state ? LED_STATE_ON : (1 - LED_STATE_ON)); + HAL_GPIO_WritePin(LED_PORT, LED_PIN, pin_state); +} + +uint32_t board_button_read(void) { + return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); +} + +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + (void) max_len; + volatile uint32_t* stm32_uuid = (volatile uint32_t*) UID_BASE; + uint32_t* id32 = (uint32_t*) (uintptr_t) id; + uint8_t const len = 12; + + id32[0] = stm32_uuid[0]; + id32[1] = stm32_uuid[1]; + id32[2] = stm32_uuid[2]; + + return len; +} + +int board_uart_read(uint8_t* buf, int len) { + (void) buf; + (void) len; + return 0; +} + +int board_uart_write(void const* buf, int len) { + #ifdef UART_DEV + HAL_UART_Transmit(&UartHandle, (uint8_t*) (uintptr_t) buf, len, 0xffff); + return len; + #else + (void) buf; + (void) len; + (void) UartHandle; + return 0; + #endif +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; + +void SysTick_Handler(void) { + system_ticks++; + HAL_IncTick(); +} + +uint32_t board_millis(void) { + return system_ticks; +} + +#endif + +void HardFault_Handler(void) { + __asm("BKPT #0\n"); +} + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void) { + +} diff --git a/hw/bsp/stm32h5/family.cmake b/hw/bsp/stm32h5/family.cmake new file mode 100644 index 000000000..94900f416 --- /dev/null +++ b/hw/bsp/stm32h5/family.cmake @@ -0,0 +1,117 @@ +include_guard() + +set(ST_FAMILY h5) +set(ST_PREFIX stm32${ST_FAMILY}xx) + +set(ST_HAL_DRIVER ${TOP}/hw/mcu/st/stm32${ST_FAMILY}xx_hal_driver) +set(ST_CMSIS ${TOP}/hw/mcu/st/cmsis_device_${ST_FAMILY}) +set(CMSIS_5 ${TOP}/lib/CMSIS_5) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR cortex-m33 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS STM32H5 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 () + + # Startup & Linker script + set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) + + string(REPLACE "stm32h" "STM32H" MCU_VARIANT_UPPER ${MCU_VARIANT}) + set(LD_FILE_GNU ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/linker/${MCU_VARIANT_UPPER}_FLASH.ld) + set(LD_FILE_Clang ${LD_FILE_GNU}) + set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + + add_library(${BOARD_TARGET} STATIC + ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_dma.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_5}/CMSIS/Core/Include + ${ST_CMSIS}/Include + ${ST_HAL_DRIVER}/Inc + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + 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_STM32H5 ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c + ${TOP}/src/portable/st/typec/typec_stm32.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_flash_stlink(${TARGET}) + family_flash_jlink(${TARGET}) +endfunction() diff --git a/hw/bsp/stm32h5/family.mk b/hw/bsp/stm32h5/family.mk new file mode 100644 index 000000000..792edb2bb --- /dev/null +++ b/hw/bsp/stm32h5/family.mk @@ -0,0 +1,66 @@ +ST_FAMILY = h5 +ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) +ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +include $(TOP)/$(BOARD_PATH)/board.mk +CPU_CORE ?= cortex-m33 + +MCU_VARIANT_UPPER = $(subst stm32h,STM32H,$(MCU_VARIANT)) + +# -------------- +# Compiler Flags +# -------------- +CFLAGS += \ + -DCFG_TUSB_MCU=OPT_MCU_STM32H5 + +# GCC Flags +CFLAGS_GCC += \ + -flto \ + +# suppress warning caused by vendor mcu driver +CFLAGS_GCC += \ + -Wno-error=cast-align \ + -Wno-error=undef \ + -Wno-error=unused-parameter \ + +CFLAGS_CLANG += \ + -Wno-error=parentheses-equality + +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs + +# ----------------- +# Sources & Include +# ----------------- + +SRC_C += \ + src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ + $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_dma.c + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + $(TOP)/$(ST_CMSIS)/Include \ + $(TOP)/$(ST_HAL_DRIVER)/Inc + +# Startup +SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_$(MCU_VARIANT).s +SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_$(MCU_VARIANT).s + +# Linker +LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/$(MCU_VARIANT)_flash.icf +LD_FILE_GCC = $(FAMILY_PATH)/linker/$(MCU_VARIANT_UPPER)_FLASH.ld + +# flash target using on-board stlink +flash: flash-stlink diff --git a/hw/bsp/stm32h5/linker/STM32H503xx_FLASH.ld b/hw/bsp/stm32h5/linker/STM32H503xx_FLASH.ld new file mode 100644 index 000000000..abf618233 --- /dev/null +++ b/hw/bsp/stm32h5/linker/STM32H503xx_FLASH.ld @@ -0,0 +1,188 @@ +/* + ****************************************************************************** + ** + ** @file : LinkerScript.ld + ** + ** @author : Auto-generated by STM32CubeIDE + ** + ** @brief : Linker script for STM32H503xx Device from STM32H5 series + ** 128Kbytes FLASH + ** 32Kbytes RAM + ** + ** Set heap size, stack size and stack location according + ** to application requirements. + ** + ** Set memory bank area and size if external memory is used + ** + ** Target : STMicroelectronics STM32 + ** + ** Distribution: The file is distributed as is, without any warranty + ** of any kind. + ** + ****************************************************************************** + ** @attention + ** + ** Copyright (c) 2023 STMicroelectronics. + ** All rights reserved. + ** + ** This software is licensed under terms that can be found in the LICENSE file + ** in the root directory of this software component. + ** If no LICENSE file comes with this software, it is provided AS-IS. + ** + ****************************************************************************** + */ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K + FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + + .ARM : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32h5/linker/STM32H523xx_FLASH.ld b/hw/bsp/stm32h5/linker/STM32H523xx_FLASH.ld new file mode 100644 index 000000000..b799892c6 --- /dev/null +++ b/hw/bsp/stm32h5/linker/STM32H523xx_FLASH.ld @@ -0,0 +1,187 @@ +/* + ****************************************************************************** + ** + ** @file : LinkerScript.ld + ** + ** @author : Auto-generated by STM32CubeIDE + ** + ** @brief : Linker script for STM32H523xx Device from STM32H5 series + ** 512Kbytes FLASH + ** 272Kbytes RAM + ** + ** Set heap size, stack size and stack location according + ** to application requirements. + ** + ** Set memory bank area and size if external memory is used + ** + ** Target : STMicroelectronics STM32 + ** + ** Distribution: The file is distributed as is, without any warranty + ** of any kind. + ** + ****************************************************************************** + ** @attention + ** + ** Copyright (c) 2023 STMicroelectronics. + ** All rights reserved. + ** + ** This software is licensed under terms that can be found in the LICENSE file + ** in the root directory of this software component. + ** If no LICENSE file comes with this software, it is provided AS-IS. + ** + ****************************************************************************** + */ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 272K + FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + + .ARM : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32h5/linker/STM32H533xx_FLASH.ld b/hw/bsp/stm32h5/linker/STM32H533xx_FLASH.ld new file mode 100644 index 000000000..dece7a003 --- /dev/null +++ b/hw/bsp/stm32h5/linker/STM32H533xx_FLASH.ld @@ -0,0 +1,187 @@ +/* + ****************************************************************************** + ** + ** @file : LinkerScript.ld + ** + ** @author : Auto-generated by STM32CubeIDE + ** + ** @brief : Linker script for STM32H533xx Device from STM32H5 series + ** 512Kbytes FLASH + ** 272Kbytes RAM + ** + ** Set heap size, stack size and stack location according + ** to application requirements. + ** + ** Set memory bank area and size if external memory is used + ** + ** Target : STMicroelectronics STM32 + ** + ** Distribution: The file is distributed as is, without any warranty + ** of any kind. + ** + ****************************************************************************** + ** @attention + ** + ** Copyright (c) 2023 STMicroelectronics. + ** All rights reserved. + ** + ** This software is licensed under terms that can be found in the LICENSE file + ** in the root directory of this software component. + ** If no LICENSE file comes with this software, it is provided AS-IS. + ** + ****************************************************************************** + */ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 272K + FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + + .ARM : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32h5/linker/STM32H562xx_FLASH.ld b/hw/bsp/stm32h5/linker/STM32H562xx_FLASH.ld new file mode 100644 index 000000000..aee2774a4 --- /dev/null +++ b/hw/bsp/stm32h5/linker/STM32H562xx_FLASH.ld @@ -0,0 +1,187 @@ +/* + ****************************************************************************** + ** + ** @file : LinkerScript.ld + ** + ** @author : Auto-generated by STM32CubeIDE + ** + ** @brief : Linker script for STM32H562xx Device from STM32H5 series + ** 2048Kbytes FLASH + ** 640Kbytes RAM + ** + ** Set heap size, stack size and stack location according + ** to application requirements. + ** + ** Set memory bank area and size if external memory is used + ** + ** Target : STMicroelectronics STM32 + ** + ** Distribution: The file is distributed as is, without any warranty + ** of any kind. + ** + ****************************************************************************** + ** @attention + ** + ** Copyright (c) 2023 STMicroelectronics. + ** All rights reserved. + ** + ** This software is licensed under terms that can be found in the LICENSE file + ** in the root directory of this software component. + ** If no LICENSE file comes with this software, it is provided AS-IS. + ** + ****************************************************************************** + */ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 640K + FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + + .ARM : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32h5/linker/STM32H563xx_FLASH.ld b/hw/bsp/stm32h5/linker/STM32H563xx_FLASH.ld new file mode 100644 index 000000000..129ed5170 --- /dev/null +++ b/hw/bsp/stm32h5/linker/STM32H563xx_FLASH.ld @@ -0,0 +1,187 @@ +/* + ****************************************************************************** + ** + ** @file : LinkerScript.ld + ** + ** @author : Auto-generated by STM32CubeIDE + ** + ** @brief : Linker script for STM32H563xx Device from STM32H5 series + ** 2048Kbytes FLASH + ** 640Kbytes RAM + ** + ** Set heap size, stack size and stack location according + ** to application requirements. + ** + ** Set memory bank area and size if external memory is used + ** + ** Target : STMicroelectronics STM32 + ** + ** Distribution: The file is distributed as is, without any warranty + ** of any kind. + ** + ****************************************************************************** + ** @attention + ** + ** Copyright (c) 2023 STMicroelectronics. + ** All rights reserved. + ** + ** This software is licensed under terms that can be found in the LICENSE file + ** in the root directory of this software component. + ** If no LICENSE file comes with this software, it is provided AS-IS. + ** + ****************************************************************************** + */ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 640K + FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + + .ARM : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32h5/linker/STM32H573xx_FLASH.ld b/hw/bsp/stm32h5/linker/STM32H573xx_FLASH.ld new file mode 100644 index 000000000..eb98f3163 --- /dev/null +++ b/hw/bsp/stm32h5/linker/STM32H573xx_FLASH.ld @@ -0,0 +1,187 @@ +/* + ****************************************************************************** + ** + ** @file : LinkerScript.ld + ** + ** @author : Auto-generated by STM32CubeIDE + ** + ** @brief : Linker script for STM32H573xx Device from STM32H5 series + ** 2048Kbytes FLASH + ** 640Kbytes RAM + ** + ** Set heap size, stack size and stack location according + ** to application requirements. + ** + ** Set memory bank area and size if external memory is used + ** + ** Target : STMicroelectronics STM32 + ** + ** Distribution: The file is distributed as is, without any warranty + ** of any kind. + ** + ****************************************************************************** + ** @attention + ** + ** Copyright (c) 2023 STMicroelectronics. + ** All rights reserved. + ** + ** This software is licensed under terms that can be found in the LICENSE file + ** in the root directory of this software component. + ** If no LICENSE file comes with this software, it is provided AS-IS. + ** + ****************************************************************************** + */ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 640K + FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + + .ARM : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32h5/stm32h5xx_hal_conf.h b/hw/bsp/stm32h5/stm32h5xx_hal_conf.h new file mode 100644 index 000000000..d017bb06b --- /dev/null +++ b/hw/bsp/stm32h5/stm32h5xx_hal_conf.h @@ -0,0 +1,355 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32h5xx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + * Copyright (c) 2018-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32h5xx_HAL_CONF_H +#define STM32h5xx_HAL_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/* #define HAL_ADC_MODULE_ENABLED */ +/* #define HAL_CEC_MODULE_ENABLED */ +/* #define HAL_COMP_MODULE_ENABLED */ +/* #define HAL_CRC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_DAC_MODULE_ENABLED */ +/* #define HAL_EXTI_MODULE_ENABLED */ +/* #define HAL_FDCAN_MODULE_ENABLED */ +/* #define HAL_HCD_MODULE_ENABLED */ +/* #define HAL_I2C_MODULE_ENABLED */ +/* #define HAL_I2S_MODULE_ENABLED */ +/* #define HAL_IWDG_MODULE_ENABLED */ +/* #define HAL_IRDA_MODULE_ENABLED */ +/* #define HAL_LPTIM_MODULE_ENABLED */ +/* #define HAL_PCD_MODULE_ENABLED */ +/* #define HAL_RNG_MODULE_ENABLED */ +/* #define HAL_RTC_MODULE_ENABLED */ +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_SMBUS_MODULE_ENABLED */ +/* #define HAL_SPI_MODULE_ENABLED */ +/* #define HAL_TIM_MODULE_ENABLED */ +/* #define HAL_USART_MODULE_ENABLED */ +/* #define HAL_WWDG_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +#define HAL_EXTI_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED +#define HAL_UART_MODULE_ENABLED + +/* ########################## Register Callbacks selection ############################## */ +/** + * @brief This is the list of modules where register callback can be used + */ +#define USE_HAL_ADC_REGISTER_CALLBACKS 0u +#define USE_HAL_CEC_REGISTER_CALLBACKS 0u +#define USE_HAL_COMP_REGISTER_CALLBACKS 0u +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0u +#define USE_HAL_DAC_REGISTER_CALLBACKS 0u +#define USE_HAL_FDCAN_REGISTER_CALLBACKS 0u +#define USE_HAL_HCD_REGISTER_CALLBACKS 0u +#define USE_HAL_I2C_REGISTER_CALLBACKS 0u +#define USE_HAL_I2S_REGISTER_CALLBACKS 0u +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0u +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0u +#define USE_HAL_PCD_REGISTER_CALLBACKS 0u +#define USE_HAL_RNG_REGISTER_CALLBACKS 0u +#define USE_HAL_RTC_REGISTER_CALLBACKS 0u +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0u +#define USE_HAL_SPI_REGISTER_CALLBACKS 0u +#define USE_HAL_TIM_REGISTER_CALLBACKS 0u +#define USE_HAL_UART_REGISTER_CALLBACKS 0u +#define USE_HAL_USART_REGISTER_CALLBACKS 0u +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0u + + +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) +#define HSE_VALUE 25000000U /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) +#define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal Core Speed oscillator (CSI) default value. + * This value is the default CSI range value after Reset. + */ +#if !defined (CSI_VALUE) +#define CSI_VALUE 4000000UL /*!< Value of the Internal oscillator in Hz*/ +#endif /* CSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) +#define HSI_VALUE 64000000UL /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI48) value for USB FS, SDMMC and RNG. + * This internal oscillator is mainly dedicated to provide a high precision clock to + * the USB peripheral by means of a special Clock Recovery System (CRS) circuitry. + * When the CRS is not used, the HSI48 RC oscillator runs on it default frequency + * which is subject to manufacturing process variations. + */ +#if !defined (HSI48_VALUE) +#define HSI48_VALUE 48000000UL /*!< Value of the Internal High Speed oscillator for USB FS/SDMMC/RNG in Hz. + The real value my vary depending on manufacturing process variations.*/ +#endif /* HSI48_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) +#define LSI_VALUE 32000UL /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz +The real value may vary depending on the variations +in voltage and temperature.*/ + +#if !defined (LSI_STARTUP_TIME) +#define LSI_STARTUP_TIME 130UL /*!< Time out for LSI start up, in ms */ +#endif /* LSI_STARTUP_TIME */ + +/** + * @brief External Low Speed oscillator (LSE) value. + * This value is used by the UART, RTC HAL module to compute the system frequency + */ +#if !defined (LSE_VALUE) +#define LSE_VALUE 32768UL /*!< Value of the External oscillator in Hz*/ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) +#define LSE_STARTUP_TIMEOUT 5000UL /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for SPI/SAI peripheral + * This value is used by the SPI/SAI HAL module to compute the SPI/SAI clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + + */ +#if !defined (EXTERNAL_CLOCK_VALUE) +#define EXTERNAL_CLOCK_VALUE 12288000UL /*!< Value of the External clock in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ############################################ System Configuration ################################################ */ + +/** + * @brief This is the HAL system configuration section + */ + +#define VDD_VALUE 3300UL /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY (15UL) /*!< tick interrupt priority (lowest by default) */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 0U /*!< Enable prefetch */ + + + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver +* Activated: CRC code is present inside driver +* Deactivated: CRC code cleaned from driver +*/ + +#define USE_SPI_CRC 0U + +/* ################## CRYP peripheral configuration ########################## */ + +#define USE_HAL_CRYP_SUSPEND_RESUME 1U + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include modules header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED +#include "stm32h5xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED +#include "stm32h5xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED +#include "stm32h5xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED +#include "stm32h5xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED +#include "stm32h5xx_hal_adc.h" +#include "stm32h5xx_hal_adc_ex.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED +#include "stm32h5xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED +#include "stm32h5xx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED +#include "stm32h5xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED +#include "stm32h5xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED +#include "stm32h5xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED +#include "stm32h5xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED +#include "stm32h5xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_FDCAN_MODULE_ENABLED +#include "stm32h5xx_hal_fdcan.h" +#endif /* HAL_FDCAN_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED +#include "stm32h5xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED +#include "stm32h5xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED +#include "stm32h5xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED +#include "stm32h5xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED +#include "stm32h5xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED +#include "stm32h5xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED +#include "stm32h5xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED +#include "stm32h5xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED +#include "stm32h5xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED +#include "stm32h5xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED +#include "stm32h5xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED +#include "stm32h5xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED +#include "stm32h5xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED +#include "stm32h5xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED +#include "stm32h5xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED +#include "stm32h5xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED +#include "stm32h5xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for functions parameters check. + * @param expr If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ +#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ +void assert_failed(uint8_t *file, uint32_t line); +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32h5xx_HAL_CONF_H */ diff --git a/hw/bsp/stm32h7/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/stm32h7/FreeRTOSConfig/FreeRTOSConfig.h index 6a1f6c043..8bbeefcc7 100644 --- a/hw/bsp/stm32h7/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/stm32h7/FreeRTOSConfig/FreeRTOSConfig.h @@ -59,7 +59,7 @@ #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) -#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*8*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 @@ -73,14 +73,15 @@ #define configENABLE_BACKWARD_COMPATIBILITY 1 #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 -#define configSUPPORT_STATIC_ALLOCATION 0 -#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 /* 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 +#define configCHECK_HANDLER_INSTALLATION 0 /* Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 @@ -116,23 +117,6 @@ #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 diff --git a/hw/bsp/stm32h7/boards/daisyseed/board.h b/hw/bsp/stm32h7/boards/daisyseed/board.h index 0ad809720..abc07488b 100644 --- a/hw/bsp/stm32h7/boards/daisyseed/board.h +++ b/hw/bsp/stm32h7/boards/daisyseed/board.h @@ -55,7 +55,7 @@ //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ -static inline void board_stm32h7_clock_init(void) +static inline void SystemClock_Config(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 }; RCC_OscInitTypeDef RCC_OscInitStruct = { 0 }; diff --git a/hw/bsp/stm32h7/boards/daisyseed/stm32h750ibkx_flash.ld b/hw/bsp/stm32h7/boards/daisyseed/stm32h750ibkx_flash.ld index 3588ada5b..e2bde9338 100644 --- a/hw/bsp/stm32h7/boards/daisyseed/stm32h750ibkx_flash.ld +++ b/hw/bsp/stm32h7/boards/daisyseed/stm32h750ibkx_flash.ld @@ -34,12 +34,6 @@ /* Entry Point */ ENTRY(Reset_Handler) -/* Highest address of the user mode stack */ -_estack = ORIGIN(RAM_D1) + LENGTH(RAM_D1); /* end of RAM */ -/* Generate a link error if heap and stack don't fit into RAM */ -_Min_Heap_Size = 0x2000 ; /* required amount of heap */ -_Min_Stack_Size = 0x4000 ; /* required amount of stack */ - /* Specify the memory areas */ MEMORY { @@ -51,6 +45,12 @@ MEMORY ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K } +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM_D1) + LENGTH(RAM_D1); /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x2000 ; /* required amount of heap */ +_Min_Stack_Size = 0x4000 ; /* required amount of stack */ + /* Define output sections */ SECTIONS { diff --git a/hw/bsp/stm32h7/boards/daisyseed/stm32h750ibkx_ram.ld b/hw/bsp/stm32h7/boards/daisyseed/stm32h750ibkx_ram.ld index 16f48b10a..03d9aaba3 100644 --- a/hw/bsp/stm32h7/boards/daisyseed/stm32h750ibkx_ram.ld +++ b/hw/bsp/stm32h7/boards/daisyseed/stm32h750ibkx_ram.ld @@ -34,12 +34,6 @@ /* Entry Point */ ENTRY(Reset_Handler) -/* Highest address of the user mode stack */ -_estack = ORIGIN(DTCMRAM) + LENGTH(DTCMRAM); /* end of RAM */ -/* Generate a link error if heap and stack don't fit into RAM */ -_Min_Heap_Size = 0x2000 ; /* required amount of heap */ -_Min_Stack_Size = 0x4000 ; /* required amount of stack */ - /* Specify the memory areas */ MEMORY { @@ -50,6 +44,12 @@ MEMORY ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K } +/* Highest address of the user mode stack */ +_estack = ORIGIN(DTCMRAM) + LENGTH(DTCMRAM); /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x2000 ; /* required amount of heap */ +_Min_Stack_Size = 0x4000 ; /* required amount of stack */ + /* Define output sections */ SECTIONS { diff --git a/hw/bsp/stm32h7/boards/stm32h723nucleo/board.h b/hw/bsp/stm32h7/boards/stm32h723nucleo/board.h index 0eb5e76ad..3d9344a87 100644 --- a/hw/bsp/stm32h7/boards/stm32h723nucleo/board.h +++ b/hw/bsp/stm32h7/boards/stm32h723nucleo/board.h @@ -62,7 +62,7 @@ //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ -static inline void board_stm32h7_clock_init(void) +static inline void SystemClock_Config(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 }; RCC_OscInitTypeDef RCC_OscInitStruct = { 0 }; diff --git a/hw/bsp/stm32h7/boards/stm32h743eval/board.h b/hw/bsp/stm32h7/boards/stm32h743eval/board.h index c46b525ca..22d66d735 100644 --- a/hw/bsp/stm32h7/boards/stm32h743eval/board.h +++ b/hw/bsp/stm32h7/boards/stm32h743eval/board.h @@ -61,7 +61,7 @@ //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ -static inline void board_stm32h7_clock_init(void) { +static inline void SystemClock_Config(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 }; RCC_OscInitTypeDef RCC_OscInitStruct = { 0 }; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = { 0 }; diff --git a/hw/bsp/stm32h7/boards/stm32h743nucleo/board.h b/hw/bsp/stm32h7/boards/stm32h743nucleo/board.h index 8c6a7ce5a..614e6e38b 100644 --- a/hw/bsp/stm32h7/boards/stm32h743nucleo/board.h +++ b/hw/bsp/stm32h7/boards/stm32h743nucleo/board.h @@ -53,60 +53,73 @@ //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ -static inline void board_stm32h7_clock_init(void) -{ - RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 }; - RCC_OscInitTypeDef RCC_OscInitStruct = { 0 }; +static inline void SystemClock_Config(void) { + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; - /* The PWR block is always enabled on the H7 series- there is no clock - enable. For now, use the default VOS3 scale mode (lowest) and limit clock - frequencies to avoid potential current draw problems from bus - power when using the max clock speeds throughout the chip. */ + /** Supply configuration update enable + */ + HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY); - /* Enable HSE Oscillator and activate PLL1 with HSE as source */ + /** Configure the main internal regulator output voltage + */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + + while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {} + + /** Initializes the RCC Oscillators according to the specified parameters + * in the RCC_OscInitTypeDef structure. + */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; - RCC_OscInitStruct.HSEState = RCC_HSE_ON; - RCC_OscInitStruct.HSIState = RCC_HSI_OFF; - RCC_OscInitStruct.CSIState = RCC_CSI_OFF; + RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; - RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; - RCC_OscInitStruct.PLL.PLLN = 336; + RCC_OscInitStruct.PLL.PLLM = 1; + RCC_OscInitStruct.PLL.PLLN = 100; RCC_OscInitStruct.PLL.PLLP = 2; - RCC_OscInitStruct.PLL.PLLQ = 7; - RCC_OscInitStruct.PLL.PLLR = 2; /* Unused */ - RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_0; - RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOMEDIUM; + RCC_OscInitStruct.PLL.PLLQ = 4; + RCC_OscInitStruct.PLL.PLLR = 2; + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3; + RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; RCC_OscInitStruct.PLL.PLLFRACN = 0; - HAL_RCC_OscConfig(&RCC_OscInitStruct); + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + Error_Handler(); + } - RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | \ - RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | \ - RCC_CLOCKTYPE_D3PCLK1); + /** Initializes the CPU, AHB and APB buses clocks + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK + |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2 + |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; - RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV1; - - /* Unlike on the STM32F4 family, it appears the maximum APB frequencies are - device-dependent- 120 MHz for this board according to Figure 2 of - the datasheet. Dividing by half will be safe for now. */ + RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2; RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2; - /* 4 wait states required for 168MHz and VOS3. */ - HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4); + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) + { + Error_Handler(); + } - /* Like on F4, on H7, USB's actual peripheral clock and bus clock are - separate. However, the main system PLL (PLL1) doesn't have a direct - connection to the USB peripheral clock to generate 48 MHz, so we do this - dance. This will connect PLL1's Q output to the USB peripheral clock. */ - RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInitStruct = { 0 }; - - RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; - RCC_PeriphCLKInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL; - HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct); + // Initialize USB clock + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = { 0 }; + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; + PeriphClkInitStruct.PLL3.PLL3M = 1; + PeriphClkInitStruct.PLL3.PLL3N = 24; + PeriphClkInitStruct.PLL3.PLL3P = 2; + PeriphClkInitStruct.PLL3.PLL3Q = 4; + PeriphClkInitStruct.PLL3.PLL3R = 2; + PeriphClkInitStruct.PLL3.PLL3RGE = RCC_PLL3VCIRANGE_3; + PeriphClkInitStruct.PLL3.PLL3FRACN = 0; + PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL3; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) + { + Error_Handler(); + } } static inline void board_stm32h7_post_init(void) diff --git a/hw/bsp/stm32h7/boards/stm32h743nucleo/cubemx/stm32h743nucleo.ioc b/hw/bsp/stm32h7/boards/stm32h743nucleo/cubemx/stm32h743nucleo.ioc new file mode 100644 index 000000000..bc269a852 --- /dev/null +++ b/hw/bsp/stm32h7/boards/stm32h743nucleo/cubemx/stm32h743nucleo.ioc @@ -0,0 +1,274 @@ +#MicroXplorer Configuration settings - do not modify +CAD.formats= +CAD.pinconfig= +CAD.provider= +ETH.IPParameters=MediaInterface +ETH.MediaInterface=HAL_ETH_RMII_MODE +File.Version=6 +KeepUserPlacement=false +Mcu.CPN=STM32H743ZIT6 +Mcu.Family=STM32H7 +Mcu.IP0=CORTEX_M7 +Mcu.IP1=ETH +Mcu.IP2=NVIC +Mcu.IP3=RCC +Mcu.IP4=SYS +Mcu.IP5=USART3 +Mcu.IP6=USB_OTG_FS +Mcu.IPNb=7 +Mcu.Name=STM32H743ZITx +Mcu.Package=LQFP144 +Mcu.Pin0=PC13 +Mcu.Pin1=PC14-OSC32_IN (OSC32_IN) +Mcu.Pin10=PC5 +Mcu.Pin11=PB0 +Mcu.Pin12=PB13 +Mcu.Pin13=PB14 +Mcu.Pin14=PD8 +Mcu.Pin15=PD9 +Mcu.Pin16=PD10 +Mcu.Pin17=PG7 +Mcu.Pin18=PA8 +Mcu.Pin19=PA9 +Mcu.Pin2=PC15-OSC32_OUT (OSC32_OUT) +Mcu.Pin20=PA11 +Mcu.Pin21=PA12 +Mcu.Pin22=PG11 +Mcu.Pin23=PG13 +Mcu.Pin24=PE1 +Mcu.Pin25=VP_SYS_VS_Systick +Mcu.Pin3=PH0-OSC_IN (PH0) +Mcu.Pin4=PH1-OSC_OUT (PH1) +Mcu.Pin5=PC1 +Mcu.Pin6=PA1 +Mcu.Pin7=PA2 +Mcu.Pin8=PA7 +Mcu.Pin9=PC4 +Mcu.PinsNb=26 +Mcu.ThirdPartyNb=0 +Mcu.UserConstants= +Mcu.UserName=STM32H743ZITx +MxCube.Version=6.9.2 +MxDb.Version=DB.6.0.92 +NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.ForceEnableDMAVector=true +NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 +NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.SysTick_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:false +NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +PA1.Locked=true +PA1.Mode=RMII +PA1.Signal=ETH_REF_CLK +PA11.Locked=true +PA11.Mode=Device_Only +PA11.Signal=USB_OTG_FS_DM +PA12.Locked=true +PA12.Mode=Device_Only +PA12.Signal=USB_OTG_FS_DP +PA2.Locked=true +PA2.Mode=RMII +PA2.Signal=ETH_MDIO +PA7.Locked=true +PA7.Mode=RMII +PA7.Signal=ETH_CRS_DV +PA8.Locked=true +PA8.Mode=Activate_SOF_FS +PA8.Signal=USB_OTG_FS_SOF +PA9.Locked=true +PA9.Mode=Activate_VBUS +PA9.Signal=USB_OTG_FS_VBUS +PB0.GPIOParameters=GPIO_Label +PB0.GPIO_Label=LD1 [Green Led] +PB0.Locked=true +PB0.Signal=GPIO_Output +PB13.Locked=true +PB13.Mode=RMII +PB13.Signal=ETH_TXD1 +PB14.GPIOParameters=GPIO_Label +PB14.GPIO_Label=LD3 [Red Led] +PB14.Locked=true +PB14.Signal=GPIO_Output +PC1.Locked=true +PC1.Mode=RMII +PC1.Signal=ETH_MDC +PC13.GPIOParameters=GPIO_Label +PC13.GPIO_Label=B1 [Blue PushButton] +PC13.Locked=true +PC13.Signal=GPIO_Input +PC14-OSC32_IN\ (OSC32_IN).Locked=true +PC14-OSC32_IN\ (OSC32_IN).Mode=LSE-External-Oscillator +PC14-OSC32_IN\ (OSC32_IN).Signal=RCC_OSC32_IN +PC15-OSC32_OUT\ (OSC32_OUT).Locked=true +PC15-OSC32_OUT\ (OSC32_OUT).Mode=LSE-External-Oscillator +PC15-OSC32_OUT\ (OSC32_OUT).Signal=RCC_OSC32_OUT +PC4.Locked=true +PC4.Mode=RMII +PC4.Signal=ETH_RXD0 +PC5.Locked=true +PC5.Mode=RMII +PC5.Signal=ETH_RXD1 +PD10.GPIOParameters=GPIO_Label +PD10.GPIO_Label=USB_OTG_FS_PWR_EN +PD10.Locked=true +PD10.Signal=GPIO_Output +PD8.GPIOParameters=GPIO_Label +PD8.GPIO_Label=STLINK_RX +PD8.Locked=true +PD8.Mode=Asynchronous +PD8.Signal=USART3_TX +PD9.GPIOParameters=GPIO_Label +PD9.GPIO_Label=STLINK_TX +PD9.Locked=true +PD9.Mode=Asynchronous +PD9.Signal=USART3_RX +PE1.GPIOParameters=GPIO_Label +PE1.GPIO_Label=LD2 [Yellow Led] +PE1.Locked=true +PE1.Signal=GPIO_Output +PG11.Locked=true +PG11.Mode=RMII +PG11.Signal=ETH_TX_EN +PG13.Locked=true +PG13.Mode=RMII +PG13.Signal=ETH_TXD0 +PG7.GPIOParameters=GPIO_Label +PG7.GPIO_Label=USB_OTG_FS_OVCR +PG7.Locked=true +PG7.Signal=GPXTI7 +PH0-OSC_IN\ (PH0).Locked=true +PH0-OSC_IN\ (PH0).Mode=HSE-External-Clock-Source +PH0-OSC_IN\ (PH0).Signal=RCC_OSC_IN +PH1-OSC_OUT\ (PH1).Locked=true +PH1-OSC_OUT\ (PH1).Signal=RCC_OSC_OUT +PinOutPanel.RotationAngle=0 +ProjectManager.AskForMigrate=true +ProjectManager.BackupPrevious=false +ProjectManager.CompilerOptimize=6 +ProjectManager.ComputerToolchain=false +ProjectManager.CoupleFile=false +ProjectManager.CustomerFirmwarePackage= +ProjectManager.DefaultFWLocation=true +ProjectManager.DeletePrevious=true +ProjectManager.DeviceId=STM32H743ZITx +ProjectManager.FirmwarePackage=STM32Cube FW_H7 V1.11.1 +ProjectManager.FreePins=false +ProjectManager.HalAssertFull=false +ProjectManager.HeapSize=0x200 +ProjectManager.KeepUserCode=true +ProjectManager.LastFirmware=true +ProjectManager.LibraryCopy=2 +ProjectManager.MainLocation=Core/Src +ProjectManager.NoMain=false +ProjectManager.PreviousToolchain=STM32CubeIDE +ProjectManager.ProjectBuild=false +ProjectManager.ProjectFileName=stm32h743nucleo.ioc +ProjectManager.ProjectName=stm32h743nucleo +ProjectManager.ProjectStructure= +ProjectManager.RegisterCallBack= +ProjectManager.StackSize=0x400 +ProjectManager.TargetToolchain=Makefile +ProjectManager.ToolChainLocation= +ProjectManager.UAScriptAfterPath= +ProjectManager.UAScriptBeforePath= +ProjectManager.UnderRoot=false +ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,false-3-MX_ETH_Init-ETH-false-HAL-true,4-MX_USART3_UART_Init-USART3-false-HAL-true,5-MX_USB_OTG_FS_PCD_Init-USB_OTG_FS-false-HAL-true,0-MX_CORTEX_M7_Init-CORTEX_M7-false-HAL-true +RCC.ADCFreq_Value=16125000 +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=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=200000000 +RCC.DFSDMFreq_Value=100000000 +RCC.DIVM1=1 +RCC.DIVM3=1 +RCC.DIVN1=100 +RCC.DIVN3=24 +RCC.DIVP1Freq_Value=400000000 +RCC.DIVP2Freq_Value=16125000 +RCC.DIVP3Freq_Value=96000000 +RCC.DIVQ1=4 +RCC.DIVQ1Freq_Value=200000000 +RCC.DIVQ2Freq_Value=16125000 +RCC.DIVQ3=4 +RCC.DIVQ3Freq_Value=48000000 +RCC.DIVR1Freq_Value=400000000 +RCC.DIVR2Freq_Value=16125000 +RCC.DIVR3Freq_Value=96000000 +RCC.FDCANFreq_Value=200000000 +RCC.FMCFreq_Value=200000000 +RCC.FamilyName=M +RCC.HCLK3ClockFreq_Value=200000000 +RCC.HCLKFreq_Value=200000000 +RCC.HPRE=RCC_HCLK_DIV2 +RCC.HRTIMFreq_Value=200000000 +RCC.HSE_VALUE=8000000 +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,DIVR1Freq_Value,DIVR2Freq_Value,DIVR3Freq_Value,FDCANFreq_Value,FMCFreq_Value,FamilyName,HCLK3ClockFreq_Value,HCLKFreq_Value,HPRE,HRTIMFreq_Value,HSE_VALUE,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=96000000 +RCC.MCO1PinFreq_Value=64000000 +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=200000000 +RCC.RNGFreq_Value=48000000 +RCC.RTCFreq_Value=32000 +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=200000000 +RCC.Tim2OutputFreq_Value=200000000 +RCC.TraceFreq_Value=64000000 +RCC.USART16Freq_Value=100000000 +RCC.USART234578Freq_Value=100000000 +RCC.USBCLockSelection=RCC_USBCLKSOURCE_PLL3 +RCC.USBFreq_Value=48000000 +RCC.VCO1OutputFreq_Value=800000000 +RCC.VCO2OutputFreq_Value=32250000 +RCC.VCO3OutputFreq_Value=192000000 +RCC.VCOInput1Freq_Value=8000000 +RCC.VCOInput2Freq_Value=250000 +RCC.VCOInput3Freq_Value=8000000 +SH.GPXTI7.0=GPIO_EXTI7 +SH.GPXTI7.ConfNb=1 +USART3.IPParameters=VirtualMode-Asynchronous +USART3.VirtualMode-Asynchronous=VM_ASYNC +USB_OTG_FS.IPParameters=VirtualMode +USB_OTG_FS.VirtualMode=Device_Only +VP_SYS_VS_Systick.Mode=SysTick +VP_SYS_VS_Systick.Signal=SYS_VS_Systick +board=NUCLEO-H743ZI2 +boardIOC=true diff --git a/hw/bsp/stm32h7/boards/stm32h745disco/board.h b/hw/bsp/stm32h7/boards/stm32h745disco/board.h index d7d3e8723..6d1506ca1 100644 --- a/hw/bsp/stm32h7/boards/stm32h745disco/board.h +++ b/hw/bsp/stm32h7/boards/stm32h745disco/board.h @@ -55,7 +55,7 @@ //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ -static inline void board_stm32h7_clock_init(void) +static inline void SystemClock_Config(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 }; RCC_OscInitTypeDef RCC_OscInitStruct = { 0 }; diff --git a/hw/bsp/stm32h7/boards/stm32h750bdk/board.cmake b/hw/bsp/stm32h7/boards/stm32h750bdk/board.cmake new file mode 100644 index 000000000..6eff708a8 --- /dev/null +++ b/hw/bsp/stm32h7/boards/stm32h750bdk/board.cmake @@ -0,0 +1,16 @@ +set(MCU_VARIANT stm32h750xx) +set(JLINK_DEVICE stm32h750xb_m7) + +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${MCU_VARIANT}_flash_CM7.ld) +set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + STM32H750xx + HSE_VALUE=25000000 + CORE_CM7 + # default to PORT 0 + BOARD_TUD_RHPORT=0 + BOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED + ) +endfunction() diff --git a/hw/bsp/stm32h7/boards/stm32h750bdk/board.h b/hw/bsp/stm32h7/boards/stm32h750bdk/board.h new file mode 100644 index 000000000..c5922efc4 --- /dev/null +++ b/hw/bsp/stm32h7/boards/stm32h750bdk/board.h @@ -0,0 +1,144 @@ +/* + * 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_PORT GPIOJ +#define LED_PIN GPIO_PIN_2 +#define LED_STATE_ON 1 + +// Blue push-button +#define BUTTON_PORT GPIOC +#define BUTTON_PIN GPIO_PIN_13 +#define BUTTON_STATE_ACTIVE 1 + +// UART +#define UART_DEV USART3 +#define UART_CLK_EN __HAL_RCC_USART3_CLK_ENABLE +#define UART_GPIO_PORT GPIOB +#define UART_GPIO_AF GPIO_AF7_USART3 +#define UART_TX_PIN GPIO_PIN_10 +#define UART_RX_PIN GPIO_PIN_11 + +// VBUS Sense detection +#define OTG_FS_VBUS_SENSE 1 +#define OTG_HS_VBUS_SENSE 0 + +// USB HS External PHY Pin: CLK, STP, DIR, NXT, D0-D7 +#define ULPI_PINS \ + {GPIOA, GPIO_PIN_3 }, {GPIOA, GPIO_PIN_5 }, {GPIOB, GPIO_PIN_0 }, {GPIOB, GPIO_PIN_1 }, \ + {GPIOB, GPIO_PIN_5 }, {GPIOB, GPIO_PIN_10}, {GPIOB, GPIO_PIN_11}, {GPIOB, GPIO_PIN_12}, \ + {GPIOB, GPIO_PIN_13}, {GPIOC, GPIO_PIN_0 }, {GPIOH, GPIO_PIN_4 }, {GPIOI, GPIO_PIN_11} + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void SystemClock_Config(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 }; + RCC_OscInitTypeDef RCC_OscInitStruct = { 0 }; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = { 0 }; + + /*!< Supply configuration update enable */ + HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY); + + /* The voltage scaling allows optimizing the power consumption when the + device is clocked below the maximum system frequency, to update the + voltage scaling value regarding system frequency refer to product + datasheet. */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + + 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; + RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; + RCC_OscInitStruct.HSIState = RCC_HSI_OFF; + RCC_OscInitStruct.CSIState = RCC_CSI_OFF; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + + /* PLL1 for System Clock */ + RCC_OscInitStruct.PLL.PLLM = 5; + RCC_OscInitStruct.PLL.PLLN = 160; + RCC_OscInitStruct.PLL.PLLFRACN = 0; + RCC_OscInitStruct.PLL.PLLP = 2; + RCC_OscInitStruct.PLL.PLLR = 2; + RCC_OscInitStruct.PLL.PLLQ = 4; + + RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOMEDIUM; + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* PLL3 for USB Clock */ + PeriphClkInitStruct.PLL3.PLL3M = 25; + PeriphClkInitStruct.PLL3.PLL3N = 336; + PeriphClkInitStruct.PLL3.PLL3FRACN = 0; + PeriphClkInitStruct.PLL3.PLL3P = 2; + PeriphClkInitStruct.PLL3.PLL3R = 2; + PeriphClkInitStruct.PLL3.PLL3Q = 7; + + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; + PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL3; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + + /* Select PLL as system clock source and configure bus clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_PCLK1 | \ + RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_D3PCLK1); + + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2; + RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; + RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV1; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4); + + /*activate CSI clock mondatory for I/O Compensation Cell*/ + __HAL_RCC_CSI_ENABLE() ; + + /* Enable SYSCFG clock mondatory for I/O Compensation Cell */ + __HAL_RCC_SYSCFG_CLK_ENABLE() ; + + /* Enables the I/O Compensation Cell */ + HAL_EnableCompensationCell(); +} + +static inline void board_stm32h7_post_init(void) +{ + // For this board does nothing +} + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/hw/bsp/stm32h7/boards/stm32h750bdk/board.mk b/hw/bsp/stm32h7/boards/stm32h750bdk/board.mk new file mode 100644 index 000000000..d37a425fb --- /dev/null +++ b/hw/bsp/stm32h7/boards/stm32h750bdk/board.mk @@ -0,0 +1,21 @@ +# STM32H745I-DISCO uses OTG_FS +# FIXME: Reset enumerates, un/replug USB plug does not enumerate + +CFLAGS += -DSTM32H750xx -DCORE_CM7 -DHSE_VALUE=25000000 + +# Default is FulSpeed port +PORT ?= 0 + +# GCC +SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32h750xx.s +LD_FILE_GCC = $(BOARD_PATH)/stm32h750xx_flash_CM7.ld + +# IAR +SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_stm32h750xx.s +LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/stm32h750xx_flash.icf + +# For flash-jlink target +JLINK_DEVICE = stm32h750xb_m7 + +# flash target using on-board stlink +flash: flash-stlink diff --git a/hw/bsp/mm32/boards/mm32f327x_bluepillplus/flash.ld b/hw/bsp/stm32h7/boards/stm32h750bdk/stm32h750xx_flash_CM7.ld similarity index 70% rename from hw/bsp/mm32/boards/mm32f327x_bluepillplus/flash.ld rename to hw/bsp/stm32h7/boards/stm32h750bdk/stm32h750xx_flash_CM7.ld index 796ed04f6..30f220a42 100644 --- a/hw/bsp/mm32/boards/mm32f327x_bluepillplus/flash.ld +++ b/hw/bsp/stm32h7/boards/stm32h750bdk/stm32h750xx_flash_CM7.ld @@ -1,35 +1,42 @@ /* - * The MIT License (MIT) - * - * Copyright (c) 2020 MM32 SE TEAM - * - * 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. - */ +****************************************************************************** +** + +** File : LinkerScript.ld +** +** +** Abstract : Linker script for STM32H7 series +** 128Kbytes FLASH and 1Mbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed īŋŊas is,īŋŊ without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +** Copyright (c) 2019 STMicroelectronics. +** All rights reserved. +** +** This software component is licensed by ST under BSD 3-Clause license, +** the "License"; You may not use this file except in compliance with the +** License. You may obtain a copy of the License at: +** opensource.org/licenses/BSD-3-Clause +** +**************************************************************************** +*/ /* Entry Point */ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ -_estack = 0x2001FFFF; /* end of RAM */ - +_estack = 0x20020000; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */ @@ -37,8 +44,9 @@ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Specify the memory areas */ MEMORY { -FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K -RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K +FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 1M +ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K } /* Define output sections */ @@ -150,7 +158,6 @@ SECTIONS } >RAM - /* Remove information from the standard libraries */ /DISCARD/ : { diff --git a/hw/bsp/stm32h7/boards/waveshare_openh743i/board.h b/hw/bsp/stm32h7/boards/waveshare_openh743i/board.h index a3d0d07f9..8f4af6f48 100644 --- a/hw/bsp/stm32h7/boards/waveshare_openh743i/board.h +++ b/hw/bsp/stm32h7/boards/waveshare_openh743i/board.h @@ -104,7 +104,7 @@ //--------------------------------------------------------------------+ // RCC Clock //--------------------------------------------------------------------+ -static inline void board_stm32h7_clock_init(void) +static inline void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; diff --git a/hw/bsp/stm32h7/family.c b/hw/bsp/stm32h7/family.c index 309a4239e..adeb38e74 100644 --- a/hw/bsp/stm32h7/family.c +++ b/hw/bsp/stm32h7/family.c @@ -29,19 +29,23 @@ #include "stm32h7xx_hal.h" #include "bsp/board_api.h" + +TU_ATTR_UNUSED static void Error_Handler(void) { +} + #include "board.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ -// Despite being call USB2_OTG +// Despite being call USB2_OTG_FS on some MCUs // OTG_FS is marked as RHPort0 by TinyUSB to be consistent across stm32 port void OTG_FS_IRQHandler(void) { tud_int_handler(0); } -// Despite being call USB2_OTG +// Despite being call USB1_OTG_HS on some MCUs // OTG_HS is marked as RHPort1 by TinyUSB to be consistent across stm32 port void OTG_HS_IRQHandler(void) { tud_int_handler(1); @@ -79,7 +83,8 @@ void trace_etm_init(void) { #endif void board_init(void) { - board_stm32h7_clock_init(); + // Implemented in board.h + SystemClock_Config(); // Enable All GPIOs clocks __HAL_RCC_GPIOA_CLK_ENABLE(); diff --git a/hw/bsp/stm32h7/family.cmake b/hw/bsp/stm32h7/family.cmake index c08857a50..026c7c3df 100644 --- a/hw/bsp/stm32h7/family.cmake +++ b/hw/bsp/stm32h7/family.cmake @@ -1,9 +1,5 @@ include_guard() -if (NOT BOARD) - message(FATAL_ERROR "BOARD not specified") -endif () - set(ST_FAMILY h7) set(ST_PREFIX stm32${ST_FAMILY}xx) @@ -16,7 +12,7 @@ include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) # toolchain set up set(CMAKE_SYSTEM_PROCESSOR cortex-m7 CACHE INTERNAL "System Processor") -set(CMAKE_TOOLCHAIN_FILE ${TOP}/tools/cmake/toolchain/arm_${TOOLCHAIN}.cmake) +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS STM32H7 CACHE INTERNAL "") @@ -26,55 +22,59 @@ set(FAMILY_MCUS STM32H7 CACHE INTERNAL "") #------------------------------------ # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) - if (NOT TARGET ${BOARD_TARGET}) - # Startup & Linker script - set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) - set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) + if (TARGET ${BOARD_TARGET}) + return() + endif() - if(NOT DEFINED LD_FILE_IAR) - set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) - endif() + # Startup & Linker script + set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) - add_library(${BOARD_TARGET} STATIC - ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_dma.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} - ) - target_include_directories(${BOARD_TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMSIS_5}/CMSIS/Core/Include - ${ST_CMSIS}/Include - ${ST_HAL_DRIVER}/Inc - ) - target_compile_options(${BOARD_TARGET} PUBLIC - ) - target_compile_definitions(${BOARD_TARGET} PUBLIC - ) + set(LD_FILE_Clang ${LD_FILE_GNU}) + if(NOT DEFINED LD_FILE_IAR) + set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + endif() - update_board(${BOARD_TARGET}) + add_library(${BOARD_TARGET} STATIC + ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_dma.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_5}/CMSIS/Core/Include + ${ST_CMSIS}/Include + ${ST_HAL_DRIVER}/Inc + ) + #target_compile_options(${BOARD_TARGET} PUBLIC) + #target_compile_definitions(${BOARD_TARGET} PUBLIC) - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - -nostartfiles - # 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 () + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) endif () endfunction() diff --git a/hw/bsp/stm32h7/family.mk b/hw/bsp/stm32h7/family.mk index a1ff26d0b..40df190db 100644 --- a/hw/bsp/stm32h7/family.mk +++ b/hw/bsp/stm32h7/family.mk @@ -30,10 +30,15 @@ endif # GCC Flags CFLAGS_GCC += \ -flto \ - -nostdlib -nostartfiles # suppress warning caused by vendor mcu driver -CFLAGS_GCC += -Wno-error=maybe-uninitialized -Wno-error=cast-align -Wno-error=unused-parameter +CFLAGS_GCC += \ + -Wno-error=cast-align \ + -Wno-error=unused-parameter \ + +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs # ----------------- # Sources & Include diff --git a/hw/bsp/stm32h7/linker/stm32h723xx_flash.ld b/hw/bsp/stm32h7/linker/stm32h723xx_flash.ld index 05e0d4e26..b779c0d35 100644 --- a/hw/bsp/stm32h7/linker/stm32h723xx_flash.ld +++ b/hw/bsp/stm32h7/linker/stm32h723xx_flash.ld @@ -34,12 +34,6 @@ /* Entry Point */ ENTRY(Reset_Handler) -/* Highest address of the user mode stack */ -_estack = ORIGIN(RAM_D1) + LENGTH(RAM_D1); /* end of RAM */ -/* Generate a link error if heap and stack don't fit into RAM */ -_Min_Heap_Size = 0x200 ; /* required amount of heap */ -_Min_Stack_Size = 0x400 ; /* required amount of stack */ - /* Specify the memory areas */ MEMORY { @@ -51,6 +45,12 @@ MEMORY RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 16K } +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM_D1) + LENGTH(RAM_D1); /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200 ; /* required amount of heap */ +_Min_Stack_Size = 0x400 ; /* required amount of stack */ + /* Define output sections */ SECTIONS { diff --git a/hw/bsp/stm32l0/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/stm32l0/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..40146e73a --- /dev/null +++ b/hw/bsp/stm32l0/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,149 @@ +/* + * 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 "stm32l0xx.h" +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#define configENABLE_FPU 0 +#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 4 +#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 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* 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 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* 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 + +/* 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 2 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<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 diff --git a/hw/bsp/stm32l4/boards/stm32l4p5nucleo/STM32L4P5ZGTX_FLASH.ld b/hw/bsp/stm32l4/boards/stm32l4p5nucleo/STM32L4P5ZGTX_FLASH.ld index 02c07dd74..6a2eaa0f7 100644 --- a/hw/bsp/stm32l4/boards/stm32l4p5nucleo/STM32L4P5ZGTX_FLASH.ld +++ b/hw/bsp/stm32l4/boards/stm32l4p5nucleo/STM32L4P5ZGTX_FLASH.ld @@ -52,12 +52,6 @@ /* Entry Point */ ENTRY(Reset_Handler) -/* Highest address of the user mode stack */ -_estack = ORIGIN(RAM) + 0x0001FFFF; /* end of "SRAM1" Ram type memory */ - -_Min_Heap_Size = 0x200; /* required amount of heap */ -_Min_Stack_Size = 0x400; /* required amount of stack */ - /* Memories definition */ MEMORY { @@ -65,6 +59,12 @@ MEMORY ROM (rx) : ORIGIN = 0x08000000, LENGTH = 1024K } +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + 0x0001FFFF; /* end of "SRAM1" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + /* Sections */ SECTIONS { diff --git a/hw/bsp/stm32l4/family.cmake b/hw/bsp/stm32l4/family.cmake index 87f87004b..b6eae7c7f 100644 --- a/hw/bsp/stm32l4/family.cmake +++ b/hw/bsp/stm32l4/family.cmake @@ -1,9 +1,5 @@ include_guard() -if (NOT BOARD) - message(FATAL_ERROR "BOARD not specified") -endif () - set(ST_FAMILY l4) set(ST_PREFIX stm32${ST_FAMILY}xx) @@ -16,7 +12,7 @@ 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(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS STM32L4 CACHE INTERNAL "") @@ -26,52 +22,57 @@ set(FAMILY_MCUS STM32L4 CACHE INTERNAL "") #------------------------------------ # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) - if (NOT TARGET ${BOARD_TARGET}) - # Startup & Linker script - set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) - set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) - set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + if (TARGET ${BOARD_TARGET}) + return() + endif() - add_library(${BOARD_TARGET} STATIC - ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_dma.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} - ) - target_include_directories(${BOARD_TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMSIS_5}/CMSIS/Core/Include - ${ST_CMSIS}/Include - ${ST_HAL_DRIVER}/Inc - ) - target_compile_options(${BOARD_TARGET} PUBLIC - ) - target_compile_definitions(${BOARD_TARGET} PUBLIC - ) + # Startup & Linker script + set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) - update_board(${BOARD_TARGET}) + set(LD_FILE_Clang ${LD_FILE_GNU}) + set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - -nostartfiles - # 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 () + add_library(${BOARD_TARGET} STATIC + ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_dma.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_5}/CMSIS/Core/Include + ${ST_CMSIS}/Include + ${ST_HAL_DRIVER}/Inc + ) +# target_compile_options(${BOARD_TARGET} PUBLIC) +# target_compile_definitions(${BOARD_TARGET} PUBLIC) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) endif () endfunction() diff --git a/hw/bsp/stm32l4/family.mk b/hw/bsp/stm32l4/family.mk index c16040887..411436cf6 100644 --- a/hw/bsp/stm32l4/family.mk +++ b/hw/bsp/stm32l4/family.mk @@ -16,10 +16,15 @@ CFLAGS += \ # GCC Flags CFLAGS_GCC += \ -flto \ - -nostdlib -nostartfiles + -Wno-error=cast-align \ -# suppress warning caused by vendor mcu driver -CFLAGS_GCC += -Wno-error=maybe-uninitialized -Wno-error=cast-align +ifeq ($(TOOLCHAIN),gcc) +CFLAGS_GCC += -Wno-error=maybe-uninitialized +endif + +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs # ----------------- # Sources & Include diff --git a/hw/bsp/stm32u5/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/stm32u5/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..b51020590 --- /dev/null +++ b/hw/bsp/stm32u5/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,149 @@ +/* + * 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 "stm32u5xx.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 4 +#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 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* 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 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* 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 + +/* 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 4 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + } >FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } >FLASH + + .ARM : + { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32u5/boards/stm32u5a5nucleo/board.cmake b/hw/bsp/stm32u5/boards/stm32u5a5nucleo/board.cmake new file mode 100644 index 000000000..230c3b722 --- /dev/null +++ b/hw/bsp/stm32u5/boards/stm32u5a5nucleo/board.cmake @@ -0,0 +1,11 @@ +set(MCU_VARIANT stm32u5a5xx) +set(JLINK_DEVICE stm32u5a5zj) + +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32U5A5ZJTXQ_FLASH.ld) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + STM32U5A5xx + HSE_VALUE=16000000UL + ) +endfunction() diff --git a/hw/bsp/stm32u5/boards/stm32u5a5nucleo/board.h b/hw/bsp/stm32u5/boards/stm32u5a5nucleo/board.h new file mode 100644 index 000000000..062fb807f --- /dev/null +++ b/hw/bsp/stm32u5/boards/stm32u5a5nucleo/board.h @@ -0,0 +1,144 @@ +/* + * 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 BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +// LED GREEN +#define LED_PORT GPIOC +#define LED_PIN GPIO_PIN_7 +#define LED_STATE_ON 1 + +// BUTTON +#define BUTTON_PORT GPIOC +#define BUTTON_PIN GPIO_PIN_13 +#define BUTTON_STATE_ACTIVE 1 + +// UART Enable for STLink VCOM +#define UART_DEV USART1 +#define UART_CLK_EN __HAL_RCC_USART1_CLK_ENABLE +#define UART_GPIO_PORT GPIOA +#define UART_GPIO_AF GPIO_AF7_USART1 +#define UART_TX_PIN GPIO_PIN_9 +#define UART_RX_PIN GPIO_PIN_10 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ + +static void SystemClock_Config(void) { + RCC_OscInitTypeDef RCC_OscInitStruct = { 0 }; + RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 }; + + __HAL_RCC_PWR_CLK_ENABLE(); + HAL_PWREx_EnableVddA(); + + /** Configure the main internal regulator output voltage + */ + if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK) { + Error_Handler(); + } + + /** Initializes the CPU, AHB and APB buses clocks + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLMBOOST = RCC_PLLMBOOST_DIV1; + RCC_OscInitStruct.PLL.PLLM = 1; + RCC_OscInitStruct.PLL.PLLN = 20; + RCC_OscInitStruct.PLL.PLLP = 8; + RCC_OscInitStruct.PLL.PLLQ = 2; + RCC_OscInitStruct.PLL.PLLR = 2; + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLLVCIRANGE_1; + RCC_OscInitStruct.PLL.PLLFRACN = 0; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { + Error_Handler(); + } + + /** Initializes the CPU, AHB and APB buses clocks + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK + | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 + | RCC_CLOCKTYPE_PCLK3; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1; + + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4); + + // USB Clock + __HAL_RCC_SYSCFG_CLK_ENABLE(); + + RCC_PeriphCLKInitTypeDef usb_clk_init = { 0}; + usb_clk_init.PeriphClockSelection = RCC_PERIPHCLK_USBPHY; + usb_clk_init.UsbPhyClockSelection = RCC_USBPHYCLKSOURCE_HSE; + if (HAL_RCCEx_PeriphCLKConfig(&usb_clk_init) != HAL_OK) { + Error_Handler(); + } + + /** Set the OTG PHY reference clock selection + */ + HAL_SYSCFG_SetOTGPHYReferenceClockSelection(SYSCFG_OTG_HS_PHY_CLK_SELECT_1); + + // USART clock + RCC_PeriphCLKInitTypeDef uart_clk_init = { 0}; + uart_clk_init.PeriphClockSelection = RCC_PERIPHCLK_USART1; + uart_clk_init.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2; + if (HAL_RCCEx_PeriphCLKConfig(&uart_clk_init) != HAL_OK) { + Error_Handler(); + } +} + +static void SystemPower_Config(void) { + HAL_PWREx_EnableVddIO2(); + + /* + * Switch to SMPS regulator instead of LDO + */ + if (HAL_PWREx_ConfigSupply(PWR_SMPS_SUPPLY) != HAL_OK) { + Error_Handler(); + } +/* USER CODE BEGIN PWR */ +/* USER CODE END PWR */ +} + + +#ifdef __cplusplus +} +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/stm32u5/boards/stm32u5a5nucleo/board.mk b/hw/bsp/stm32u5/boards/stm32u5a5nucleo/board.mk new file mode 100644 index 000000000..e759cec24 --- /dev/null +++ b/hw/bsp/stm32u5/boards/stm32u5a5nucleo/board.mk @@ -0,0 +1,11 @@ +CFLAGS += \ + -DSTM32U5A5xx \ + -DHSE_VALUE=16000000UL \ + +# All source paths should be relative to the top level. +LD_FILE = ${BOARD_PATH}/STM32U5A5ZJTXQ_FLASH.ld + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32u5a5xx.s + +# For flash-jlink target +JLINK_DEVICE = stm32u575zi diff --git a/hw/bsp/stm32u5/boards/stm32u5a5nucleo/cubemx/stm32u5a5nucleo.ioc b/hw/bsp/stm32u5/boards/stm32u5a5nucleo/cubemx/stm32u5a5nucleo.ioc new file mode 100644 index 000000000..289734040 --- /dev/null +++ b/hw/bsp/stm32u5/boards/stm32u5a5nucleo/cubemx/stm32u5a5nucleo.ioc @@ -0,0 +1,352 @@ +#MicroXplorer Configuration settings - do not modify +ADC1.Channel-1\#ChannelRegularConversion=ADC_CHANNEL_2 +ADC1.IPParameters=Rank-1\#ChannelRegularConversion,master,Channel-1\#ChannelRegularConversion,SamplingTime-1\#ChannelRegularConversion,OffsetNumber-1\#ChannelRegularConversion,MonitoredBy-1\#ChannelRegularConversion,NbrOfConversionFlag +ADC1.MonitoredBy-1\#ChannelRegularConversion=__NULL +ADC1.NbrOfConversionFlag=1 +ADC1.OffsetNumber-1\#ChannelRegularConversion=ADC_OFFSET_NONE +ADC1.Rank-1\#ChannelRegularConversion=1 +ADC1.SamplingTime-1\#ChannelRegularConversion=ADC_SAMPLETIME_5CYCLE +ADC1.master=1 +CAD.formats= +CAD.pinconfig= +CAD.provider= +CORTEX_M33_NS.userName=CORTEX_M33 +File.Version=6 +GPDMA1.DIRECTION_GPDMACH0=DMA_MEMORY_TO_PERIPH +GPDMA1.DIRECTION_GPDMACH3=DMA_MEMORY_TO_PERIPH +GPDMA1.IPHANDLE_GPDMACH0-SIMPLEREQUEST_GPDMACH0=__NULL +GPDMA1.IPHANDLE_GPDMACH3-SIMPLEREQUEST_GPDMACH3=__NULL +GPDMA1.IPHANDLE_GPDMACH5-SIMPLEREQUEST_GPDMACH5=__NULL +GPDMA1.IPParameters=IPHANDLE_GPDMACH5-SIMPLEREQUEST_GPDMACH5,REQUEST_GPDMACH5,IPHANDLE_GPDMACH3-SIMPLEREQUEST_GPDMACH3,REQUEST_GPDMACH3,DIRECTION_GPDMACH3,IPHANDLE_GPDMACH0-SIMPLEREQUEST_GPDMACH0,REQUEST_GPDMACH0,DIRECTION_GPDMACH0,SRCINC_GPDMACH0 +GPDMA1.REQUEST_GPDMACH0=GPDMA1_REQUEST_USART1_TX +GPDMA1.REQUEST_GPDMACH3=GPDMA1_REQUEST_UCPD1_TX +GPDMA1.REQUEST_GPDMACH5=GPDMA1_REQUEST_UCPD1_RX +GPDMA1.SRCINC_GPDMACH0=DMA_SINC_INCREMENTED +GPIO.groupedBy=Group By Peripherals +KeepUserPlacement=false +MMTAppReg1.MEMORYMAP.AP=RW_priv_only +MMTAppReg1.MEMORYMAP.AppRegionName=RAM +MMTAppReg1.MEMORYMAP.ContextName=CortexM33 +MMTAppReg1.MEMORYMAP.CoreName=ARM Cortex-M33 +MMTAppReg1.MEMORYMAP.DefaultDataRegion=true +MMTAppReg1.MEMORYMAP.IPParameters=StartAddress,Size,CoreName,DefaultDataRegion,ContextName,Name,AP +MMTAppReg1.MEMORYMAP.Name=RAM +MMTAppReg1.MEMORYMAP.Size=2555904 +MMTAppReg1.MEMORYMAP.StartAddress=0x20000000 +MMTAppReg2.MEMORYMAP.AppRegionName=RAM Reserved Alias Region +MMTAppReg2.MEMORYMAP.CoreName=ARM Cortex-M33 +MMTAppReg2.MEMORYMAP.DefaultDataRegion=false +MMTAppReg2.MEMORYMAP.IPParameters=StartAddress,Size,CoreName,DefaultDataRegion,ReservedRegion,Name +MMTAppReg2.MEMORYMAP.Name=RAM Reserved Alias Region +MMTAppReg2.MEMORYMAP.ReservedRegion=true +MMTAppReg2.MEMORYMAP.Size=2555904 +MMTAppReg2.MEMORYMAP.StartAddress=0x0A000000 +MMTAppReg3.MEMORYMAP.AP=RO_priv_only +MMTAppReg3.MEMORYMAP.AppRegionName=FLASH +MMTAppReg3.MEMORYMAP.Cacheability=WTRA +MMTAppReg3.MEMORYMAP.ContextName=CortexM33 +MMTAppReg3.MEMORYMAP.CoreName=ARM Cortex-M33 +MMTAppReg3.MEMORYMAP.DefaultCodeRegion=true +MMTAppReg3.MEMORYMAP.DefaultDataRegion=false +MMTAppReg3.MEMORYMAP.IPParameters=StartAddress,Size,CoreName,DefaultDataRegion,MemType,ContextName,Name,AP,Cacheability,DefaultCodeRegion +MMTAppReg3.MEMORYMAP.MemType=ROM +MMTAppReg3.MEMORYMAP.Name=FLASH +MMTAppReg3.MEMORYMAP.Size=4194304 +MMTAppReg3.MEMORYMAP.StartAddress=0x08000000 +MMTAppRegionsCount=3 +MMTConfigApplied=false +Mcu.CPN=STM32U5A5ZJT6Q +Mcu.ContextProject=TrustZoneDisabled +Mcu.Family=STM32U5 +Mcu.IP0=ADC1 +Mcu.IP1=CORTEX_M33_NS +Mcu.IP10=UCPD1 +Mcu.IP11=USART1 +Mcu.IP12=USBPD +Mcu.IP13=USBX +Mcu.IP14=USB_OTG_HS +Mcu.IP2=GPDMA1 +Mcu.IP3=ICACHE +Mcu.IP4=MEMORYMAP +Mcu.IP5=NVIC +Mcu.IP6=PWR +Mcu.IP7=RCC +Mcu.IP8=SYS +Mcu.IP9=THREADX +Mcu.IPNb=15 +Mcu.Name=STM32U5A5ZJTxQ +Mcu.Package=LQFP144 +Mcu.Pin0=PH0-OSC_IN (PH0) +Mcu.Pin1=PH1-OSC_OUT (PH1) +Mcu.Pin10=VP_GPDMA1_VS_GPDMACH0 +Mcu.Pin11=VP_GPDMA1_VS_GPDMACH3 +Mcu.Pin12=VP_GPDMA1_VS_GPDMACH5 +Mcu.Pin13=VP_ICACHE_VS_ICACHE +Mcu.Pin14=VP_PWR_VS_DBSignals +Mcu.Pin15=VP_PWR_VS_SECSignals +Mcu.Pin16=VP_PWR_VS_LPOM +Mcu.Pin17=VP_SYS_VS_tim6 +Mcu.Pin18=VP_THREADX_VS_RTOSJjThreadXJjCoreJjDefault +Mcu.Pin19=VP_USBPD_VS_USBPD1 +Mcu.Pin2=PC1 +Mcu.Pin20=VP_USBPD_VS_PD3TYPEC +Mcu.Pin21=VP_USBPD_VS_usbpd_tim2 +Mcu.Pin22=VP_USBPD_VS_usbpd_usb_cohabitation +Mcu.Pin23=VP_USBX_Core_System +Mcu.Pin24=VP_USBX_UX Device CoreStack_HS +Mcu.Pin25=VP_USBX_UX Device Controller_HS +Mcu.Pin26=VP_USBX_UX Device CDC ACM Class_HS +Mcu.Pin27=VP_MEMORYMAP_VS_MEMORYMAP +Mcu.Pin3=PB15 +Mcu.Pin4=PG2 +Mcu.Pin5=PA9 +Mcu.Pin6=PA10 +Mcu.Pin7=PA11 +Mcu.Pin8=PA12 +Mcu.Pin9=PA15 (JTDI) +Mcu.PinsNb=28 +Mcu.ThirdPartyNb=0 +Mcu.UserConstants= +Mcu.UserName=STM32U5A5ZJTxQ +MxCube.Version=6.9.2 +MxDb.Version=DB.6.0.92 +NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false +NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false +NVIC.ForceEnableDMAVector=true +NVIC.GPDMA1_Channel0_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true\:true +NVIC.GPDMA1_Channel3_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true\:true +NVIC.GPDMA1_Channel5_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true\:true +NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false +NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false +NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false +NVIC.OTG_HS_IRQn=true\:7\:0\:true\:false\:true\:false\:true\:true\:true +NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false\:false +NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 +NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false\:false +NVIC.SavedPendsvIrqHandlerGenerated=true +NVIC.SavedSvcallIrqHandlerGenerated=true +NVIC.SavedSystickIrqHandlerGenerated=true +NVIC.SysTick_IRQn=true\:0\:0\:true\:false\:false\:false\:false\:true\:false +NVIC.TIM6_IRQn=true\:15\:0\:false\:false\:true\:false\:false\:true\:true +NVIC.TimeBase=TIM6_IRQn +NVIC.TimeBaseIP=TIM6 +NVIC.UCPD1_IRQn=true\:5\:0\:true\:false\:true\:false\:true\:false\:true +NVIC.USART1_IRQn=true\:6\:0\:true\:false\:true\:false\:true\:true\:true +NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false +PA10.GPIOParameters=GPIO_Speed,GPIO_PuPd +PA10.GPIO_PuPd=GPIO_PULLUP +PA10.GPIO_Speed=GPIO_SPEED_FREQ_HIGH +PA10.Mode=Asynchronous +PA10.Signal=USART1_RX +PA11.GPIOParameters=GPIO_Speed +PA11.GPIO_Speed=GPIO_SPEED_FREQ_LOW +PA11.Mode=Internal_Phy_Device +PA11.Signal=USB_OTG_HS_DM +PA12.GPIOParameters=GPIO_Speed +PA12.GPIO_Speed=GPIO_SPEED_FREQ_LOW +PA12.Mode=Internal_Phy_Device +PA12.Signal=USB_OTG_HS_DP +PA15\ (JTDI).Mode=Sink_AllSignals +PA15\ (JTDI).Signal=UCPD1_CC1 +PA9.GPIOParameters=GPIO_Speed,GPIO_PuPd +PA9.GPIO_PuPd=GPIO_PULLUP +PA9.GPIO_Speed=GPIO_SPEED_FREQ_HIGH +PA9.Mode=Asynchronous +PA9.Signal=USART1_TX +PB15.Mode=Sink_AllSignals +PB15.Signal=UCPD1_CC2 +PC1.Mode=IN2-Single-Ended +PC1.Signal=ADC1_IN2 +PG2.GPIOParameters=GPIO_Label +PG2.GPIO_Label=LED_RED +PG2.Locked=true +PG2.Signal=GPIO_Output +PH0-OSC_IN\ (PH0).Mode=HSE-External-Oscillator +PH0-OSC_IN\ (PH0).Signal=RCC_OSC_IN +PH1-OSC_OUT\ (PH1).Mode=HSE-External-Oscillator +PH1-OSC_OUT\ (PH1).Signal=RCC_OSC_OUT +PWR.IPParameters=PowerMode +PWR.PowerMode=PWR_SMPS_SUPPLY +PinOutPanel.RotationAngle=0 +ProjectManager.AskForMigrate=true +ProjectManager.BackupPrevious=false +ProjectManager.CompilerOptimize=6 +ProjectManager.ComputerToolchain=false +ProjectManager.CoupleFile=false +ProjectManager.CustomerFirmwarePackage= +ProjectManager.DefaultFWLocation=true +ProjectManager.DeletePrevious=true +ProjectManager.DeviceId=STM32U5A5ZJTxQ +ProjectManager.Example=Ux_Device_CDC_ACM +ProjectManager.ExampleSource=MxCubeFw +ProjectManager.FirmwarePackage=STM32Cube FW_U5 V1.3.0 +ProjectManager.FreePins=false +ProjectManager.HalAssertFull=false +ProjectManager.HeapSize=0x200 +ProjectManager.KeepUserCode=true +ProjectManager.LPBAM.generateCode= +ProjectManager.LastFirmware=true +ProjectManager.LibraryCopy=1 +ProjectManager.MainLocation=Core/Src +ProjectManager.NoMain=false +ProjectManager.PreviousToolchain= +ProjectManager.ProjectBuild=false +ProjectManager.ProjectFileName=stm32u5a5nucleo.ioc +ProjectManager.ProjectName=stm32u5a5nucleo +ProjectManager.ProjectStructure= +ProjectManager.RegisterCallBack= +ProjectManager.StackSize=0x400 +ProjectManager.TargetToolchain=STM32CubeIDE +ProjectManager.ToolChainLocation= +ProjectManager.UAScriptAfterPath= +ProjectManager.UAScriptBeforePath= +ProjectManager.UnderRoot=false +ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_GPDMA1_Init-GPDMA1-false-HAL-true,4-MX_ICACHE_Init-ICACHE-false-HAL-true,5-MX_USART1_UART_Init-USART1-false-HAL-false,6-MX_UCPD1_Init-UCPD1-false-LL-true,7-MX_USB_OTG_HS_PCD_Init-USB_OTG_HS-true-HAL-false,8-MX_USBPD_Init-USBPD-false-HAL-false,9-MX_USBX_Init-USBX-false-HAL-false,10-MX_ADC1_Init-ADC1-false-HAL-true,11-MX_MEMORYMAP_Init-MEMORYMAP-false-HAL-true,0-MX_CORTEX_M33_NS_Init-CORTEX_M33_NS-false-HAL-true,0-MX_PWR_Init-PWR-false-HAL-true +RCC.ADCFreq_Value=16000000 +RCC.ADF1Freq_Value=160000000 +RCC.AHBFreq_Value=160000000 +RCC.APB1Freq_Value=160000000 +RCC.APB1TimFreq_Value=160000000 +RCC.APB2Freq_Value=160000000 +RCC.APB2TimFreq_Value=160000000 +RCC.APB3Freq_Value=160000000 +RCC.CK48Freq_Value=48000000 +RCC.CRSFreq_Value=48000000 +RCC.CortexFreq_Value=160000000 +RCC.DACCLockSelectionVirtual=RCC_DAC1CLKSOURCE_LSI +RCC.DACFreq_Value=32000 +RCC.EPOD_VALUE=16000000 +RCC.FCLKCortexFreq_Value=160000000 +RCC.FDCANFreq_Value=160000000 +RCC.FamilyName=M +RCC.HCLKFreq_Value=160000000 +RCC.HSE_VALUE=16000000 +RCC.HSI48_VALUE=48000000 +RCC.HSI_VALUE=16000000 +RCC.I2C1Freq_Value=160000000 +RCC.I2C2Freq_Value=160000000 +RCC.I2C3Freq_Value=160000000 +RCC.I2C4Freq_Value=160000000 +RCC.I2C5Freq_Value=160000000 +RCC.I2C6Freq_Value=160000000 +RCC.IPParameters=ADCFreq_Value,ADF1Freq_Value,AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,APB3Freq_Value,CK48Freq_Value,CRSFreq_Value,CortexFreq_Value,DACCLockSelectionVirtual,DACFreq_Value,EPOD_VALUE,FCLKCortexFreq_Value,FDCANFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI48_VALUE,HSI_VALUE,I2C1Freq_Value,I2C2Freq_Value,I2C3Freq_Value,I2C4Freq_Value,I2C5Freq_Value,I2C6Freq_Value,LPTIM2Freq_Value,LPUART1Freq_Value,LSCOPinFreq_Value,LSE_VALUE,LSIDIV_VALUE,LSI_VALUE,MCO1PinFreq_Value,MDF1Freq_Value,MSIClockRange,MSI_VALUE,OCTOSPIMFreq_Value,PLL1P,PLL2FRACN,PLL2PoutputFreq_Value,PLL2QoutputFreq_Value,PLL2RoutputFreq_Value,PLL3FRACN,PLL3PoutputFreq_Value,PLL3QoutputFreq_Value,PLL3RoutputFreq_Value,PLLFRACN,PLLN,PLLPoutputFreq_Value,PLLQoutputFreq_Value,PLLRCLKFreq_Value,PLLSourceVirtual,RNGFreq_Value,SAESFreq_Value,SAI1Freq_Value,SAI2Freq_Value,SDMMCFreq_Value,SPI1Freq_Value,SPI2Freq_Value,SPI3Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,UART4Freq_Value,UART5Freq_Value,USART1Freq_Value,USART2Freq_Value,USART3Freq_Value,USART6Freq_Value,USBPHYCLockSelection,USBPHYFreq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VCOPLL2OutputFreq_Value,VCOPLL3OutputFreq_Value +RCC.LPTIM2Freq_Value=160000000 +RCC.LPUART1Freq_Value=160000000 +RCC.LSCOPinFreq_Value=32000 +RCC.LSE_VALUE=32768 +RCC.LSIDIV_VALUE=32000 +RCC.LSI_VALUE=32000 +RCC.MCO1PinFreq_Value=160000000 +RCC.MDF1Freq_Value=160000000 +RCC.MSIClockRange=RCC_MSIRANGE_0 +RCC.MSI_VALUE=48000000 +RCC.OCTOSPIMFreq_Value=160000000 +RCC.PLL1P=8 +RCC.PLL2FRACN=0 +RCC.PLL2PoutputFreq_Value=3096000000 +RCC.PLL2QoutputFreq_Value=3096000000 +RCC.PLL2RoutputFreq_Value=3096000000 +RCC.PLL3FRACN=0 +RCC.PLL3PoutputFreq_Value=3096000000 +RCC.PLL3QoutputFreq_Value=3096000000 +RCC.PLL3RoutputFreq_Value=3096000000 +RCC.PLLFRACN=0 +RCC.PLLN=20 +RCC.PLLPoutputFreq_Value=40000000 +RCC.PLLQoutputFreq_Value=160000000 +RCC.PLLRCLKFreq_Value=160000000 +RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE +RCC.RNGFreq_Value=48000000 +RCC.SAESFreq_Value=48000000 +RCC.SAI1Freq_Value=3096000000 +RCC.SAI2Freq_Value=3096000000 +RCC.SDMMCFreq_Value=40000000 +RCC.SPI1Freq_Value=160000000 +RCC.SPI2Freq_Value=160000000 +RCC.SPI3Freq_Value=160000000 +RCC.SYSCLKFreq_VALUE=160000000 +RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK +RCC.UART4Freq_Value=160000000 +RCC.UART5Freq_Value=160000000 +RCC.USART1Freq_Value=160000000 +RCC.USART2Freq_Value=160000000 +RCC.USART3Freq_Value=160000000 +RCC.USART6Freq_Value=160000000 +RCC.USBPHYCLockSelection=RCC_USBPHYCLKSOURCE_HSE +RCC.USBPHYFreq_Value=16000000 +RCC.VCOInput2Freq_Value=48000000 +RCC.VCOInput3Freq_Value=48000000 +RCC.VCOInputFreq_Value=16000000 +RCC.VCOOutputFreq_Value=320000000 +RCC.VCOPLL2OutputFreq_Value=6192000000 +RCC.VCOPLL3OutputFreq_Value=6192000000 +USART1.IPParameters=VirtualMode-Asynchronous +USART1.VirtualMode-Asynchronous=VM_ASYNC +USBX.BSP.number=1 +USBX.Core_System=1 +USBX.IPParameters=Core_System,UX_Device_CoreStack,UX_Device_Controller,UX_DEVICE_CDC_ACM,USBD_CDCACM_EPIN_ADDR,USBD_CDCACM_EPOUT_HS_MPS,USBD_CDCACM_EPIN_HS_MPS,UX_DEVICE_APP_MEM_POOL_SIZE,USBD_PRODUCT_STRING,UX_SLAVE_REQUEST_DATA_MAX_LENGTH,USBX_DEVICE_SYS_SIZE,USBD_PID,USBD_SERIAL_NUMBER,UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH,USBD_CDCACM_EPINCMD_ADDR,MAX_POWER_IN_MILLI_AMPER +USBX.MAX_POWER_IN_MILLI_AMPER=0 +USBX.USBD_CDCACM_EPINCMD_ADDR=2 +USBX.USBD_CDCACM_EPIN_ADDR=1 +USBX.USBD_CDCACM_EPIN_HS_MPS=512 +USBX.USBD_CDCACM_EPOUT_HS_MPS=512 +USBX.USBD_PID=22336 +USBX.USBD_PRODUCT_STRING=STM32 Virtual ComPort +USBX.USBD_SERIAL_NUMBER=CDC_ACM001 +USBX.USBX_DEVICE_SYS_SIZE=4*1024 +USBX.UX_DEVICE_APP_MEM_POOL_SIZE=8192 +USBX.UX_DEVICE_CDC_ACM=1 +USBX.UX_Device_Controller=1 +USBX.UX_Device_CoreStack=1 +USBX.UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH=256 +USBX.UX_SLAVE_REQUEST_DATA_MAX_LENGTH=512 +USBX0.BSP.STBoard=false +USBX0.BSP.api=Unknown +USBX0.BSP.component= +USBX0.BSP.condition= +USBX0.BSP.instance=USB_OTG_HS +USBX0.BSP.ip=USB_OTG_HS +USBX0.BSP.mode=Device_Only +USBX0.BSP.name=USBDevice +USBX0.BSP.semaphore= +USBX0.BSP.solution=USB_OTG_HS +USB_OTG_HS.IPParameters=VirtualMode +USB_OTG_HS.VirtualMode=Device_HS +VP_GPDMA1_VS_GPDMACH0.Mode=SIMPLEREQUEST_GPDMACH0 +VP_GPDMA1_VS_GPDMACH0.Signal=GPDMA1_VS_GPDMACH0 +VP_GPDMA1_VS_GPDMACH3.Mode=SIMPLEREQUEST_GPDMACH3 +VP_GPDMA1_VS_GPDMACH3.Signal=GPDMA1_VS_GPDMACH3 +VP_GPDMA1_VS_GPDMACH5.Mode=SIMPLEREQUEST_GPDMACH5 +VP_GPDMA1_VS_GPDMACH5.Signal=GPDMA1_VS_GPDMACH5 +VP_ICACHE_VS_ICACHE.Mode=DirectMappedCache +VP_ICACHE_VS_ICACHE.Signal=ICACHE_VS_ICACHE +VP_MEMORYMAP_VS_MEMORYMAP.Mode=CurAppReg +VP_MEMORYMAP_VS_MEMORYMAP.Signal=MEMORYMAP_VS_MEMORYMAP +VP_PWR_VS_DBSignals.Mode=DisableDeadBatterySignals +VP_PWR_VS_DBSignals.Signal=PWR_VS_DBSignals +VP_PWR_VS_LPOM.Mode=PowerOptimisation +VP_PWR_VS_LPOM.Signal=PWR_VS_LPOM +VP_PWR_VS_SECSignals.Mode=Security/Privilege +VP_PWR_VS_SECSignals.Signal=PWR_VS_SECSignals +VP_SYS_VS_tim6.Mode=TIM6 +VP_SYS_VS_tim6.Signal=SYS_VS_tim6 +VP_THREADX_VS_RTOSJjThreadXJjCoreJjDefault.Mode=Core_Default +VP_THREADX_VS_RTOSJjThreadXJjCoreJjDefault.Signal=THREADX_VS_RTOSJjThreadXJjCoreJjDefault +VP_USBPD_VS_PD3TYPEC.Mode=PD3_TypeC +VP_USBPD_VS_PD3TYPEC.Signal=USBPD_VS_PD3TYPEC +VP_USBPD_VS_USBPD1.Mode=USBPD_P0 +VP_USBPD_VS_USBPD1.Signal=USBPD_VS_USBPD1 +VP_USBPD_VS_usbpd_tim2.Mode=TIM2 +VP_USBPD_VS_usbpd_tim2.Signal=USBPD_VS_usbpd_tim2 +VP_USBPD_VS_usbpd_usb_cohabitation.Mode=Enable USB Support +VP_USBPD_VS_usbpd_usb_cohabitation.Signal=USBPD_VS_usbpd_usb_cohabitation +VP_USBX_Core_System.Mode=Core_System +VP_USBX_Core_System.Signal=USBX_Core_System +VP_USBX_UX\ Device\ CDC\ ACM\ Class_HS.Mode=UX_Device_class_CDC_ACM_HS +VP_USBX_UX\ Device\ CDC\ ACM\ Class_HS.Signal=USBX_UX Device CDC ACM Class_HS +VP_USBX_UX\ Device\ Controller_HS.Mode=UX_Device_Controller_HS +VP_USBX_UX\ Device\ Controller_HS.Signal=USBX_UX Device Controller_HS +VP_USBX_UX\ Device\ CoreStack_HS.Mode=UX_Device_CoreStack_HS +VP_USBX_UX\ Device\ CoreStack_HS.Signal=USBX_UX Device CoreStack_HS +board=NUCLEO-U5A5ZJ-Q +boardIOC=true diff --git a/hw/bsp/stm32u5/family.c b/hw/bsp/stm32u5/family.c index a30d886aa..ec64f7622 100644 --- a/hw/bsp/stm32u5/family.c +++ b/hw/bsp/stm32u5/family.c @@ -25,15 +25,33 @@ * This file is part of the TinyUSB stack. */ +// Suppress warning caused by mcu driver +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wundef" +#endif + #include "stm32u5xx_hal.h" + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + #include "bsp/board_api.h" + +TU_ATTR_UNUSED static void Error_Handler(void) { +} + #include "board.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ -void OTG_FS_IRQHandler(void) -{ +void OTG_FS_IRQHandler(void) { + tud_int_handler(0); +} + +void OTG_HS_IRQHandler(void) { tud_int_handler(0); } @@ -43,10 +61,10 @@ void OTG_FS_IRQHandler(void) UART_HandleTypeDef UartHandle; -void board_init(void) -{ - - board_clock_init(); +void board_init(void) { + // Init clock, implemented in board.h + SystemClock_Config(); + SystemPower_Config(); // Enable All GPIOs clocks __HAL_RCC_GPIOA_CLK_ENABLE(); @@ -60,12 +78,12 @@ void board_init(void) UART_CLK_EN(); + /* Enable Instruction cache */ + HAL_ICACHE_Enable(); + #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(OTG_FS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif GPIO_InitTypeDef GPIO_InitStruct; @@ -89,7 +107,7 @@ void board_init(void) GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM; GPIO_InitStruct.Alternate = UART_GPIO_AF; HAL_GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct); @@ -104,10 +122,9 @@ void board_init(void) UartHandle.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; UartHandle.Init.ClockPrescaler = UART_PRESCALER_DIV1; UartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; - HAL_UART_Init(&UartHandle); - /* Configure USB FS GPIOs */ + /* Configure USB GPIOs */ /* Configure DM DP Pins */ GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; @@ -123,8 +140,14 @@ void board_init(void) GPIO_InitStruct.Alternate = GPIO_AF10_USB; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); -#if OTG_FS_VBUS_SENSE - // Configure VBUS Pin +#ifdef USB_OTG_FS + #if CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(OTG_FS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); + #endif + + #if defined(OTG_FS_VBUS_SENSE) && OTG_FS_VBUS_SENSE + // Configure VBUS Pin OTG_FS_VBUS_SENSE GPIO_InitStruct.Pin = GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; @@ -132,70 +155,104 @@ void board_init(void) // Enable VBUS sense (B device) via pin PA9 USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_VBDEN; -#else + #else // Disable VBUS sense (B device) via pin PA9 USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_VBDEN; // B-peripheral session valid override enable USB_OTG_FS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN; USB_OTG_FS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL; -#endif // vbus sense + #endif // vbus sense /* Enable USB power on Pwrctrl CR2 register */ HAL_PWREx_EnableVddUSB(); - /* USB_OTG_FS clock enable */ + /* USB clock enable */ __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); + +#else + // STM59x/Ax/Fx/Gx only have 1 USB HS port + + #if CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(OTG_HS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); + #endif + + /* USB clock enable */ + __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); + __HAL_RCC_USBPHYC_CLK_ENABLE(); + + /* Enable USB power on Pwrctrl CR2 register */ + HAL_PWREx_EnableVddUSB(); + HAL_PWREx_EnableUSBHSTranceiverSupply(); + + /*Configuring the SYSCFG registers OTG_HS PHY*/ + HAL_SYSCFG_EnableOTGPHY(SYSCFG_OTG_HS_PHY_ENABLE); + + // Disable VBUS sense (B device) + USB_OTG_HS->GCCFG &= ~USB_OTG_GCCFG_VBDEN; + + // B-peripheral session valid override enable + USB_OTG_HS->GCCFG |= USB_OTG_GCCFG_VBVALEXTOEN; + USB_OTG_HS->GCCFG |= USB_OTG_GCCFG_VBVALOVAL; +#endif // USB_OTG_FS } //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ -void board_led_write(bool state) -{ +void board_led_write(bool state) { HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); } -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); } -int board_uart_read(uint8_t *buf, int len) -{ - (void)buf; - (void)len; +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + (void) max_len; + volatile uint32_t *stm32_uuid = (volatile uint32_t *) UID_BASE; + uint32_t *id32 = (uint32_t *) (uintptr_t) id; + uint8_t const len = 12; + + id32[0] = stm32_uuid[0]; + id32[1] = stm32_uuid[1]; + id32[2] = stm32_uuid[2]; + + return len; +} + +int board_uart_read(uint8_t *buf, int len) { + (void) buf; + (void) len; return 0; } -int board_uart_write(void const *buf, int len) -{ - HAL_UART_Transmit(&UartHandle, (uint8_t *)(uintptr_t)buf, len, 0xffff); +int board_uart_write(void const *buf, int len) { + HAL_UART_Transmit(&UartHandle, (uint8_t *) (uintptr_t) buf, len, 0xffff); return len; } #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; -void SysTick_Handler(void) -{ + +void SysTick_Handler(void) { HAL_IncTick(); system_ticks++; } -uint32_t board_millis(void) -{ +uint32_t board_millis(void) { return system_ticks; } + #endif -void HardFault_Handler(void) -{ - asm("bkpt"); +void HardFault_Handler(void) { + asm("bkpt 1"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. -void _init(void) -{ +void _init(void) { } diff --git a/hw/bsp/stm32u5/family.cmake b/hw/bsp/stm32u5/family.cmake new file mode 100644 index 000000000..7402540b7 --- /dev/null +++ b/hw/bsp/stm32u5/family.cmake @@ -0,0 +1,117 @@ +include_guard() + +set(ST_FAMILY u5) +set(ST_PREFIX stm32${ST_FAMILY}xx) + +set(ST_HAL_DRIVER ${TOP}/hw/mcu/st/stm32${ST_FAMILY}xx_hal_driver) +set(ST_CMSIS ${TOP}/hw/mcu/st/cmsis_device_${ST_FAMILY}) +set(CMSIS_5 ${TOP}/lib/CMSIS_5) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR cortex-m33 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS STM32U5 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() + + # Startup & Linker script + set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) + + string(REPLACE "stm32u" "STM32U" MCU_VARIANT_UPPER ${MCU_VARIANT}) + if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/linker/${MCU_VARIANT_UPPER}_FLASH.ld) + endif () + set(LD_FILE_Clang ${LD_FILE_GNU}) + set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + + add_library(${BOARD_TARGET} STATIC + ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_icache.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_5}/CMSIS/Core/Include + ${ST_CMSIS}/Include + ${ST_HAL_DRIVER}/Inc + ) + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + 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_STM32U5 ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c + #${TOP}/src/portable/st/typec/typec_stm32.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_flash_stlink(${TARGET}) + family_flash_jlink(${TARGET}) +endfunction() diff --git a/hw/bsp/stm32u5/family.mk b/hw/bsp/stm32u5/family.mk index 9174fe96a..be5809340 100644 --- a/hw/bsp/stm32u5/family.mk +++ b/hw/bsp/stm32u5/family.mk @@ -8,23 +8,35 @@ include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= cortex-m33 CFLAGS += \ - -flto \ - -nostdlib -nostartfiles \ -DCFG_TUSB_MCU=OPT_MCU_STM32U5 # suppress warning caused by vendor mcu driver -CFLAGS += -Wno-error=maybe-uninitialized -Wno-error=cast-align -Wno-error=undef -Wno-error=unused-parameter +CFLAGS_GCC += \ + -flto \ + -Wno-error=cast-align \ + -Wno-error=undef \ + -Wno-error=unused-parameter \ + -Wno-error=type-limits \ + +ifeq ($(TOOLCHAIN),gcc) +CFLAGS_GCC += -Wno-error=maybe-uninitialized +endif + +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs SRC_C += \ src/portable/synopsys/dwc2/dcd_dwc2.c \ $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ - $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ - $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_icache.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr_ex.c \ - $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c INC += \ diff --git a/hw/bsp/stm32u5/boards/stm32u575eval/STM32U575AIIXQ_FLASH.ld b/hw/bsp/stm32u5/linker/STM32U535xx_FLASH.ld similarity index 94% rename from hw/bsp/stm32u5/boards/stm32u575eval/STM32U575AIIXQ_FLASH.ld rename to hw/bsp/stm32u5/linker/STM32U535xx_FLASH.ld index 03c022bc2..6ac1479a3 100644 --- a/hw/bsp/stm32u5/boards/stm32u575eval/STM32U575AIIXQ_FLASH.ld +++ b/hw/bsp/stm32u5/linker/STM32U535xx_FLASH.ld @@ -5,9 +5,9 @@ ** ** Author : STM32CubeIDE ** -** Abstract : Linker script for STM32U575xI Device from STM32U5 series -** 2048Kbytes FLASH -** 784Kbytes RAM +** Abstract : Linker script for STM32U535xE Device from STM32U5 series +** 512Kbytes FLASH +** 272Kbytes RAM ** ** Set heap size, stack size and stack location according ** to application requirements. @@ -35,20 +35,20 @@ /* Entry Point */ ENTRY(Reset_Handler) +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K + SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K +} + /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ _Min_Heap_Size = 0x200 ; /* required amount of heap */ _Min_Stack_Size = 0x400 ; /* required amount of stack */ -/* Memories definition */ -MEMORY -{ - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 768K - SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K - FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K -} - /* Sections */ SECTIONS { diff --git a/hw/bsp/stm32u5/linker/STM32U545xx_FLASH.ld b/hw/bsp/stm32u5/linker/STM32U545xx_FLASH.ld new file mode 100644 index 000000000..ce370c643 --- /dev/null +++ b/hw/bsp/stm32u5/linker/STM32U545xx_FLASH.ld @@ -0,0 +1,167 @@ +/* +****************************************************************************** +** +** File : LinkerScript.ld +** +** Author : STM32CubeIDE +** +** Abstract : Linker script for STM32U545xE Device from STM32U5 series +** 512Kbytes FLASH +** 272Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +** Copyright (c) 2022 STMicroelectronics. +** All rights reserved. +** +** This software is licensed under terms that can be found in the LICENSE file +** in the root directory of this software component. +** If no LICENSE file comes with this software, it is provided AS-IS. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K + SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200 ; /* required amount of heap */ +_Min_Stack_Size = 0x400 ; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + KEEP(*(.isr_vector)) /* Startup code */ + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + } >FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } >FLASH + + .ARM : + { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32u5/linker/STM32U575xx_FLASH.ld b/hw/bsp/stm32u5/linker/STM32U575xx_FLASH.ld new file mode 100644 index 000000000..b24c533de --- /dev/null +++ b/hw/bsp/stm32u5/linker/STM32U575xx_FLASH.ld @@ -0,0 +1,185 @@ +/* +****************************************************************************** +** +** File : LinkerScript.ld +** +** Author : Auto-generated by STM32CubeIDE +** +** Abstract : Linker script for STM32U575xx Device from STM32U5 series +** 2048Kbytes ROM +** 784Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +**

© Copyright (c) 2021 STMicroelectronics. +** All rights reserved.

+** +** This software component is licensed by ST under BSD 3-Clause license, +** the "License"; You may not use this file except in compliance with the +** License. You may obtain a copy of the License at: +** opensource.org/licenses/BSD-3-Clause +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 768K + ROM (rx) : ORIGIN = 0x08000000, LENGTH = 2048K + SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "ROM" Rom type memory */ + .isr_vector : + { + . = ALIGN(8); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(8); + } >ROM + + /* The program code and other data into "ROM" Rom type memory */ + .text : + { + . = ALIGN(8); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(8); + _etext = .; /* define a global symbols at end of code */ + } >ROM + + /* Constant data into "ROM" Rom type memory */ + .rodata : + { + . = ALIGN(8); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(8); + } >ROM + + .ARM.extab : { + . = ALIGN(8); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(8); + } >ROM + + .ARM : { + . = ALIGN(8); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(8); + } >ROM + + .preinit_array : + { + . = ALIGN(8); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(8); + } >ROM + + .init_array : + { + . = ALIGN(8); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(8); + } >ROM + + .fini_array : + { + . = ALIGN(8); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(8); + } >ROM + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(8); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(8); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> ROM + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(8); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(8); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32u5/linker/STM32U585xx_FLASH.ld b/hw/bsp/stm32u5/linker/STM32U585xx_FLASH.ld new file mode 100644 index 000000000..15b8054bc --- /dev/null +++ b/hw/bsp/stm32u5/linker/STM32U585xx_FLASH.ld @@ -0,0 +1,185 @@ +/* +****************************************************************************** +** +** File : LinkerScript.ld +** +** Author : Auto-generated by STM32CubeIDE +** +** Abstract : Linker script for STM32U585xx Device from STM32U5 series +** 2048Kbytes ROM +** 784Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +**

© Copyright (c) 2021 STMicroelectronics. +** All rights reserved.

+** +** This software component is licensed by ST under BSD 3-Clause license, +** the "License"; You may not use this file except in compliance with the +** License. You may obtain a copy of the License at: +** opensource.org/licenses/BSD-3-Clause +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 768K + ROM (rx) : ORIGIN = 0x08000000, LENGTH = 2048K + SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "ROM" Rom type memory */ + .isr_vector : + { + . = ALIGN(8); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(8); + } >ROM + + /* The program code and other data into "ROM" Rom type memory */ + .text : + { + . = ALIGN(8); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(8); + _etext = .; /* define a global symbols at end of code */ + } >ROM + + /* Constant data into "ROM" Rom type memory */ + .rodata : + { + . = ALIGN(8); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(8); + } >ROM + + .ARM.extab : { + . = ALIGN(8); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(8); + } >ROM + + .ARM : { + . = ALIGN(8); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(8); + } >ROM + + .preinit_array : + { + . = ALIGN(8); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(8); + } >ROM + + .init_array : + { + . = ALIGN(8); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(8); + } >ROM + + .fini_array : + { + . = ALIGN(8); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(8); + } >ROM + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(8); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(8); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> ROM + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(8); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(8); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32u5/linker/STM32U595xx_FLASH.ld b/hw/bsp/stm32u5/linker/STM32U595xx_FLASH.ld new file mode 100644 index 000000000..100ee14a5 --- /dev/null +++ b/hw/bsp/stm32u5/linker/STM32U595xx_FLASH.ld @@ -0,0 +1,168 @@ +/* +****************************************************************************** +** +** File : LinkerScript.ld +** +** Author : STM32CubeIDE +** +** Abstract : Linker script for STM32U595xJ Device from STM32U5 series +** 4096Kbytes FLASH +** 2528Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +**

© Copyright (c) 2021 STMicroelectronics. +** All rights reserved.

+** +** This software component is licensed by ST under BSD 3-Clause license, +** the "License"; You may not use this file except in compliance with the +** License. You may obtain a copy of the License at: +** opensource.org/licenses/BSD-3-Clause +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2496K + SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200 ; /* required amount of heap */ +_Min_Stack_Size = 0x400 ; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + KEEP(*(.isr_vector)) /* Startup code */ + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + } >FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } >FLASH + + .ARM : + { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32u5/linker/STM32U599xx_FLASH.ld b/hw/bsp/stm32u5/linker/STM32U599xx_FLASH.ld new file mode 100644 index 000000000..55997bf40 --- /dev/null +++ b/hw/bsp/stm32u5/linker/STM32U599xx_FLASH.ld @@ -0,0 +1,168 @@ +/* +****************************************************************************** +** +** File : LinkerScript.ld +** +** Author : STM32CubeIDE +** +** Abstract : Linker script for STM32U599xJ Device from STM32U5 series +** 4096Kbytes FLASH +** 2528Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +**

© Copyright (c) 2021 STMicroelectronics. +** All rights reserved.

+** +** This software component is licensed by ST under BSD 3-Clause license, +** the "License"; You may not use this file except in compliance with the +** License. You may obtain a copy of the License at: +** opensource.org/licenses/BSD-3-Clause +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2496K + SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200 ; /* required amount of heap */ +_Min_Stack_Size = 0x400 ; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + KEEP(*(.isr_vector)) /* Startup code */ + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + } >FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } >FLASH + + .ARM : + { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32u5/linker/STM32U5A9xx_FLASH.ld b/hw/bsp/stm32u5/linker/STM32U5A9xx_FLASH.ld new file mode 100644 index 000000000..a5f7d3405 --- /dev/null +++ b/hw/bsp/stm32u5/linker/STM32U5A9xx_FLASH.ld @@ -0,0 +1,168 @@ +/* +****************************************************************************** +** +** File : LinkerScript.ld +** +** Author : STM32CubeIDE +** +** Abstract : Linker script for STM32U5A9xJ Device from STM32U5 series +** 4096Kbytes FLASH +** 2528Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +**

© Copyright (c) 2021 STMicroelectronics. +** All rights reserved.

+** +** This software component is licensed by ST under BSD 3-Clause license, +** the "License"; You may not use this file except in compliance with the +** License. You may obtain a copy of the License at: +** opensource.org/licenses/BSD-3-Clause +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2496K + SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200 ; /* required amount of heap */ +_Min_Stack_Size = 0x400 ; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + KEEP(*(.isr_vector)) /* Startup code */ + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + } >FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } >FLASH + + .ARM : + { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32u5/linker/STM32U5F7xx_FLASH.ld b/hw/bsp/stm32u5/linker/STM32U5F7xx_FLASH.ld new file mode 100644 index 000000000..bb9953440 --- /dev/null +++ b/hw/bsp/stm32u5/linker/STM32U5F7xx_FLASH.ld @@ -0,0 +1,168 @@ +/* +****************************************************************************** +** +** File : LinkerScript.ld +** +** Author : STM32CubeIDE +** +** Abstract : Linker script for STM32U5F7xJ Device from STM32U5 series +** 4096Kbytes FLASH +** 2528Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +**

© Copyright (c) 2023 STMicroelectronics. +** All rights reserved.

+** +** This software component is licensed by ST under BSD 3-Clause license, +** the "License"; You may not use this file except in compliance with the +** License. You may obtain a copy of the License at: +** opensource.org/licenses/BSD-3-Clause +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2496K + SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200 ; /* required amount of heap */ +_Min_Stack_Size = 0x400 ; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + KEEP(*(.isr_vector)) /* Startup code */ + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + } >FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } >FLASH + + .ARM : + { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32u5/linker/STM32U5F9xx_FLASH.ld b/hw/bsp/stm32u5/linker/STM32U5F9xx_FLASH.ld new file mode 100644 index 000000000..d8f1f4c5f --- /dev/null +++ b/hw/bsp/stm32u5/linker/STM32U5F9xx_FLASH.ld @@ -0,0 +1,168 @@ +/* +****************************************************************************** +** +** File : LinkerScript.ld +** +** Author : STM32CubeIDE +** +** Abstract : Linker script for STM32U5F9xJ Device from STM32U5 series +** 4096Kbytes FLASH +** 2528Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +**

© Copyright (c) 2023 STMicroelectronics. +** All rights reserved.

+** +** This software component is licensed by ST under BSD 3-Clause license, +** the "License"; You may not use this file except in compliance with the +** License. You may obtain a copy of the License at: +** opensource.org/licenses/BSD-3-Clause +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2496K + SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200 ; /* required amount of heap */ +_Min_Stack_Size = 0x400 ; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + KEEP(*(.isr_vector)) /* Startup code */ + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + } >FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } >FLASH + + .ARM : + { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32u5/linker/STM32U5G7xx_FLASH.ld b/hw/bsp/stm32u5/linker/STM32U5G7xx_FLASH.ld new file mode 100644 index 000000000..d02d6ebf1 --- /dev/null +++ b/hw/bsp/stm32u5/linker/STM32U5G7xx_FLASH.ld @@ -0,0 +1,168 @@ +/* +****************************************************************************** +** +** File : LinkerScript.ld +** +** Author : STM32CubeIDE +** +** Abstract : Linker script for STM32U5G7xJ Device from STM32U5 series +** 4096Kbytes FLASH +** 2528Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +**

© Copyright (c) 2023 STMicroelectronics. +** All rights reserved.

+** +** This software component is licensed by ST under BSD 3-Clause license, +** the "License"; You may not use this file except in compliance with the +** License. You may obtain a copy of the License at: +** opensource.org/licenses/BSD-3-Clause +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2496K + SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200 ; /* required amount of heap */ +_Min_Stack_Size = 0x400 ; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + KEEP(*(.isr_vector)) /* Startup code */ + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + } >FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } >FLASH + + .ARM : + { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32u5/linker/STM32U5G9xx_FLASH.ld b/hw/bsp/stm32u5/linker/STM32U5G9xx_FLASH.ld new file mode 100644 index 000000000..1b072fdd4 --- /dev/null +++ b/hw/bsp/stm32u5/linker/STM32U5G9xx_FLASH.ld @@ -0,0 +1,168 @@ +/* +****************************************************************************** +** +** File : LinkerScript.ld +** +** Author : STM32CubeIDE +** +** Abstract : Linker script for STM32U5G9xJ Device from STM32U5 series +** 4096Kbytes FLASH +** 2528Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +**

© Copyright (c) 2023 STMicroelectronics. +** All rights reserved.

+** +** This software component is licensed by ST under BSD 3-Clause license, +** the "License"; You may not use this file except in compliance with the +** License. You may obtain a copy of the License at: +** opensource.org/licenses/BSD-3-Clause +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2496K + SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096K +} + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200 ; /* required amount of heap */ +_Min_Stack_Size = 0x400 ; /* required amount of stack */ + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + KEEP(*(.isr_vector)) /* Startup code */ + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + } >FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } >FLASH + + .ARM : + { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32wb/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/stm32wb/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..6ad115f60 --- /dev/null +++ b/hw/bsp/stm32wb/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,153 @@ +/* + * 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 "stm32wbxx.h" +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#if defined(__ARM_FP) && __ARM_FP >= 4 + #define configENABLE_FPU 1 +#else + #define configENABLE_FPU 0 +#endif +#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 4 +#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 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* 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 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* 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 + +/* 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 4 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<FLASH @@ -52,14 +53,14 @@ SECTIONS . = ALIGN(4); }>SRAM - /* User_heap_stack section, used to check that there is enough RAM left */ - ._user_heap_stack : - { - . = ALIGN(8); - PROVIDE ( end = . ); - PROVIDE ( _end = . ); - . = . + _Min_Heap_Size; - . = . + _Min_Stack_Size; - . = ALIGN(8); - } >SRAM + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >SRAM } diff --git a/hw/bsp/tm4c123/family.c b/hw/bsp/tm4c/family.c similarity index 99% rename from hw/bsp/tm4c123/family.c rename to hw/bsp/tm4c/family.c index ad5ae505f..738bc3fa0 100644 --- a/hw/bsp/tm4c123/family.c +++ b/hw/bsp/tm4c/family.c @@ -8,7 +8,7 @@ void USB0_Handler(void) { #if CFG_TUH_ENABLED - tuh_int_handler(0); + tuh_int_handler(0, true); #endif #if CFG_TUD_ENABLED diff --git a/hw/bsp/tm4c/family.cmake b/hw/bsp/tm4c/family.cmake new file mode 100644 index 000000000..86db985d6 --- /dev/null +++ b/hw/bsp/tm4c/family.cmake @@ -0,0 +1,95 @@ +include_guard() + +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +set(MCU_VARIANT tm4c${MCU_SUB_VARIANT}) +set(MCU_VARIANT_UPPER TM4C${MCU_SUB_VARIANT}) + +set(SDK_DIR ${TOP}/hw/mcu/ti/${MCU_VARIANT}xx) +set(CMSIS_DIR ${TOP}/lib/CMSIS_5) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR cortex-m4 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS TM4C123 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() + + set(LD_FILE_Clang ${LD_FILE_GNU}) + + set(STARTUP_FILE_GNU ${SDK_DIR}/Source/GCC/${MCU_VARIANT}_startup.c) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${SDK_DIR}/Source/system_${MCU_VARIANT_UPPER}.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_DIR}/Include/${MCU_VARIANT_UPPER} + ${CMSIS_DIR}/CMSIS/Core/Include + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + --specs=nosys.specs --specs=nano.specs + -uvectors + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + message(FATAL_ERROR "Clang is not supported for MSP432E4") + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_TM4C123 ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/mentor/musb/dcd_musb.c + ${TOP}/src/portable/mentor/musb/hcd_musb.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_add_bin_hex(${TARGET}) + family_flash_openocd(${TARGET}) +endfunction() diff --git a/hw/bsp/tm4c/family.mk b/hw/bsp/tm4c/family.mk new file mode 100644 index 000000000..76ae785b2 --- /dev/null +++ b/hw/bsp/tm4c/family.mk @@ -0,0 +1,28 @@ +include $(TOP)/$(BOARD_PATH)/board.mk +CPU_CORE ?= cortex-m4 + +MCU_VARIANT = tm4c${MCU_SUB_VARIANT} +MCU_VARIANT_UPPER = TM4C${MCU_SUB_VARIANT} + +SDK_DIR = hw/mcu/ti/${MCU_VARIANT}xx + +CFLAGS += \ + -flto \ + -DCFG_TUSB_MCU=OPT_MCU_TM4C123 \ + -uvectors \ + +# mcu driver cause following warnings +CFLAGS += -Wno-error=strict-prototypes -Wno-error=cast-qual + +LDFLAGS_GCC += --specs=nosys.specs --specs=nano.specs + +INC += \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + $(TOP)/$(SDK_DIR)/Include/${MCU_VARIANT_UPPER} \ + $(TOP)/$(BOARD_PATH) + +SRC_C += \ + src/portable/mentor/musb/dcd_musb.c \ + src/portable/mentor/musb/hcd_musb.c \ + $(SDK_DIR)/Source/system_${MCU_VARIANT_UPPER}.c \ + $(SDK_DIR)/Source/GCC/${MCU_VARIANT}_startup.c diff --git a/hw/bsp/tm4c123/family.mk b/hw/bsp/tm4c123/family.mk deleted file mode 100644 index 608c530bb..000000000 --- a/hw/bsp/tm4c123/family.mk +++ /dev/null @@ -1,29 +0,0 @@ -DEPS_SUBMODULES += hw/mcu/ti - -include $(TOP)/$(BOARD_PATH)/board.mk -CPU_CORE ?= cortex-m4 - -CFLAGS += \ - -flto \ - -DCFG_TUSB_MCU=OPT_MCU_TM4C123 \ - -uvectors \ - -DTM4C123GH6PM - -# mcu driver cause following warnings -CFLAGS += -Wno-error=strict-prototypes -Wno-error=cast-qual - -MCU_DIR=hw/mcu/ti/tm4c123xx/ - -# All source paths should be relative to the top level. -LD_FILE = $(BOARD_PATH)/tm4c123.ld - -INC += \ - $(TOP)/$(MCU_DIR)/CMSIS/5.7.0/CMSIS/Include \ - $(TOP)/$(MCU_DIR)/Include/TM4C123 \ - $(TOP)/$(BOARD_PATH) - -SRC_C += \ - src/portable/mentor/musb/dcd_musb.c \ - src/portable/mentor/musb/hcd_musb.c \ - $(MCU_DIR)/Source/system_TM4C123.c \ - $(MCU_DIR)/Source/GCC/tm4c123_startup.c diff --git a/hw/bsp/xmc4000/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/xmc4000/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..76eacea39 --- /dev/null +++ b/hw/bsp/xmc4000/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,149 @@ +/* + * 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 "xmc_device.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 4 +#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 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* 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 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* 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 + +/* 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 6 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<core, args->savename, &size); + if(elf->data) { + free(elf->data); + } free(elf); + c = cipher_init(vmk, NULL); cipher_calc_cmac(c, spkimage, size, (uint8_t *) spkimage + size); cipher_deinit(c); diff --git a/lib/SEGGER_RTT/RTT/SEGGER_RTT.c b/lib/SEGGER_RTT/RTT/SEGGER_RTT.c index 730a5cfb3..811d951fd 100644 --- a/lib/SEGGER_RTT/RTT/SEGGER_RTT.c +++ b/lib/SEGGER_RTT/RTT/SEGGER_RTT.c @@ -183,6 +183,11 @@ Additional information: * ********************************************************************** */ +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wcast-qual" +#pragma GCC diagnostic ignored "-Wcast-align" +#endif + #if (defined __ICCARM__) || (defined __ICCRX__) #define RTT_PRAGMA(P) _Pragma(#P) #endif diff --git a/lib/embedded-cli/embedded_cli.h b/lib/embedded-cli/embedded_cli.h index 33354cd84..91c96f3a1 100644 --- a/lib/embedded-cli/embedded_cli.h +++ b/lib/embedded-cli/embedded_cli.h @@ -743,7 +743,7 @@ EmbeddedCli *embeddedCliNew(EmbeddedCliConfig *config) { bool allocated = false; if (config->cliBuffer == NULL) { - config->cliBuffer = (CLI_UINT *) malloc(totalSize); // malloc guarantees alignment. +// config->cliBuffer = (CLI_UINT *) malloc(totalSize); // malloc guarantees alignment. if (config->cliBuffer == NULL) return NULL; allocated = true; @@ -887,7 +887,7 @@ void embeddedCliFree(EmbeddedCli *cli) { PREPARE_IMPL(cli); if (IS_FLAG_SET(impl->flags, CLI_FLAG_ALLOCATED)) { // allocation is done in single call to malloc, so need only single free - free(cli); +// free(cli); } } diff --git a/lib/networking/dhserver.h b/lib/networking/dhserver.h index b3642459a..b0d57ac4e 100644 --- a/lib/networking/dhserver.h +++ b/lib/networking/dhserver.h @@ -56,7 +56,13 @@ typedef struct dhcp_config dhcp_entry_t *entries; } dhcp_config_t; +#ifdef __cplusplus +extern "C" { +#endif err_t dhserv_init(const dhcp_config_t *config); void dhserv_free(void); +#ifdef __cplusplus +} +#endif #endif /* DHSERVER_H */ diff --git a/lib/networking/dnserver.c b/lib/networking/dnserver.c index 6d15fee02..25bbf4875 100644 --- a/lib/networking/dnserver.c +++ b/lib/networking/dnserver.c @@ -192,7 +192,7 @@ err_t dnserv_init(const ip_addr_t *bind, uint16_t port, dns_query_proc_t qp) return ERR_OK; } -void dnserv_free() +void dnserv_free(void) { if (pcb == NULL) return; udp_remove(pcb); diff --git a/lib/networking/dnserver.h b/lib/networking/dnserver.h index 50b29be89..a7a7f9acb 100644 --- a/lib/networking/dnserver.h +++ b/lib/networking/dnserver.h @@ -41,7 +41,13 @@ typedef bool (*dns_query_proc_t)(const char *name, ip4_addr_t *addr); +#ifdef __cplusplus +extern "C" { +#endif err_t dnserv_init(const ip_addr_t *bind, uint16_t port, dns_query_proc_t query_proc); void dnserv_free(void); +#ifdef __cplusplus +} +#endif #endif diff --git a/lib/rt-thread/SConscript b/lib/rt-thread/SConscript new file mode 100644 index 000000000..205e12958 --- /dev/null +++ b/lib/rt-thread/SConscript @@ -0,0 +1,42 @@ +import rtconfig +from building import * + +cwd = GetCurrentDir() +src = Split(""" +../../src/tusb.c +../../src/common/tusb_fifo.c +../../src/device/usbd.c +../../src/device/usbd_control.c +./tusb_rt_thread_port.c +""") +path = [cwd, cwd + "/../../src"] + +# BSP +if GetDepend(["SOC_FAMILY_STM32"]): + src += ["../../src/portable/synopsys/dwc2/dcd_dwc2.c", + "../../src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c"] + +if GetDepend(["SOC_NRF52840"]): + src += ["../../src/portable/nordic/nrf5x/dcd_nrf5x.c"] + +if GetDepend(["SOC_FAMILY_RENESAS"]): + src += ["../../src/portable/renesas/rusb2/dcd_rusb2.c", + "../../src/portable/renesas/rusb2/rusb2_common.c"] + +# Device class +if GetDepend(["PKG_TINYUSB_DEVICE_CDC"]): + src += ["../../src/class/cdc/cdc_device.c"] + +if GetDepend(["PKG_TINYUSB_DEVICE_MSC"]): + src += ["../../src/class/msc/msc_device.c", "port/msc_device_port.c"] + +LOCAL_CFLAGS = '' + +if rtconfig.PLATFORM == 'gcc' or rtconfig.PLATFORM == 'armclang': # GCC or Keil AC6 + LOCAL_CFLAGS += ' -std=c99' +elif rtconfig.PLATFORM == 'armcc': # Keil AC5 + LOCAL_CFLAGS += ' --c99 --gnu' + +group = DefineGroup('TinyUSB', src, depend = ['PKG_USING_TINYUSB'], CPPPATH = path, LOCAL_CFLAGS = LOCAL_CFLAGS) + +Return('group') diff --git a/lib/rt-thread/port/msc_device_port.c b/lib/rt-thread/port/msc_device_port.c new file mode 100644 index 000000000..c7e8c508e --- /dev/null +++ b/lib/rt-thread/port/msc_device_port.c @@ -0,0 +1,171 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 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. + */ +#ifdef __RTTHREAD__ +#include +#include + +#include +#include + +static bool ejected = false; +static rt_device_t flash_device; +static struct rt_device_blk_geometry blk_geom; + +#ifdef __CC_ARM +uint16_t __builtin_bswap16(uint16_t x) +{ + return (x << 8) | (x >> 8); +} +#endif + +void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]) +{ + (void) lun; + + const char vid[] = PKG_TINYUSB_DEVICE_MSC_VID; + const char pid[] = PKG_TINYUSB_DEVICE_MSC_PID; + const char rev[] = PKG_TINYUSB_DEVICE_MSC_REV; + + memcpy(vendor_id, vid, strlen(vid)); + memcpy(product_id, pid, strlen(pid)); + memcpy(product_rev, rev, strlen(rev)); +} + +bool tud_msc_test_unit_ready_cb(uint8_t lun) +{ + (void) lun; + + if (ejected) + { + tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3a, 0x00); + return false; + } + + if (flash_device == NULL) + { + flash_device = rt_device_find(PKG_TINYUSB_DEVICE_MSC_NAME); + } + if (flash_device != NULL) + { + static uint8_t open_flg = 0; + if (!open_flg) + { + open_flg = 1; + rt_device_open(flash_device, 0); + } + + rt_device_control(flash_device, RT_DEVICE_CTRL_BLK_GETGEOME, &blk_geom); + return true; + } + + return false; +} + +void tud_msc_capacity_cb(uint8_t lun, uint32_t *block_count, uint16_t *block_size) +{ + (void) lun; + + *block_count = blk_geom.sector_count; + *block_size = blk_geom.bytes_per_sector; +} + +bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject) +{ + (void) lun; + (void) power_condition; + + if (load_eject) + { + if (start) + { + ejected = false; + } else { + // unload disk storage + ejected = true; + } + } + + return true; +} + +int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void *buffer, uint32_t bufsize) +{ + (void) lun; + (void) offset; + (void) bufsize; + + return (int32_t) rt_device_read(flash_device, (rt_off_t) lba, buffer, 1) * blk_geom.bytes_per_sector; +} + +int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t *buffer, uint32_t bufsize) +{ + (void) lun; + (void) offset; + (void) bufsize; + + return (int32_t) rt_device_write(flash_device, (rt_off_t) lba, buffer, 1) * blk_geom.bytes_per_sector; +} + +int32_t tud_msc_scsi_cb(uint8_t lun, uint8_t const scsi_cmd[16], void *buffer, uint16_t bufsize) +{ + void const *response = NULL; + uint16_t resplen = 0; + + // most scsi handled is input + bool in_xfer = true; + + switch (scsi_cmd[0]) + { + case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: + // Host is about to read/write etc ... better not to disconnect disk + resplen = 0; + break; + + default: + // Set Sense = Invalid Command Operation + tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); + + // negative means error -> tinyusb could stall and/or response with failed status + resplen = -1; + break; + } + + // return resplen must not larger than bufsize + if (resplen > bufsize) resplen = bufsize; + + if (response && (resplen > 0)) + { + if (in_xfer) + { + memcpy(buffer, response, resplen); + } else { + // SCSI output + } + } + + return resplen; +} +#endif /*__RTTHREAD__*/ diff --git a/lib/rt-thread/tusb_config.h b/lib/rt-thread/tusb_config.h new file mode 100644 index 000000000..8b145f3f7 --- /dev/null +++ b/lib/rt-thread/tusb_config.h @@ -0,0 +1,147 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 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 _TUSB_CONFIG_H_ +#define _TUSB_CONFIG_H_ + +#ifdef __RTTHREAD__ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +//-------------------------------------------------------------------- +// COMMON CONFIGURATION +//-------------------------------------------------------------------- + +#if defined(SOC_SERIES_STM32F0) +#define CFG_TUSB_MCU OPT_MCU_STM32F0 +#elif defined(SOC_SERIES_STM32F1) +#define CFG_TUSB_MCU OPT_MCU_STM32F1 +#elif defined(SOC_SERIES_STM32F2) +#define CFG_TUSB_MCU OPT_MCU_STM32F2 +#elif defined(SOC_SERIES_STM32F3) +#define CFG_TUSB_MCU OPT_MCU_STM32F3 +#elif defined(SOC_SERIES_STM32F4) +#define CFG_TUSB_MCU OPT_MCU_STM32F4 +#elif defined(SOC_SERIES_STM32F7) +#define CFG_TUSB_MCU OPT_MCU_STM32F7 +#elif defined(SOC_SERIES_STM32H7) +#define CFG_TUSB_MCU OPT_MCU_STM32H7 +#elif defined(SOC_SERIES_STM32L0) +#define CFG_TUSB_MCU OPT_MCU_STM32L0 +#elif defined(SOC_SERIES_STM32L1) +#define CFG_TUSB_MCU OPT_MCU_STM32L1 +#elif defined(SOC_SERIES_STM32L4) +#define CFG_TUSB_MCU OPT_MCU_STM32L4 +#elif defined(SOC_NRF52840) +#define CFG_TUSB_MCU OPT_MCU_NRF5X +#elif defined(SOC_HPM6000) +#define CFG_TUSB_MCU OPT_MCU_HPM +#elif defined(SOC_RP2040) +#define CFG_TUSB_MCU OPT_MCU_RP2040 +#elif defined(SOC_FAMILY_RENESAS) +#define CFG_TUSB_MCU OPT_MCU_RAXXX +#else +#error "Not support for current MCU" +#endif + +#define CFG_TUSB_OS OPT_OS_RTTHREAD + +//-------------------------------------------------------------------- +// DEBUG CONFIGURATION +//-------------------------------------------------------------------- +#ifdef CFG_TUSB_DEBUG +#define CFG_TUSB_DEBUG_PRINTF rt_kprintf +#endif /* CFG_TUSB_DEBUG */ + +#ifndef BOARD_DEVICE_RHPORT_NUM +#define BOARD_DEVICE_RHPORT_NUM PKG_TINYUSB_RHPORT_NUM +#endif + +#ifndef BOARD_DEVICE_RHPORT_SPEED +#define BOARD_DEVICE_RHPORT_SPEED PKG_TINYUSB_DEVICE_PORT_SPEED +#endif + +#if BOARD_DEVICE_RHPORT_NUM == 0 +#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#elif BOARD_DEVICE_RHPORT_NUM == 1 +#define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#else + #error "Incorrect RHPort configuration" +#endif + +/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. + * Tinyusb use follows macros to declare transferring memory so that they can be put + * into those specific section. + * e.g + * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) + * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) + */ +#ifndef CFG_TUSB_MEM_SECTION +#define CFG_TUSB_MEM_SECTION rt_section(PKG_TINYUSB_MEM_SECTION) +#endif + +#ifndef CFG_TUSB_MEM_ALIGN +#define CFG_TUSB_MEM_ALIGN rt_align(PKG_TINYUSB_MEM_ALIGN) +#endif + +//-------------------------------------------------------------------- +// DEVICE CONFIGURATION +//-------------------------------------------------------------------- + +#ifndef CFG_TUD_ENDPOINT0_SIZE +#define CFG_TUD_ENDPOINT0_SIZE PKG_TINYUSB_EDPT0_SIZE +#endif + +// CDC FIFO size of TX and RX +#define CFG_TUD_CDC_RX_BUFSIZE PKG_TINYUSB_DEVICE_CDC_RX_BUFSIZE +#define CFG_TUD_CDC_TX_BUFSIZE PKG_TINYUSB_DEVICE_CDC_TX_BUFSIZE + +#define CFG_TUD_MSC_EP_BUFSIZE PKG_TINYUSB_DEVICE_MSC_EP_BUFSIZE + +#define CFG_TUD_HID_EP_BUFSIZE PKG_TINYUSB_DEVICE_HID_EP_BUFSIZE + +#ifndef PKG_TINYUSB_DEVICE_CDC_STRING +#define PKG_TINYUSB_DEVICE_CDC_STRING "" +#endif + +#ifndef PKG_TINYUSB_DEVICE_MSC_STRING +#define PKG_TINYUSB_DEVICE_MSC_STRING "" +#endif + +#ifndef PKG_TINYUSB_DEVICE_HID_STRING +#define PKG_TINYUSB_DEVICE_HID_STRING "" +#endif + + +#ifdef __cplusplus +} +#endif +#endif /*__RTTHREAD__*/ + +#endif /* _TUSB_CONFIG_H_ */ diff --git a/lib/rt-thread/tusb_rt_thread_port.c b/lib/rt-thread/tusb_rt_thread_port.c new file mode 100644 index 000000000..d33e3ac60 --- /dev/null +++ b/lib/rt-thread/tusb_rt_thread_port.c @@ -0,0 +1,81 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 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. + */ +#ifdef __RTTHREAD__ +#include + +#define DBG_TAG "TinyUSB" +#define DBG_LVL DBG_INFO +#include +#include + +#ifndef RT_USING_HEAP +/* if there is not enable heap, we should use static thread and stack. */ +static rt_uint8_t tusb_stack[PKG_TINYUSB_STACK_SIZE]; +static struct rt_thread tusb_thread; +#endif /* RT_USING_HEAP */ + +extern int tusb_board_init(void); + +static void tusb_thread_entry(void *parameter) +{ + (void) parameter; + while (1) + { + tud_task(); + } +} + +static int init_tinyusb(void) +{ + rt_thread_t tid; + + tusb_board_init(); + tusb_init(); + +#ifdef RT_USING_HEAP + tid = rt_thread_create("tusb", tusb_thread_entry, RT_NULL, + PKG_TINYUSB_STACK_SIZE, + PKG_TINYUSB_THREAD_PRIORITY, 10); + if (tid == RT_NULL) +#else + rt_err_t result; + + tid = &tusb_thread; + result = rt_thread_init(tid, "tusb", tusb_thread_entry, RT_NULL, + tusb_stack, sizeof(tusb_stack), 4, 10); + if (result != RT_EOK) +#endif /* RT_USING_HEAP */ + { + LOG_E("Fail to create TinyUSB thread"); + return -1; + } + + rt_thread_startup(tid); + + return 0; +} +INIT_APP_EXPORT(init_tinyusb); +#endif /*__RTTHREAD__*/ diff --git a/library.json b/library.json new file mode 100644 index 000000000..3cdd5990f --- /dev/null +++ b/library.json @@ -0,0 +1,23 @@ +{ + "name": "TinyUSB", + "version": "0.16.0", + "description": "TinyUSB is an open-source cross-platform USB Host/Device stack for embedded system, designed to be memory-safe with no dynamic allocation and thread-safe with all interrupt events are deferred then handled in the non-ISR task function.", + "keywords": "usb, host, device", + "repository": + { + "type": "git", + "url": "https://github.com/hathach/tinyusb.git" + }, + "authors": + [ + { + "name": "Ha Thach", + "email": "thach@tinyusb.org", + "maintainer": true + } + ], + "license": "MIT", + "homepage": "https://www.tinyusb.org/", + "frameworks": "*", + "platforms": "*" +} diff --git a/repository.yml b/repository.yml index 702753a90..28666d2d4 100644 --- a/repository.yml +++ b/repository.yml @@ -13,5 +13,6 @@ repo.versions: "0.13.0": "0.13.0" "0.14.0": "0.14.0" "0.15.0": "0.15.0" - "0-latest": "0.15.0" + "0.16.0": "0.16.0" + "0-latest": "0.16.0" "0-dev": "0.0.0" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 076e1e1eb..272962332 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -41,7 +41,7 @@ function(add_tinyusb TARGET) ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../lib/networking ) - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") target_compile_options(${TARGET} PRIVATE -Wall -Wextra diff --git a/src/class/audio/audio.h b/src/class/audio/audio.h index 70d431282..d6f3e22e2 100644 --- a/src/class/audio/audio.h +++ b/src/class/audio/audio.h @@ -924,6 +924,31 @@ typedef struct TU_ATTR_PACKED { } subrange[numSubRanges]; \ } +// 6.1 Interrupt Data Message Format +typedef struct TU_ATTR_PACKED +{ + uint8_t bInfo; + uint8_t bAttribute; + union + { + uint16_t wValue; + struct + { + uint8_t wValue_cn_or_mcn; + uint8_t wValue_cs; + }; + }; + union + { + uint16_t wIndex; + struct + { + uint8_t wIndex_ep_or_int; + uint8_t wIndex_entity_id; + }; + }; +} audio_interrupt_data_t; + /** @} */ #ifdef __cplusplus diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 1a7ce7870..9ba38a20c 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -96,13 +96,6 @@ #define USE_LINEAR_BUFFER 1 #endif -// Temporarily put the check here for stm32_fsdev -#ifdef TUP_USBIP_FSDEV - #define USE_ISO_EP_ALLOCATION 1 -#else - #define USE_ISO_EP_ALLOCATION 0 -#endif - // Declaration of buffers // Check for maximum supported numbers @@ -110,24 +103,36 @@ #error Maximum number of audio functions restricted to three! #endif +// Put sw_buf in USB section only if necessary +#if USE_LINEAR_BUFFER || CFG_TUD_AUDIO_ENABLE_ENCODING +#define IN_SW_BUF_MEM_SECTION +#else +#define IN_SW_BUF_MEM_SECTION CFG_TUD_MEM_SECTION +#endif +#if USE_LINEAR_BUFFER || CFG_TUD_AUDIO_ENABLE_DECODING +#define OUT_SW_BUF_MEM_SECTION +#else +#define OUT_SW_BUF_MEM_SECTION CFG_TUD_MEM_SECTION +#endif + // 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_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]; + IN_SW_BUF_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_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]; + IN_SW_BUF_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_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]; + IN_SW_BUF_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 @@ -154,21 +159,21 @@ // 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_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]; + OUT_SW_BUF_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_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]; + OUT_SW_BUF_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_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]; + OUT_SW_BUF_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 @@ -217,7 +222,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_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]; + 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 +230,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_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]; + 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 +238,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_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]; + 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 +248,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_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]; + 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 +256,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_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]; + 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 +264,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_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]; + 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 @@ -289,10 +294,12 @@ typedef struct #endif -#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN - uint8_t ep_int_ctr; // Audio control interrupt EP. +#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP + uint8_t ep_int; // Audio control interrupt EP. #endif + bool mounted; // Device opened + /*------------- From this point, data is not cleared by bus reset -------------*/ uint16_t desc_length; // Length of audio function descriptor @@ -346,8 +353,8 @@ typedef struct #endif // Audio control interrupt buffer - no FIFO - 6 Bytes according to UAC 2 specification (p. 74) -#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN - CFG_TUSB_MEM_ALIGN uint8_t ep_int_ctr_buf[CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE]; +#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP + CFG_TUSB_MEM_ALIGN uint8_t ep_int_buf[6]; #endif // Decoding parameters - parameters are set when alternate AS interface is set by host @@ -364,14 +371,21 @@ typedef struct #endif #endif +#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL + uint32_t sample_rate_tx; + uint16_t packet_sz_tx[3]; + uint8_t bclock_id_tx; + uint8_t interval_tx; +#endif + // Encoding parameters - parameters are set when alternate AS interface is set by host -#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_ENCODING +#if CFG_TUD_AUDIO_ENABLE_EP_IN && (CFG_TUD_AUDIO_ENABLE_ENCODING || CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL) audio_format_type_t format_type_tx; uint8_t n_channels_tx; + uint8_t n_bytes_per_sampe_tx; #if CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING audio_data_format_type_I_t format_type_I_tx; - uint8_t n_bytes_per_sampe_tx; uint8_t n_channels_per_ff_tx; uint8_t n_ff_used_tx; #endif @@ -444,7 +458,7 @@ static bool audiod_verify_itf_exists(uint8_t itf, uint8_t *func_id); static bool audiod_verify_ep_exists(uint8_t ep, uint8_t *func_id); static uint8_t audiod_get_audio_fct_idx(audiod_function_t * audio); -#if CFG_TUD_AUDIO_ENABLE_ENCODING || CFG_TUD_AUDIO_ENABLE_DECODING +#if (CFG_TUD_AUDIO_ENABLE_EP_IN && (CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL || CFG_TUD_AUDIO_ENABLE_ENCODING)) || (CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING) static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * p_desc, uint8_t const * p_desc_end, uint8_t const as_itf); static inline uint8_t tu_desc_subtype(void const* desc) @@ -453,6 +467,11 @@ static inline uint8_t tu_desc_subtype(void const* desc) } #endif +#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL +static bool audiod_calc_tx_packet_sz(audiod_function_t* audio); +static uint16_t audiod_tx_packet_size(const uint16_t* norminal_size, uint16_t data_count, uint16_t fifo_depth, uint16_t max_size); +#endif + #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP static bool set_fb_params_freq(audiod_function_t* audio, uint32_t sample_freq, uint32_t mclk_freq); #endif @@ -462,23 +481,7 @@ bool tud_audio_n_mounted(uint8_t func_id) TU_VERIFY(func_id < CFG_TUD_AUDIO); audiod_function_t* audio = &_audiod_fct[func_id]; -#if CFG_TUD_AUDIO_ENABLE_EP_OUT - if (audio->ep_out == 0) return false; -#endif - -#if CFG_TUD_AUDIO_ENABLE_EP_IN - if (audio->ep_in == 0) return false; -#endif - -#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN - if (audio->ep_int_ctr == 0) return false; -#endif - -#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP - if (audio->ep_fb == 0) return false; -#endif - - return true; + return audio->mounted; } //--------------------------------------------------------------------+ @@ -631,73 +634,55 @@ static bool audiod_rx_done_cb(uint8_t rhport, audiod_function_t* audio, uint16_t // Decoding according to 2.3.1.5 Audio Streams // Helper function -static inline uint8_t * audiod_interleaved_copy_bytes_fast_decode(uint16_t const nBytesToCopy, void * dst, uint8_t * dst_end, uint8_t * src, uint8_t const n_ff_used) +static inline void * audiod_interleaved_copy_bytes_fast_decode(uint16_t const nBytesPerSample, void * dst, const void * dst_end, void * src, uint8_t const n_ff_used) { + // Due to one FIFO contains 2 channels, data always aligned to (nBytesPerSample * 2) + uint16_t * dst16 = dst; + uint16_t * src16 = src; + const uint16_t * dst_end16 = dst_end; + uint32_t * dst32 = dst; + uint32_t * src32 = src; + const uint32_t * dst_end32 = dst_end; - // This function is an optimized version of - // while((uint8_t *)dst < dst_end) - // { - // memcpy(dst, src, nBytesToCopy); - // dst = (uint8_t *)dst + nBytesToCopy; - // src += nBytesToCopy * n_ff_used; - // } - - // Optimize for fast half word copies - typedef struct{ - uint16_t val; - } __attribute((__packed__)) unaligned_uint16_t; - - // Optimize for fast word copies - typedef struct{ - uint32_t val; - } __attribute((__packed__)) unaligned_uint32_t; - - switch (nBytesToCopy) + if (nBytesPerSample == 1) { - case 1: - while((uint8_t *)dst < dst_end) - { - *(uint8_t *)dst++ = *src; - src += n_ff_used; - } - break; - - case 2: - while((uint8_t *)dst < dst_end) - { - *(unaligned_uint16_t*)dst = *(unaligned_uint16_t*)src; - dst += 2; - src += 2 * n_ff_used; - } - break; - - case 3: - while((uint8_t *)dst < dst_end) - { - // memcpy(dst, src, 3); - // dst = (uint8_t *)dst + 3; - // src += 3 * n_ff_used; - - // TODO: Is there a faster way to copy 3 bytes? - *(uint8_t *)dst++ = *src++; - *(uint8_t *)dst++ = *src++; - *(uint8_t *)dst++ = *src++; - - src += 3 * (n_ff_used - 1); - } - break; - - case 4: - while((uint8_t *)dst < dst_end) - { - *(unaligned_uint32_t*)dst = *(unaligned_uint32_t*)src; - dst += 4; - src += 4 * n_ff_used; - } - break; + while(dst16 < dst_end16) + { + *dst16++ = *src16++; + src16 += n_ff_used - 1; + } + return src16; + } + else if (nBytesPerSample == 2) + { + while(dst32 < dst_end32) + { + *dst32++ = *src32++; + src32 += n_ff_used - 1; + } + return src32; + } + else if (nBytesPerSample == 3) + { + while(dst16 < dst_end16) + { + *dst16++ = *src16++; + *dst16++ = *src16++; + *dst16++ = *src16++; + src16 += 3 * (n_ff_used - 1); + } + return src16; + } + else // nBytesPerSample == 4 + { + while(dst32 < dst_end32) + { + *dst32++ = *src32++; + *dst32++ = *src32++; + src32 += 2 * (n_ff_used - 1); + } + return src32; } - - return src; } static bool audiod_decode_type_I_pcm(uint8_t rhport, audiod_function_t* audio, uint16_t n_bytes_received) @@ -819,27 +804,32 @@ tu_fifo_t* tud_audio_n_get_tx_support_ff(uint8_t func_id, uint8_t ff_idx) #endif -#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN - -// If no interrupt transmit is pending bytes get written into buffer and a transmit is scheduled - once transmit completed tud_audio_int_ctr_done_cb() is called in inform user -uint16_t tud_audio_int_ctr_n_write(uint8_t func_id, uint8_t const* buffer, uint16_t len) +#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP +// If no interrupt transmit is pending bytes get written into buffer and a transmit is scheduled - once transmit completed tud_audio_int_done_cb() is called in inform user +bool tud_audio_int_n_write(uint8_t func_id, const audio_interrupt_data_t * data) { TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); + TU_VERIFY(_audiod_fct[func_id].ep_int != 0); + // We write directly into the EP's buffer - abort if previous transfer not complete - TU_VERIFY(!usbd_edpt_busy(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int_ctr)); + TU_VERIFY(usbd_edpt_claim(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int)); - TU_VERIFY(tu_memcpy_s(_audiod_fct[func_id].ep_int_ctr_buf, CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE, buffer, len)==0); - - // Schedule transmit - TU_VERIFY(usbd_edpt_xfer(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int_ctr, _audiod_fct[func_id].ep_int_ctr_buf, len)); + // Check length + if (tu_memcpy_s(_audiod_fct[func_id].ep_int_buf, sizeof(_audiod_fct[func_id].ep_int_buf), data, sizeof(audio_interrupt_data_t)) == 0) + { + // Schedule transmit + TU_ASSERT(usbd_edpt_xfer(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int, _audiod_fct[func_id].ep_int_buf, sizeof(_audiod_fct[func_id].ep_int_buf)), 0); + } else + { + // Release endpoint since we don't make any transfer + usbd_edpt_release(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int); + } return true; } - #endif - // This function is called once a transmit of an audio packet was successfully completed. Here, we encode samples and place it in IN EP's buffer for next transmission. // If you prefer your own (more efficient) implementation suiting your purpose set CFG_TUD_AUDIO_ENABLE_ENCODING = 0 and use tud_audio_n_write. @@ -904,9 +894,12 @@ static bool audiod_tx_done_cb(uint8_t rhport, audiod_function_t * audio) #else // No support FIFOs, if no linear buffer required schedule transmit, else put data into linear buffer and schedule - +#if CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL + // packet_sz_tx is based on total packet size, here we want size for each support buffer. + n_bytes_tx = audiod_tx_packet_size(audio->packet_sz_tx, tu_fifo_count(&audio->ep_in_ff), audio->ep_in_ff.depth, audio->ep_in_sz); +#else n_bytes_tx = tu_min16(tu_fifo_count(&audio->ep_in_ff), audio->ep_in_sz); // Limit up to max packet size, more can not be done for ISO - +#endif #if USE_LINEAR_BUFFER_TX tu_fifo_read_n(&audio->ep_in_ff, audio->lin_buf_in, n_bytes_tx); TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_in, audio->lin_buf_in, n_bytes_tx)); @@ -944,64 +937,55 @@ range [-1, +1) * */ // Helper function -static inline uint8_t * audiod_interleaved_copy_bytes_fast_encode(uint16_t const nBytesToCopy, uint8_t * src, uint8_t * src_end, uint8_t * dst, uint8_t const n_ff_used) +static inline void * audiod_interleaved_copy_bytes_fast_encode(uint16_t const nBytesPerSample, void * src, const void * src_end, void * dst, uint8_t const n_ff_used) { - // Optimize for fast half word copies - typedef struct{ - uint16_t val; - } __attribute((__packed__)) unaligned_uint16_t; + // Due to one FIFO contains 2 channels, data always aligned to (nBytesPerSample * 2) + uint16_t * dst16 = dst; + uint16_t * src16 = src; + const uint16_t * src_end16 = src_end; + uint32_t * dst32 = dst; + uint32_t * src32 = src; + const uint32_t * src_end32 = src_end; - // Optimize for fast word copies - typedef struct{ - uint32_t val; - } __attribute((__packed__)) unaligned_uint32_t; - - switch (nBytesToCopy) + if (nBytesPerSample == 1) { - case 1: - while(src < src_end) - { - *dst = *src++; - dst += n_ff_used; - } - break; - - case 2: - while(src < src_end) - { - *(unaligned_uint16_t*)dst = *(unaligned_uint16_t*)src; - src += 2; - dst += 2 * n_ff_used; - } - break; - - case 3: - while(src < src_end) - { - // memcpy(dst, src, 3); - // src = (uint8_t *)src + 3; - // dst += 3 * n_ff_used; - - // TODO: Is there a faster way to copy 3 bytes? - *dst++ = *src++; - *dst++ = *src++; - *dst++ = *src++; - - dst += 3 * (n_ff_used - 1); - } - break; - - case 4: - while(src < src_end) - { - *(unaligned_uint32_t*)dst = *(unaligned_uint32_t*)src; - src += 4; - dst += 4 * n_ff_used; - } - break; + while(src16 < src_end16) + { + *dst16++ = *src16++; + dst16 += n_ff_used - 1; + } + return dst16; + } + else if (nBytesPerSample == 2) + { + while(src32 < src_end32) + { + *dst32++ = *src32++; + dst32 += n_ff_used - 1; + } + return dst32; + } + else if (nBytesPerSample == 3) + { + while(src16 < src_end16) + { + *dst16++ = *src16++; + *dst16++ = *src16++; + *dst16++ = *src16++; + dst16 += 3 * (n_ff_used - 1); + } + return dst16; + } + else // nBytesPerSample == 4 + { + while(src32 < src_end32) + { + *dst32++ = *src32++; + *dst32++ = *src32++; + dst32 += 2 * (n_ff_used - 1); + } + return dst32; } - - return dst; } static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audio) @@ -1014,8 +998,6 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi // Determine amount of samples uint8_t const n_ff_used = audio->n_ff_used_tx; - uint16_t const nBytesToCopy = audio->n_channels_per_ff_tx * audio->n_bytes_per_sampe_tx; - uint16_t const capPerFF = audio->ep_in_sz / n_ff_used; // Sample capacity per FIFO in bytes uint16_t nBytesPerFFToSend = tu_fifo_count(&audio->tx_supp_ff[0]); uint8_t cnt_ff; @@ -1028,14 +1010,23 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi } } - // Check if there is enough +#if CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL + const uint16_t norm_packet_sz_tx[3] = {audio->packet_sz_tx[0] / n_ff_used, + audio->packet_sz_tx[1] / n_ff_used, + audio->packet_sz_tx[2] / n_ff_used}; + // packet_sz_tx is based on total packet size, here we want size for each support buffer. + nBytesPerFFToSend = audiod_tx_packet_size(norm_packet_sz_tx, nBytesPerFFToSend, audio->tx_supp_ff[0].depth, audio->ep_in_sz / n_ff_used); + // Check if there is enough data + if (nBytesPerFFToSend == 0) return 0; +#else + // Check if there is enough data if (nBytesPerFFToSend == 0) return 0; - // Limit to maximum sample number - THIS IS A POSSIBLE ERROR SOURCE IF TOO MANY SAMPLE WOULD NEED TO BE SENT BUT CAN NOT! - nBytesPerFFToSend = tu_min16(nBytesPerFFToSend, capPerFF); - + nBytesPerFFToSend = tu_min16(nBytesPerFFToSend, audio->ep_in_sz / n_ff_used); // Round to full number of samples (flooring) - nBytesPerFFToSend = (nBytesPerFFToSend / nBytesToCopy) * nBytesToCopy; + uint16_t const nSlotSize = audio->n_channels_per_ff_tx * audio->n_bytes_per_sampe_tx; + nBytesPerFFToSend = (nBytesPerFFToSend / nSlotSize) * nSlotSize; +#endif // Encode uint8_t * dst; @@ -1298,7 +1289,7 @@ void audiod_init(void) #endif // CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_ENCODING // Set encoding parameters for Type_I formats -#if CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING +#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING switch (i) { #if CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ > 0 @@ -1398,6 +1389,10 @@ void audiod_init(void) } } +bool audiod_deinit(void) { + return false; // TODO not implemented yet +} + void audiod_reset(uint8_t rhport) { (void) rhport; @@ -1441,10 +1436,11 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin // Verify version is correct - this check can be omitted TU_VERIFY(itf_desc->bInterfaceProtocol == AUDIO_INT_PROTOCOL_CODE_V2); - // Verify interrupt control EP is enabled if demanded by descriptor - this should be best some static check however - this check can be omitted - if (itf_desc->bNumEndpoints == 1) // 0 or 1 EPs are allowed + // Verify interrupt control EP is enabled if demanded by descriptor + TU_ASSERT(itf_desc->bNumEndpoints <= 1); // 0 or 1 EPs are allowed + if (itf_desc->bNumEndpoints == 1) { - TU_VERIFY(CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN > 0); + TU_ASSERT(CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP); } // Alternate setting MUST be zero - this check can be omitted @@ -1477,83 +1473,143 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin #endif } -#if USE_ISO_EP_ALLOCATION - #if CFG_TUD_AUDIO_ENABLE_EP_IN - uint8_t ep_in = 0; - uint16_t ep_in_size = 0; - #endif - - #if CFG_TUD_AUDIO_ENABLE_EP_OUT - uint8_t ep_out = 0; - uint16_t ep_out_size = 0; - #endif - - #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP - uint8_t ep_fb = 0; - #endif - - uint8_t const *p_desc = _audiod_fct[i].p_desc; - uint8_t const *p_desc_end = p_desc + _audiod_fct[i].desc_length - TUD_AUDIO_DESC_IAD_LEN; - while (p_desc < p_desc_end) +#ifdef TUP_DCD_EDPT_ISO_ALLOC { - if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) - { - tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) p_desc; - if (desc_ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) - { - #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP - // Explicit feedback EP - if (desc_ep->bmAttributes.usage == 1) - { - ep_fb = desc_ep->bEndpointAddress; - } - #endif - // Data EP - if (desc_ep->bmAttributes.usage == 0) - { - if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) - { #if CFG_TUD_AUDIO_ENABLE_EP_IN - ep_in = desc_ep->bEndpointAddress; - ep_in_size = TU_MAX(tu_edpt_packet_size(desc_ep), ep_in_size); + uint8_t ep_in = 0; + uint16_t ep_in_size = 0; #endif - } else - { + #if CFG_TUD_AUDIO_ENABLE_EP_OUT - ep_out = desc_ep->bEndpointAddress; - ep_out_size = TU_MAX(tu_edpt_packet_size(desc_ep), ep_out_size); + uint8_t ep_out = 0; + uint16_t ep_out_size = 0; #endif + + #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP + uint8_t ep_fb = 0; + #endif + uint8_t const *p_desc = _audiod_fct[i].p_desc; + uint8_t const *p_desc_end = p_desc + _audiod_fct[i].desc_length - TUD_AUDIO_DESC_IAD_LEN; + while (p_desc < p_desc_end) + { + if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) + { + tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) p_desc; + if (desc_ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) + { + #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP + // Explicit feedback EP + if (desc_ep->bmAttributes.usage == 1) + { + ep_fb = desc_ep->bEndpointAddress; + } + #endif + // Data EP + if (desc_ep->bmAttributes.usage == 0) + { + if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) + { + #if CFG_TUD_AUDIO_ENABLE_EP_IN + ep_in = desc_ep->bEndpointAddress; + ep_in_size = TU_MAX(tu_edpt_packet_size(desc_ep), ep_in_size); + #endif + } else + { + #if CFG_TUD_AUDIO_ENABLE_EP_OUT + ep_out = desc_ep->bEndpointAddress; + ep_out_size = TU_MAX(tu_edpt_packet_size(desc_ep), ep_out_size); + #endif + } + } + + } + } + + p_desc = tu_desc_next(p_desc); + } + + #if CFG_TUD_AUDIO_ENABLE_EP_IN + if (ep_in) + { + usbd_edpt_iso_alloc(rhport, ep_in, ep_in_size); + } + #endif + + #if CFG_TUD_AUDIO_ENABLE_EP_OUT + if (ep_out) + { + usbd_edpt_iso_alloc(rhport, ep_out, ep_out_size); + } + #endif + + #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP + if (ep_fb) + { + usbd_edpt_iso_alloc(rhport, ep_fb, 4); + } + #endif + } +#endif // TUP_DCD_EDPT_ISO_ALLOC + +#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL + { + uint8_t const *p_desc = _audiod_fct[i].p_desc; + uint8_t const *p_desc_end = p_desc + _audiod_fct[i].desc_length - TUD_AUDIO_DESC_IAD_LEN; + // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning + while (p_desc_end - p_desc > 0) + { + if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) + { + tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) p_desc; + if (desc_ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) + { + if (desc_ep->bmAttributes.usage == 0) + { + if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) + { + _audiod_fct[i].interval_tx = desc_ep->bInterval; + } } } - + } else + if (tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE && tu_desc_subtype(p_desc) == AUDIO_CS_AC_INTERFACE_OUTPUT_TERMINAL) + { + if(tu_unaligned_read16(p_desc + 4) == AUDIO_TERM_TYPE_USB_STREAMING) + { + _audiod_fct[i].bclock_id_tx = p_desc[8]; + } } + p_desc = tu_desc_next(p_desc); } - p_desc = tu_desc_next(p_desc); } +#endif // CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL - #if CFG_TUD_AUDIO_ENABLE_EP_IN - if (ep_in) +#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP { - usbd_edpt_iso_alloc(rhport, ep_in, ep_in_size); + uint8_t const *p_desc = _audiod_fct[i].p_desc; + uint8_t const *p_desc_end = p_desc + _audiod_fct[i].desc_length - TUD_AUDIO_DESC_IAD_LEN; + // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning + while (p_desc_end - p_desc > 0) + { + // For each endpoint + if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) + { + tusb_desc_endpoint_t const* desc_ep = (tusb_desc_endpoint_t const *) p_desc; + uint8_t const ep_addr = desc_ep->bEndpointAddress; + // If endpoint is input-direction and interrupt-type + if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN && desc_ep->bmAttributes.xfer == TUSB_XFER_INTERRUPT) + { + // Store endpoint number and open endpoint + _audiod_fct[i].ep_int = ep_addr; + TU_ASSERT(usbd_edpt_open(_audiod_fct[i].rhport, desc_ep)); + } + } + p_desc = tu_desc_next(p_desc); + } } - #endif - - #if CFG_TUD_AUDIO_ENABLE_EP_OUT - if (ep_out) - { - usbd_edpt_iso_alloc(rhport, ep_out, ep_out_size); - } - #endif - - #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP - if (ep_fb) - { - usbd_edpt_iso_alloc(rhport, ep_fb, 4); - } - #endif - -#endif // USE_ISO_EP_ALLOCATION +#endif + _audiod_fct[i].mounted = true; break; } } @@ -1615,7 +1671,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * if (audio->ep_in_as_intf_num == itf) { audio->ep_in_as_intf_num = 0; - #if !USE_ISO_EP_ALLOCATION + #ifndef TUP_DCD_EDPT_ISO_ALLOC usbd_edpt_close(rhport, audio->ep_in); #endif @@ -1634,6 +1690,11 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * audio->ep_in = 0; // Necessary? + #if CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL + audio->packet_sz_tx[0] = 0; + audio->packet_sz_tx[1] = 0; + audio->packet_sz_tx[2] = 0; + #endif } #endif // CFG_TUD_AUDIO_ENABLE_EP_IN @@ -1641,7 +1702,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * if (audio->ep_out_as_intf_num == itf) { audio->ep_out_as_intf_num = 0; - #if !USE_ISO_EP_ALLOCATION + #ifndef TUP_DCD_EDPT_ISO_ALLOC usbd_edpt_close(rhport, audio->ep_out); #endif @@ -1662,7 +1723,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * // Close corresponding feedback EP #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP - #if !USE_ISO_EP_ALLOCATION + #ifndef TUP_DCD_EDPT_ISO_ALLOC usbd_edpt_close(rhport, audio->ep_fb); #endif audio->ep_fb = 0; @@ -1684,7 +1745,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * // Find correct interface if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && ((tusb_desc_interface_t const * )p_desc)->bInterfaceNumber == itf && ((tusb_desc_interface_t const * )p_desc)->bAlternateSetting == alt) { -#if CFG_TUD_AUDIO_ENABLE_ENCODING || CFG_TUD_AUDIO_ENABLE_DECODING +#if (CFG_TUD_AUDIO_ENABLE_EP_IN && (CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL || CFG_TUD_AUDIO_ENABLE_ENCODING)) || (CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING) uint8_t const * p_desc_parse_for_params = p_desc; #endif // From this point forward follow the EP descriptors associated to the current alternate setting interface - Open EPs if necessary @@ -1694,7 +1755,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) { tusb_desc_endpoint_t const* desc_ep = (tusb_desc_endpoint_t const *) p_desc; -#if USE_ISO_EP_ALLOCATION +#ifdef TUP_DCD_EDPT_ISO_ALLOC TU_ASSERT(usbd_edpt_iso_activate(rhport, desc_ep)); #else TU_ASSERT(usbd_edpt_open(rhport, desc_ep)); @@ -1713,12 +1774,13 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * audio->ep_in_sz = tu_edpt_packet_size(desc_ep); // If software encoding is enabled, parse for the corresponding parameters - doing this here means only AS interfaces with EPs get scanned for parameters - #if CFG_TUD_AUDIO_ENABLE_ENCODING + #if CFG_TUD_AUDIO_ENABLE_ENCODING || CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL audiod_parse_for_AS_params(audio, p_desc_parse_for_params, p_desc_end, itf); // Reconfigure size of support FIFOs - this is necessary to avoid samples to get split in case of a wrap - #if CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING - const uint16_t active_fifo_depth = (uint16_t) ((audio->tx_supp_ff_sz_max / audio->n_bytes_per_sampe_tx) * audio->n_bytes_per_sampe_tx); + #if CFG_TUD_AUDIO_ENABLE_ENCODING && CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING + const uint16_t active_fifo_depth = (uint16_t) ((audio->tx_supp_ff_sz_max / (audio->n_channels_per_ff_tx * audio->n_bytes_per_sampe_tx)) + * (audio->n_channels_per_ff_tx * audio->n_bytes_per_sampe_tx)); for (uint8_t cnt = 0; cnt < audio->n_tx_supp_ff; cnt++) { tu_fifo_config(&audio->tx_supp_ff[cnt], audio->tx_supp_ff[cnt].buffer, active_fifo_depth, 1, true); @@ -1850,6 +1912,10 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * if (disable) usbd_sof_enable(rhport, false); #endif +#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL + audiod_calc_tx_packet_sz(audio); +#endif + tud_control_status(rhport, p_request); return true; @@ -1949,7 +2015,10 @@ static bool audiod_control_request(uint8_t rhport, tusb_control_request_t const case TUSB_REQ_SET_INTERFACE: return audiod_set_interface(rhport, p_request); - // Unknown/Unsupported request + case TUSB_REQ_CLEAR_FEATURE: + return true; + + // Unknown/Unsupported request default: TU_BREAKPOINT(); return false; } } @@ -2070,10 +2139,10 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 { audiod_function_t* audio = &_audiod_fct[func_id]; -#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN +#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP // Data transmission of control interrupt finished - if (audio->ep_int_ctr == ep_addr) + if (audio->ep_int == ep_addr) { // According to USB2 specification, maximum payload of interrupt EP is 8 bytes on low speed, 64 bytes on full speed, and 1024 bytes on high speed (but only if an alternate interface other than 0 is used - see specification p. 49) // In case there is nothing to send we have to return a NAK - this is taken care of by PHY ??? @@ -2082,7 +2151,8 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 // I assume here, that things above are handled by PHY // All transmission is done - what remains to do is to inform job was completed - if (tud_audio_int_ctr_done_cb) TU_VERIFY(tud_audio_int_ctr_done_cb(rhport, (uint16_t) xferred_bytes)); + if (tud_audio_int_done_cb) tud_audio_int_done_cb(rhport); + return true; } #endif @@ -2292,6 +2362,19 @@ bool tud_audio_buffer_and_schedule_control_xfer(uint8_t rhport, tusb_control_req // Copy into buffer TU_VERIFY(0 == tu_memcpy_s(_audiod_fct[func_id].ctrl_buf, _audiod_fct[func_id].ctrl_buf_sz, data, (size_t)len)); +#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL + // Find data for sampling_frequency_control + if (p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS && p_request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE) + { + uint8_t entityID = TU_U16_HIGH(p_request->wIndex); + uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue); + if (_audiod_fct[func_id].bclock_id_tx == entityID && ctrlSel == AUDIO_CS_CTRL_SAM_FREQ && p_request->bRequest == AUDIO_CS_REQ_CUR) + { + _audiod_fct[func_id].sample_rate_tx = tu_unaligned_read32(_audiod_fct[func_id].ctrl_buf); + } + } +#endif + // Schedule transmit return tud_control_xfer(rhport, p_request, (void*)_audiod_fct[func_id].ctrl_buf, len); } @@ -2431,7 +2514,7 @@ static bool audiod_verify_ep_exists(uint8_t ep, uint8_t *func_id) return false; } -#if CFG_TUD_AUDIO_ENABLE_ENCODING || CFG_TUD_AUDIO_ENABLE_DECODING +#if (CFG_TUD_AUDIO_ENABLE_EP_IN && (CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL || CFG_TUD_AUDIO_ENABLE_ENCODING)) || (CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING) // p_desc points to the AS interface of alternate setting zero // itf is the interface number of the corresponding interface - we check if the interface belongs to EP in or EP out to see if it is a TX or RX parameter // Currently, only AS interfaces with an EP (in or out) are supposed to be parsed for! @@ -2469,7 +2552,7 @@ static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * } #endif -#if CFG_TUD_AUDIO_ENABLE_EP_OUT +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING if (as_itf == audio->ep_out_as_intf_num) { audio->n_channels_rx = ((audio_desc_cs_as_interface_t const * )p_desc)->bNrChannels; @@ -2482,7 +2565,7 @@ static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * } // Look for a Type I Format Type Descriptor(2.3.1.6 - Audio Formats) -#if CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING || CFG_TUD_AUDIO_ENABLE_TYPE_I_DECODING +#if CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING || CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL || CFG_TUD_AUDIO_ENABLE_TYPE_I_DECODING if (tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE && tu_desc_subtype(p_desc) == AUDIO_CS_AS_INTERFACE_FORMAT_TYPE && ((audio_desc_type_I_format_t const * )p_desc)->bFormatType == AUDIO_FORMAT_TYPE_I) { #if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_EP_OUT @@ -2502,7 +2585,7 @@ static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * } #endif -#if CFG_TUD_AUDIO_ENABLE_EP_OUT +#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING if (as_itf == audio->ep_out_as_intf_num) { audio->n_bytes_per_sampe_rx = ((audio_desc_type_I_format_t const * )p_desc)->bSubslotSize; @@ -2518,6 +2601,96 @@ static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * } #endif +#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL + +static bool audiod_calc_tx_packet_sz(audiod_function_t* audio) +{ + TU_VERIFY(audio->format_type_tx == AUDIO_FORMAT_TYPE_I); + TU_VERIFY(audio->n_channels_tx); + TU_VERIFY(audio->n_bytes_per_sampe_tx); + TU_VERIFY(audio->interval_tx); + TU_VERIFY(audio->sample_rate_tx); + + const uint8_t interval = (tud_speed_get() == TUSB_SPEED_FULL) ? audio->interval_tx : 1 << (audio->interval_tx - 1); + + const uint16_t sample_normimal = (uint16_t)(audio->sample_rate_tx * interval / ((tud_speed_get() == TUSB_SPEED_FULL) ? 1000 : 8000)); + const uint16_t sample_reminder = (uint16_t)(audio->sample_rate_tx * interval % ((tud_speed_get() == TUSB_SPEED_FULL) ? 1000 : 8000)); + + const uint16_t packet_sz_tx_min = (uint16_t)((sample_normimal - 1) * audio->n_channels_tx * audio->n_bytes_per_sampe_tx); + const uint16_t packet_sz_tx_norm = (uint16_t)(sample_normimal * audio->n_channels_tx * audio->n_bytes_per_sampe_tx); + const uint16_t packet_sz_tx_max = (uint16_t)((sample_normimal + 1) * audio->n_channels_tx * audio->n_bytes_per_sampe_tx); + + // Endpoint size must larger than packet size + TU_ASSERT(packet_sz_tx_max <= audio->ep_in_sz); + + // Frmt20.pdf 2.3.1.1 USB Packets + if (sample_reminder) + { + // All virtual frame packets must either contain INT(nav) audio slots (small VFP) or INT(nav)+1 (large VFP) audio slots + audio->packet_sz_tx[0] = packet_sz_tx_norm; + audio->packet_sz_tx[1] = packet_sz_tx_norm; + audio->packet_sz_tx[2] = packet_sz_tx_max; + } else + { + // In the case where nav = INT(nav), ni may vary between INT(nav)-1 (small VFP), INT(nav) + // (medium VFP) and INT(nav)+1 (large VFP). + audio->packet_sz_tx[0] = packet_sz_tx_min; + audio->packet_sz_tx[1] = packet_sz_tx_norm; + audio->packet_sz_tx[2] = packet_sz_tx_max; + } + + return true; +} + +static uint16_t audiod_tx_packet_size(const uint16_t* norminal_size, uint16_t data_count, uint16_t fifo_depth, uint16_t max_depth) +{ + // Flow control need a FIFO size of at least 4*Navg + if(norminal_size[1] && norminal_size[1] <= fifo_depth * 4) + { + // Use blackout to prioritize normal size packet + static int ctrl_blackout = 0; + uint16_t packet_size; + uint16_t slot_size = norminal_size[2] - norminal_size[1]; + if (data_count < norminal_size[0]) + { + // If you get here frequently, then your I2S clock deviation is too big ! + packet_size = 0; + } else + if (data_count < fifo_depth / 2 - slot_size && !ctrl_blackout) + { + packet_size = norminal_size[0]; + ctrl_blackout = 10; + } else + if (data_count > fifo_depth / 2 + slot_size && !ctrl_blackout) + { + packet_size = norminal_size[2]; + if(norminal_size[0] == norminal_size[1]) + { + // nav > INT(nav), eg. 44.1k, 88.2k + ctrl_blackout = 0; + } else + { + // nav = INT(nav), eg. 48k, 96k + ctrl_blackout = 10; + } + } else + { + packet_size = norminal_size[1]; + if (ctrl_blackout) + { + ctrl_blackout--; + } + } + // Normally this cap is not necessary + return tu_min16(packet_size, max_depth); + } else + { + return tu_min16(data_count, max_depth); + } +} + +#endif + #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index 7c88b99fc..b16514fd4 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -181,6 +181,11 @@ #endif #endif +// (For TYPE-I format only) Flow control is necessary to allow IN ep send correct amount of data, unless it's a virtual device where data is perfectly synchronized to USB clock. +#ifndef CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL +#define CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL 1 +#endif + // Enable/disable feedback EP (required for asynchronous RX applications) #ifndef CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP #define CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP 0 // Feedback - 0 or 1 @@ -191,13 +196,9 @@ #define CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION 0 // 0 or 1 #endif -// Audio interrupt control EP size - disabled if 0 -#ifndef CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN -#define CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN 0 // Audio interrupt control - if required - 6 Bytes according to UAC 2 specification (p. 74) -#endif - -#ifndef CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE -#define CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE 6 // Buffer size of audio control interrupt EP - 6 Bytes according to UAC 2 specification (p. 74) +// Enable/disable interrupt EP (required for notifying host of control changes) +#ifndef CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP +#define CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP 0 // Feedback - 0 or 1 #endif // Use software encoding/decoding @@ -388,10 +389,11 @@ uint16_t tud_audio_n_write_support_ff (uint8_t func_id, uint8_t ff_i tu_fifo_t* tud_audio_n_get_tx_support_ff (uint8_t func_id, uint8_t ff_idx); #endif -#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN -uint16_t tud_audio_int_ctr_n_write (uint8_t func_id, uint8_t const* buffer, uint16_t len); +#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP +bool tud_audio_int_n_write (uint8_t func_id, const audio_interrupt_data_t * data); #endif + //--------------------------------------------------------------------+ // Application API (Interface0) //--------------------------------------------------------------------+ @@ -431,8 +433,8 @@ static inline tu_fifo_t* tud_audio_get_tx_support_ff (uint8_t ff_idx); // INT CTR API -#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN -static inline uint16_t tud_audio_int_ctr_write (uint8_t const* buffer, uint16_t len); +#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP +static inline bool tud_audio_int_write (const audio_interrupt_data_t * data); #endif // Buffer control EP data and schedule a transmit @@ -531,8 +533,8 @@ TU_ATTR_WEAK TU_ATTR_FAST_FUNC void tud_audio_feedback_interval_isr(uint8_t func #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN -TU_ATTR_WEAK bool tud_audio_int_ctr_done_cb(uint8_t rhport, uint16_t n_bytes_copied); +#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP +TU_ATTR_WEAK void tud_audio_int_done_cb(uint8_t rhport); #endif // Invoked when audio set interface request received @@ -663,10 +665,10 @@ static inline tu_fifo_t* tud_audio_get_tx_support_ff(uint8_t ff_idx) #endif -#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN -static inline uint16_t tud_audio_int_ctr_write(uint8_t const* buffer, uint16_t len) +#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP +static inline bool tud_audio_int_write(const audio_interrupt_data_t * data) { - return tud_audio_int_ctr_n_write(0, buffer, len); + return tud_audio_int_n_write(0, data); } #endif @@ -683,6 +685,7 @@ static inline bool tud_audio_fb_set(uint32_t feedback) // Internal Class Driver API //--------------------------------------------------------------------+ void audiod_init (void); +bool audiod_deinit (void); void audiod_reset (uint8_t rhport); uint16_t audiod_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool audiod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/class/bth/bth_device.c b/src/class/bth/bth_device.c index c5c74d26a..cbf6e1332 100755 --- a/src/class/bth/bth_device.c +++ b/src/class/bth/bth_device.c @@ -91,11 +91,14 @@ bool tud_bt_acl_data_send(void *event, uint16_t event_len) //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ -void btd_init(void) -{ +void btd_init(void) { tu_memclr(&_btd_itf, sizeof(_btd_itf)); } +bool btd_deinit(void) { + return true; +} + void btd_reset(uint8_t rhport) { (void)rhport; @@ -204,7 +207,9 @@ bool btd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t c request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE) { // HCI command packet addressing for single function Primary Controllers - TU_VERIFY(request->bRequest == 0 && request->wValue == 0 && request->wIndex == 0); + // also compatible with historical mode if enabled + TU_VERIFY((request->bRequest == 0 && request->wValue == 0 && request->wIndex == 0) || + (CFG_TUD_BTH_HISTORICAL_COMPATIBLE && request->bRequest == 0xe0)); } else if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE) { diff --git a/src/class/bth/bth_device.h b/src/class/bth/bth_device.h index 921bd7a1a..4f6350839 100755 --- a/src/class/bth/bth_device.h +++ b/src/class/bth/bth_device.h @@ -36,10 +36,17 @@ #ifndef CFG_TUD_BTH_EVENT_EPSIZE #define CFG_TUD_BTH_EVENT_EPSIZE 16 #endif + #ifndef CFG_TUD_BTH_DATA_EPSIZE #define CFG_TUD_BTH_DATA_EPSIZE 64 #endif +// Allow BTH class to work in historically compatibility mode where the bRequest is always 0xe0. +// See Bluetooth Core v5.3, Vol. 4, Part B, Section 2.2 +#ifndef CFG_TUD_BTH_HISTORICAL_COMPATIBLE +#define CFG_TUD_BTH_HISTORICAL_COMPATIBLE 0 +#endif + typedef struct TU_ATTR_PACKED { uint16_t op_code; @@ -97,6 +104,7 @@ bool tud_bt_acl_data_send(void *acl_data, uint16_t data_len); // Internal Class Driver API //--------------------------------------------------------------------+ void btd_init (void); +bool btd_deinit (void); void btd_reset (uint8_t rhport); uint16_t btd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool btd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const *request); diff --git a/src/class/cdc/cdc.h b/src/class/cdc/cdc.h index 4658e43af..5cbd658fe 100644 --- a/src/class/cdc/cdc.h +++ b/src/class/cdc/cdc.h @@ -136,8 +136,7 @@ typedef enum{ //--------------------------------------------------------------------+ /// Communication Interface Management Element Request Codes -typedef enum -{ +typedef enum { CDC_REQUEST_SEND_ENCAPSULATED_COMMAND = 0x00, ///< is used to issue a command in the format of the supported control protocol of the Communications Class interface CDC_REQUEST_GET_ENCAPSULATED_RESPONSE = 0x01, ///< is used to request a response in the format of the supported control protocol of the Communications Class interface. CDC_REQUEST_SET_COMM_FEATURE = 0x02, @@ -180,37 +179,38 @@ typedef enum CDC_REQUEST_GET_ATM_VC_STATISTICS = 0x53, CDC_REQUEST_MDLM_SEMANTIC_MODEL = 0x60, -}cdc_management_request_t; +} cdc_management_request_t; -enum -{ +typedef enum { CDC_CONTROL_LINE_STATE_DTR = 0x01, CDC_CONTROL_LINE_STATE_RTS = 0x02, -}; +} cdc_control_line_state_t; -enum -{ - CDC_LINE_CONDING_STOP_BITS_1 = 0, // 1 bit - CDC_LINE_CONDING_STOP_BITS_1_5 = 1, // 1.5 bits - CDC_LINE_CONDING_STOP_BITS_2 = 2, // 2 bits -}; +typedef enum { + CDC_LINE_CODING_STOP_BITS_1 = 0, // 1 bit + CDC_LINE_CODING_STOP_BITS_1_5 = 1, // 1.5 bits + CDC_LINE_CODING_STOP_BITS_2 = 2, // 2 bits +} cdc_line_coding_stopbits_t; -enum -{ +// TODO Backward compatible for typos. Maybe removed in the future release +#define CDC_LINE_CONDING_STOP_BITS_1 CDC_LINE_CODING_STOP_BITS_1 +#define CDC_LINE_CONDING_STOP_BITS_1_5 CDC_LINE_CODING_STOP_BITS_1_5 +#define CDC_LINE_CONDING_STOP_BITS_2 CDC_LINE_CODING_STOP_BITS_2 + +typedef enum { CDC_LINE_CODING_PARITY_NONE = 0, CDC_LINE_CODING_PARITY_ODD = 1, CDC_LINE_CODING_PARITY_EVEN = 2, CDC_LINE_CODING_PARITY_MARK = 3, CDC_LINE_CODING_PARITY_SPACE = 4, -}; +} cdc_line_coding_parity_t; //--------------------------------------------------------------------+ // Management Element Notification (Notification Endpoint) //--------------------------------------------------------------------+ /// 6.3 Notification Codes -typedef enum -{ +typedef enum { CDC_NOTIF_NETWORK_CONNECTION = 0x00, ///< This notification allows the device to notify the host about network connection status. CDC_NOTIF_RESPONSE_AVAILABLE = 0x01, ///< This notification allows the device to notify the hostthat a response is available. This response can be retrieved with a subsequent \ref CDC_REQUEST_GET_ENCAPSULATED_RESPONSE request. CDC_NOTIF_AUX_JACK_HOOK_STATE = 0x08, diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 70d9c2e24..f36725eba 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -43,10 +43,7 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ -enum -{ - BULK_PACKET_SIZE = (TUD_OPT_HIGH_SPEED ? 512 : 64) -}; +#define BULK_PACKET_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) typedef struct { @@ -150,7 +147,7 @@ uint32_t tud_cdc_n_available(uint8_t itf) uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - uint32_t num_read = tu_fifo_read_n(&p_cdc->rx_ff, buffer, (uint16_t) bufsize); + uint32_t num_read = tu_fifo_read_n(&p_cdc->rx_ff, buffer, (uint16_t) TU_MIN(bufsize, UINT16_MAX)); _prep_out_transaction(p_cdc); return num_read; } @@ -173,12 +170,14 @@ void tud_cdc_n_read_flush (uint8_t itf) uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - uint16_t ret = tu_fifo_write_n(&p_cdc->tx_ff, buffer, (uint16_t) bufsize); + uint16_t ret = tu_fifo_write_n(&p_cdc->tx_ff, buffer, (uint16_t) TU_MIN(bufsize, UINT16_MAX)); // flush if queue more than packet size - // may need to suppress -Wunreachable-code since most of the time CFG_TUD_CDC_TX_BUFSIZE < BULK_PACKET_SIZE - if ( (tu_fifo_count(&p_cdc->tx_ff) >= BULK_PACKET_SIZE) || ((CFG_TUD_CDC_TX_BUFSIZE < BULK_PACKET_SIZE) && tu_fifo_full(&p_cdc->tx_ff)) ) - { + if ( tu_fifo_count(&p_cdc->tx_ff) >= BULK_PACKET_SIZE + #if CFG_TUD_CDC_TX_BUFSIZE < BULK_PACKET_SIZE + || tu_fifo_full(&p_cdc->tx_ff) // check full if fifo size is less than packet size + #endif + ) { tud_cdc_n_write_flush(itf); } @@ -253,11 +252,39 @@ void cdcd_init(void) // In this way, the most current data is prioritized. tu_fifo_config(&p_cdc->tx_ff, p_cdc->tx_ff_buf, TU_ARRAY_SIZE(p_cdc->tx_ff_buf), 1, true); - tu_fifo_config_mutex(&p_cdc->rx_ff, NULL, osal_mutex_create(&p_cdc->rx_ff_mutex)); - tu_fifo_config_mutex(&p_cdc->tx_ff, osal_mutex_create(&p_cdc->tx_ff_mutex), NULL); + #if OSAL_MUTEX_REQUIRED + osal_mutex_t mutex_rd = osal_mutex_create(&p_cdc->rx_ff_mutex); + osal_mutex_t mutex_wr = osal_mutex_create(&p_cdc->tx_ff_mutex); + TU_ASSERT(mutex_rd != NULL && mutex_wr != NULL, ); + + tu_fifo_config_mutex(&p_cdc->rx_ff, NULL, mutex_rd); + tu_fifo_config_mutex(&p_cdc->tx_ff, mutex_wr, NULL); + #endif } } +bool cdcd_deinit(void) { + #if OSAL_MUTEX_REQUIRED + for(uint8_t i=0; irx_ff.mutex_rd; + osal_mutex_t mutex_wr = p_cdc->tx_ff.mutex_wr; + + if (mutex_rd) { + osal_mutex_delete(mutex_rd); + tu_fifo_config_mutex(&p_cdc->rx_ff, NULL, NULL); + } + + if (mutex_wr) { + osal_mutex_delete(mutex_wr); + tu_fifo_config_mutex(&p_cdc->tx_ff, NULL, NULL); + } + } + #endif + + return true; +} + void cdcd_reset(uint8_t rhport) { (void) rhport; @@ -268,7 +295,9 @@ void cdcd_reset(uint8_t rhport) tu_memclr(p_cdc, ITF_MEM_RESET_SIZE); tu_fifo_clear(&p_cdc->rx_ff); + #if !CFG_TUD_CDC_PERSISTENT_TX_BUFF tu_fifo_clear(&p_cdc->tx_ff); + #endif tu_fifo_set_overwritable(&p_cdc->tx_ff, true); } } diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index a6e07aa5c..db709b3bc 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -41,6 +41,12 @@ #define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #endif +// By default the TX fifo buffer is cleared on connect / bus reset. +// Enable this to persist any data in the fifo instead. +#ifndef CFG_TUD_CDC_PERSISTENT_TX_BUFF + #define CFG_TUD_CDC_PERSISTENT_TX_BUFF (0) +#endif + #ifdef __cplusplus extern "C" { #endif @@ -247,6 +253,7 @@ static inline bool tud_cdc_write_clear(void) // INTERNAL USBD-CLASS DRIVER API //--------------------------------------------------------------------+ void cdcd_init (void); +bool cdcd_deinit (void); void cdcd_reset (uint8_t rhport); uint16_t cdcd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool cdcd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 40ebd331d..133a10f6e 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -22,6 +22,9 @@ * THE SOFTWARE. * * This file is part of the TinyUSB stack. + * + * Contribution + * - Heiko Kuester: CH34x support */ #include "tusb_option.h" @@ -29,7 +32,7 @@ #if (CFG_TUH_ENABLED && CFG_TUH_CDC) #include "host/usbh.h" -#include "host/usbh_classdriver.h" +#include "host/usbh_pvt.h" #include "cdc_host.h" @@ -50,12 +53,18 @@ typedef struct { uint8_t bInterfaceSubClass; uint8_t bInterfaceProtocol; - uint8_t serial_drid; // Serial Driver ID - cdc_acm_capability_t acm_capability; uint8_t ep_notif; + uint8_t serial_drid; // Serial Driver ID + bool mounted; // Enumeration is complete + cdc_acm_capability_t acm_capability; - uint8_t line_state; // DTR (bit0), RTS (bit1) TU_ATTR_ALIGNED(4) cdc_line_coding_t line_coding; // Baudrate, stop bits, parity, data width + uint8_t line_state; // DTR (bit0), RTS (bit1) + + #if CFG_TUH_CDC_FTDI || CFG_TUH_CDC_CP210X || CFG_TUH_CDC_CH34X + cdc_line_coding_t requested_line_coding; + // 1 byte padding + #endif tuh_xfer_cb_t user_control_cb; @@ -69,7 +78,6 @@ typedef struct { uint8_t rx_ff_buf[CFG_TUH_CDC_TX_BUFSIZE]; CFG_TUH_MEM_ALIGN uint8_t rx_ep_buf[CFG_TUH_CDC_TX_EPSIZE]; } stream; - } cdch_interface_t; CFG_TUH_MEM_SECTION @@ -80,47 +88,60 @@ static cdch_interface_t cdch_data[CFG_TUH_CDC]; //--------------------------------------------------------------------+ //------------- ACM prototypes -------------// +static bool acm_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); static void acm_process_config(tuh_xfer_t* xfer); +static bool acm_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool acm_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool acm_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool acm_set_control_line_state(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); -static bool acm_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); //------------- FTDI prototypes -------------// #if CFG_TUH_CDC_FTDI #include "serial/ftdi_sio.h" -static uint16_t const ftdi_pids[] = { TU_FTDI_PID_LIST }; -enum { - FTDI_PID_COUNT = sizeof(ftdi_pids) / sizeof(ftdi_pids[0]) -}; - -// Store last request baudrate since divisor to baudrate is not easy -static uint32_t _ftdi_requested_baud; +static uint16_t const ftdi_vid_pid_list[][2] = {CFG_TUH_CDC_FTDI_VID_PID_LIST}; static bool ftdi_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len); static void ftdi_process_config(tuh_xfer_t* xfer); -static bool ftdi_sio_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool ftdi_sio_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool ftdi_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool ftdi_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool ftdi_sio_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); #endif //------------- CP210X prototypes -------------// #if CFG_TUH_CDC_CP210X #include "serial/cp210x.h" -static uint16_t const cp210x_pids[] = { TU_CP210X_PID_LIST }; -enum { - CP210X_PID_COUNT = sizeof(cp210x_pids) / sizeof(cp210x_pids[0]) -}; +static uint16_t const cp210x_vid_pid_list[][2] = {CFG_TUH_CDC_CP210X_VID_PID_LIST}; static bool cp210x_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); static void cp210x_process_config(tuh_xfer_t* xfer); -static bool cp210x_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); static bool cp210x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool cp210x_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool cp210x_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool cp210x_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); #endif +//------------- CH34x prototypes -------------// +#if CFG_TUH_CDC_CH34X +#include "serial/ch34x.h" + +static uint16_t const ch34x_vid_pid_list[][2] = {CFG_TUH_CDC_CH34X_VID_PID_LIST}; + +static bool ch34x_open(uint8_t daddr, tusb_desc_interface_t const* itf_desc, uint16_t max_len); +static void ch34x_process_config(tuh_xfer_t* xfer); + +static bool ch34x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool ch34x_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool ch34x_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +static bool ch34x_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +#endif + +//------------- Common -------------// enum { SERIAL_DRIVER_ACM = 0, @@ -131,60 +152,96 @@ enum { #if CFG_TUH_CDC_CP210X SERIAL_DRIVER_CP210X, #endif + +#if CFG_TUH_CDC_CH34X + SERIAL_DRIVER_CH34X, +#endif + + SERIAL_DRIVER_COUNT }; typedef struct { + uint16_t const (*vid_pid_list)[2]; + uint16_t const vid_pid_count; + bool (*const open)(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len); void (*const process_set_config)(tuh_xfer_t* xfer); bool (*const set_control_line_state)(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data); bool (*const set_baudrate)(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); + bool (*const set_data_format)(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, tuh_xfer_cb_t complete_cb, uintptr_t user_data); + bool (*const set_line_coding)(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data); } cdch_serial_driver_t; // Note driver list must be in the same order as SERIAL_DRIVER enum static const cdch_serial_driver_t serial_drivers[] = { - { .process_set_config = acm_process_config, - .set_control_line_state = acm_set_control_line_state, - .set_baudrate = acm_set_baudrate + { + .vid_pid_list = NULL, + .vid_pid_count = 0, + .open = acm_open, + .process_set_config = acm_process_config, + .set_control_line_state = acm_set_control_line_state, + .set_baudrate = acm_set_baudrate, + .set_data_format = acm_set_data_format, + .set_line_coding = acm_set_line_coding }, #if CFG_TUH_CDC_FTDI - { .process_set_config = ftdi_process_config, - .set_control_line_state = ftdi_sio_set_modem_ctrl, - .set_baudrate = ftdi_sio_set_baudrate + { + .vid_pid_list = ftdi_vid_pid_list, + .vid_pid_count = TU_ARRAY_SIZE(ftdi_vid_pid_list), + .open = ftdi_open, + .process_set_config = ftdi_process_config, + .set_control_line_state = ftdi_sio_set_modem_ctrl, + .set_baudrate = ftdi_sio_set_baudrate, + .set_data_format = ftdi_set_data_format, + .set_line_coding = ftdi_set_line_coding }, #endif #if CFG_TUH_CDC_CP210X - { .process_set_config = cp210x_process_config, - .set_control_line_state = cp210x_set_modem_ctrl, - .set_baudrate = cp210x_set_baudrate + { + .vid_pid_list = cp210x_vid_pid_list, + .vid_pid_count = TU_ARRAY_SIZE(cp210x_vid_pid_list), + .open = cp210x_open, + .process_set_config = cp210x_process_config, + .set_control_line_state = cp210x_set_modem_ctrl, + .set_baudrate = cp210x_set_baudrate, + .set_data_format = cp210x_set_data_format, + .set_line_coding = cp210x_set_line_coding + }, + #endif + + #if CFG_TUH_CDC_CH34X + { + .vid_pid_list = ch34x_vid_pid_list, + .vid_pid_count = TU_ARRAY_SIZE(ch34x_vid_pid_list), + .open = ch34x_open, + .process_set_config = ch34x_process_config, + .set_control_line_state = ch34x_set_modem_ctrl, + .set_baudrate = ch34x_set_baudrate, + .set_data_format = ch34x_set_data_format, + .set_line_coding = ch34x_set_line_coding }, #endif }; -enum { - SERIAL_DRIVER_COUNT = sizeof(serial_drivers) / sizeof(serial_drivers[0]) -}; +TU_VERIFY_STATIC(TU_ARRAY_SIZE(serial_drivers) == SERIAL_DRIVER_COUNT, "Serial driver count mismatch"); //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ -static inline cdch_interface_t* get_itf(uint8_t idx) -{ +static inline cdch_interface_t* get_itf(uint8_t idx) { TU_ASSERT(idx < CFG_TUH_CDC, NULL); cdch_interface_t* p_cdc = &cdch_data[idx]; return (p_cdc->daddr != 0) ? p_cdc : NULL; } -static inline uint8_t get_idx_by_ep_addr(uint8_t daddr, uint8_t ep_addr) -{ - for(uint8_t i=0; idaddr == daddr) && - (ep_addr == p_cdc->ep_notif || ep_addr == p_cdc->stream.rx.ep_addr || ep_addr == p_cdc->stream.tx.ep_addr)) - { + (ep_addr == p_cdc->ep_notif || ep_addr == p_cdc->stream.rx.ep_addr || ep_addr == p_cdc->stream.tx.ep_addr)) { return i; } } @@ -192,14 +249,10 @@ static inline uint8_t get_idx_by_ep_addr(uint8_t daddr, uint8_t ep_addr) return TUSB_INDEX_INVALID_8; } - -static cdch_interface_t* make_new_itf(uint8_t daddr, tusb_desc_interface_t const *itf_desc) -{ - for(uint8_t i=0; idaddr = daddr; p_cdc->bInterfaceNumber = itf_desc->bInterfaceNumber; p_cdc->bInterfaceSubClass = itf_desc->bInterfaceSubClass; @@ -220,20 +273,16 @@ static void cdch_internal_control_complete(tuh_xfer_t* xfer); // APPLICATION API //--------------------------------------------------------------------+ -uint8_t tuh_cdc_itf_get_index(uint8_t daddr, uint8_t itf_num) -{ - for(uint8_t i=0; idaddr == daddr && p_cdc->bInterfaceNumber == itf_num) return i; } return TUSB_INDEX_INVALID_8; } -bool tuh_cdc_itf_get_info(uint8_t idx, tuh_itf_info_t* info) -{ +bool tuh_cdc_itf_get_info(uint8_t idx, tuh_itf_info_t* info) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc && info); @@ -255,30 +304,27 @@ bool tuh_cdc_itf_get_info(uint8_t idx, tuh_itf_info_t* info) return true; } -bool tuh_cdc_mounted(uint8_t idx) -{ +bool tuh_cdc_mounted(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); - return p_cdc != NULL; + TU_VERIFY(p_cdc); + return p_cdc->mounted; } -bool tuh_cdc_get_dtr(uint8_t idx) -{ +bool tuh_cdc_get_dtr(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); return (p_cdc->line_state & CDC_CONTROL_LINE_STATE_DTR) ? true : false; } -bool tuh_cdc_get_rts(uint8_t idx) -{ +bool tuh_cdc_get_rts(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); return (p_cdc->line_state & CDC_CONTROL_LINE_STATE_RTS) ? true : false; } -bool tuh_cdc_get_local_line_coding(uint8_t idx, cdc_line_coding_t* line_coding) -{ +bool tuh_cdc_get_local_line_coding(uint8_t idx, cdc_line_coding_t* line_coding) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); @@ -291,32 +337,28 @@ bool tuh_cdc_get_local_line_coding(uint8_t idx, cdc_line_coding_t* line_coding) // Write //--------------------------------------------------------------------+ -uint32_t tuh_cdc_write(uint8_t idx, void const* buffer, uint32_t bufsize) -{ +uint32_t tuh_cdc_write(uint8_t idx, void const* buffer, uint32_t bufsize) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); return tu_edpt_stream_write(&p_cdc->stream.tx, buffer, bufsize); } -uint32_t tuh_cdc_write_flush(uint8_t idx) -{ +uint32_t tuh_cdc_write_flush(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); return tu_edpt_stream_write_xfer(&p_cdc->stream.tx); } -bool tuh_cdc_write_clear(uint8_t idx) -{ +bool tuh_cdc_write_clear(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); return tu_edpt_stream_clear(&p_cdc->stream.tx); } -uint32_t tuh_cdc_write_available(uint8_t idx) -{ +uint32_t tuh_cdc_write_available(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); @@ -327,32 +369,28 @@ uint32_t tuh_cdc_write_available(uint8_t idx) // Read //--------------------------------------------------------------------+ -uint32_t tuh_cdc_read (uint8_t idx, void* buffer, uint32_t bufsize) -{ +uint32_t tuh_cdc_read (uint8_t idx, void* buffer, uint32_t bufsize) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); return tu_edpt_stream_read(&p_cdc->stream.rx, buffer, bufsize); } -uint32_t tuh_cdc_read_available(uint8_t idx) -{ +uint32_t tuh_cdc_read_available(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); return tu_edpt_stream_read_available(&p_cdc->stream.rx); } -bool tuh_cdc_peek(uint8_t idx, uint8_t* ch) -{ +bool tuh_cdc_peek(uint8_t idx, uint8_t* ch) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); return tu_edpt_stream_peek(&p_cdc->stream.rx, ch); } -bool tuh_cdc_read_clear (uint8_t idx) -{ +bool tuh_cdc_read_clear (uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); @@ -365,28 +403,25 @@ bool tuh_cdc_read_clear (uint8_t idx) // Control Endpoint API //--------------------------------------------------------------------+ -// internal control complete to update state such as line state, encoding -static void cdch_internal_control_complete(tuh_xfer_t* xfer) -{ - uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); +static void process_internal_control_complete(tuh_xfer_t* xfer, uint8_t itf_num) { uint8_t idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num); cdch_interface_t* p_cdc = get_itf(idx); TU_ASSERT(p_cdc, ); + uint16_t const value = tu_le16toh(xfer->setup->wValue); - if (xfer->result == XFER_RESULT_SUCCESS) - { + if (xfer->result == XFER_RESULT_SUCCESS) { switch (p_cdc->serial_drid) { case SERIAL_DRIVER_ACM: switch (xfer->setup->bRequest) { case CDC_REQUEST_SET_CONTROL_LINE_STATE: - p_cdc->line_state = (uint8_t) tu_le16toh(xfer->setup->wValue); + p_cdc->line_state = (uint8_t) value; break; case CDC_REQUEST_SET_LINE_CODING: { uint16_t const len = tu_min16(sizeof(cdc_line_coding_t), tu_le16toh(xfer->setup->wLength)); memcpy(&p_cdc->line_coding, xfer->buffer, len); - } break; + } default: break; } @@ -396,12 +431,11 @@ static void cdch_internal_control_complete(tuh_xfer_t* xfer) case SERIAL_DRIVER_FTDI: switch (xfer->setup->bRequest) { case FTDI_SIO_MODEM_CTRL: - p_cdc->line_state = (uint8_t) (tu_le16toh(xfer->setup->wValue) & 0x00ff); + p_cdc->line_state = (uint8_t) value; break; case FTDI_SIO_SET_BAUD_RATE: - // convert from divisor to baudrate is not supported - p_cdc->line_coding.bit_rate = _ftdi_requested_baud; + p_cdc->line_coding.bit_rate = p_cdc->requested_line_coding.bit_rate; break; default: break; @@ -413,15 +447,61 @@ static void cdch_internal_control_complete(tuh_xfer_t* xfer) case SERIAL_DRIVER_CP210X: switch(xfer->setup->bRequest) { case CP210X_SET_MHS: - p_cdc->line_state = (uint8_t) (tu_le16toh(xfer->setup->wValue) & 0x00ff); + p_cdc->line_state = (uint8_t) value; break; case CP210X_SET_BAUDRATE: { uint32_t baudrate; memcpy(&baudrate, xfer->buffer, sizeof(uint32_t)); p_cdc->line_coding.bit_rate = tu_le32toh(baudrate); - } break; + } + + default: break; + } + break; + #endif + + #if CFG_TUH_CDC_CH34X + case SERIAL_DRIVER_CH34X: + switch (xfer->setup->bRequest) { + case CH34X_REQ_WRITE_REG: + // register write request + switch (value) { + case CH34X_REG16_DIVISOR_PRESCALER: + // baudrate + p_cdc->line_coding.bit_rate = p_cdc->requested_line_coding.bit_rate; + break; + + case CH32X_REG16_LCR2_LCR: + // data format + p_cdc->line_coding.stop_bits = p_cdc->requested_line_coding.stop_bits; + p_cdc->line_coding.parity = p_cdc->requested_line_coding.parity; + p_cdc->line_coding.data_bits = p_cdc->requested_line_coding.data_bits; + break; + + default: break; + } + break; + + case CH34X_REQ_MODEM_CTRL: { + // set modem controls RTS/DTR request. Note: signals are inverted + uint16_t const modem_signal = ~value; + if (modem_signal & CH34X_BIT_RTS) { + p_cdc->line_state |= CDC_CONTROL_LINE_STATE_RTS; + } else { + p_cdc->line_state &= (uint8_t) ~CDC_CONTROL_LINE_STATE_RTS; + } + + if (modem_signal & CH34X_BIT_DTR) { + p_cdc->line_state |= CDC_CONTROL_LINE_STATE_DTR; + } else { + p_cdc->line_state &= (uint8_t) ~CDC_CONTROL_LINE_STATE_DTR; + } + break; + } + + default: break; } break; #endif @@ -436,14 +516,20 @@ static void cdch_internal_control_complete(tuh_xfer_t* xfer) } } +// internal control complete to update state such as line state, encoding +static void cdch_internal_control_complete(tuh_xfer_t* xfer) { + uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); + process_internal_control_complete(xfer, itf_num); +} + bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT); cdch_serial_driver_t const* driver = &serial_drivers[p_cdc->serial_drid]; - if ( complete_cb ) { + if (complete_cb) { return driver->set_control_line_state(p_cdc, line_state, complete_cb, user_data); - }else { + } else { // blocking xfer_result_t result = XFER_RESULT_INVALID; bool ret = driver->set_control_line_state(p_cdc, line_state, complete_cb, (uintptr_t) &result); @@ -454,7 +540,6 @@ bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_c } TU_VERIFY(ret && result == XFER_RESULT_SUCCESS); - p_cdc->line_state = (uint8_t) line_state; return true; } @@ -465,9 +550,9 @@ bool tuh_cdc_set_baudrate(uint8_t idx, uint32_t baudrate, tuh_xfer_cb_t complete TU_VERIFY(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT); cdch_serial_driver_t const* driver = &serial_drivers[p_cdc->serial_drid]; - if ( complete_cb ) { + if (complete_cb) { return driver->set_baudrate(p_cdc, baudrate, complete_cb, user_data); - }else { + } else { // blocking xfer_result_t result = XFER_RESULT_INVALID; bool ret = driver->set_baudrate(p_cdc, baudrate, complete_cb, (uintptr_t) &result); @@ -478,25 +563,23 @@ bool tuh_cdc_set_baudrate(uint8_t idx, uint32_t baudrate, tuh_xfer_cb_t complete } TU_VERIFY(ret && result == XFER_RESULT_SUCCESS); - p_cdc->line_coding.bit_rate = baudrate; return true; } } -bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +bool tuh_cdc_set_data_format(uint8_t idx, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { cdch_interface_t* p_cdc = get_itf(idx); - // only ACM support this set line coding request - TU_VERIFY(p_cdc && p_cdc->serial_drid == SERIAL_DRIVER_ACM); - TU_VERIFY(p_cdc->acm_capability.support_line_request); + TU_VERIFY(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT); + cdch_serial_driver_t const* driver = &serial_drivers[p_cdc->serial_drid]; - if ( complete_cb ) { - return acm_set_line_coding(p_cdc, line_coding, complete_cb, user_data); - }else { + if (complete_cb) { + return driver->set_data_format(p_cdc, stop_bits, parity, data_bits, complete_cb, user_data); + } else { // blocking xfer_result_t result = XFER_RESULT_INVALID; - bool ret = acm_set_line_coding(p_cdc, line_coding, complete_cb, (uintptr_t) &result); + bool ret = driver->set_data_format(p_cdc, stop_bits, parity, data_bits, complete_cb, (uintptr_t) &result); if (user_data) { // user_data is not NULL, return result via user_data @@ -504,7 +587,31 @@ bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, } TU_VERIFY(ret && result == XFER_RESULT_SUCCESS); + p_cdc->line_coding.stop_bits = stop_bits; + p_cdc->line_coding.parity = parity; + p_cdc->line_coding.data_bits = data_bits; + return true; + } +} +bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + cdch_interface_t* p_cdc = get_itf(idx); + TU_VERIFY(p_cdc && p_cdc->serial_drid < SERIAL_DRIVER_COUNT); + cdch_serial_driver_t const* driver = &serial_drivers[p_cdc->serial_drid]; + + if ( complete_cb ) { + return driver->set_line_coding(p_cdc, line_coding, complete_cb, user_data); + } else { + // blocking + xfer_result_t result = XFER_RESULT_INVALID; + bool ret = driver->set_line_coding(p_cdc, line_coding, complete_cb, (uintptr_t) &result); + + if (user_data) { + // user_data is not NULL, return result via user_data + *((xfer_result_t*) user_data) = result; + } + + TU_VERIFY(ret && result == XFER_RESULT_SUCCESS); p_cdc->line_coding = *line_coding; return true; } @@ -514,39 +621,44 @@ bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, // CLASS-USBH API //--------------------------------------------------------------------+ -void cdch_init(void) -{ +bool cdch_init(void) { + TU_LOG_DRV("sizeof(cdch_interface_t) = %u\r\n", sizeof(cdch_interface_t)); tu_memclr(cdch_data, sizeof(cdch_data)); - - for(size_t i=0; istream.tx, true, true, false, - p_cdc->stream.tx_ff_buf, CFG_TUH_CDC_TX_BUFSIZE, - p_cdc->stream.tx_ep_buf, CFG_TUH_CDC_TX_EPSIZE); + p_cdc->stream.tx_ff_buf, CFG_TUH_CDC_TX_BUFSIZE, + p_cdc->stream.tx_ep_buf, CFG_TUH_CDC_TX_EPSIZE); tu_edpt_stream_init(&p_cdc->stream.rx, true, false, false, - p_cdc->stream.rx_ff_buf, CFG_TUH_CDC_RX_BUFSIZE, - p_cdc->stream.rx_ep_buf, CFG_TUH_CDC_RX_EPSIZE); + p_cdc->stream.rx_ff_buf, CFG_TUH_CDC_RX_BUFSIZE, + p_cdc->stream.rx_ep_buf, CFG_TUH_CDC_RX_EPSIZE); } + + return true; } -void cdch_close(uint8_t daddr) -{ - for(uint8_t idx=0; idxstream.tx); + tu_edpt_stream_deinit(&p_cdc->stream.rx); + } + return true; +} + +void cdch_close(uint8_t daddr) { + for (uint8_t idx = 0; idx < CFG_TUH_CDC; idx++) { cdch_interface_t* p_cdc = &cdch_data[idx]; - if (p_cdc->daddr == daddr) - { + if (p_cdc->daddr == daddr) { TU_LOG_DRV(" CDCh close addr = %u index = %u\r\n", daddr, idx); // Invoke application callback if (tuh_cdc_umount_cb) tuh_cdc_umount_cb(idx); - //tu_memclr(p_cdc, sizeof(cdch_interface_t)); p_cdc->daddr = 0; p_cdc->bInterfaceNumber = 0; + p_cdc->mounted = false; tu_edpt_stream_close(&p_cdc->stream.tx); tu_edpt_stream_close(&p_cdc->stream.rx); } @@ -570,16 +682,11 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t // - xferred_bytes is multiple of EP Packet size and not zero tu_edpt_stream_write_zlp_if_needed(&p_cdc->stream.tx, xferred_bytes); } - } - else if ( ep_addr == p_cdc->stream.rx.ep_addr ) { + } else if ( ep_addr == p_cdc->stream.rx.ep_addr ) { #if CFG_TUH_CDC_FTDI if (p_cdc->serial_drid == SERIAL_DRIVER_FTDI) { // FTDI reserve 2 bytes for status - // FTDI status -// uint8_t status[2] = { -// p_cdc->stream.rx.ep_buf[0], -// p_cdc->stream.rx.ep_buf[1] -// }; + // uint8_t status[2] = {p_cdc->stream.rx.ep_buf[0], p_cdc->stream.rx.ep_buf[1]}; tu_edpt_stream_read_xfer_complete_offset(&p_cdc->stream.rx, xferred_bytes, 2); }else #endif @@ -605,22 +712,15 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t // Enumeration //--------------------------------------------------------------------+ -static bool acm_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); - -static bool open_ep_stream_pair(cdch_interface_t* p_cdc, tusb_desc_endpoint_t const *desc_ep) -{ - for(size_t i=0; i<2; i++) - { +static bool open_ep_stream_pair(cdch_interface_t* p_cdc, tusb_desc_endpoint_t const* desc_ep) { + for (size_t i = 0; i < 2; i++) { TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && - TUSB_XFER_BULK == desc_ep->bmAttributes.xfer); - + TUSB_XFER_BULK == desc_ep->bmAttributes.xfer); TU_ASSERT(tuh_edpt_open(p_cdc->daddr, desc_ep)); - if ( tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN ) - { + if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { tu_edpt_stream_open(&p_cdc->stream.rx, p_cdc->daddr, desc_ep); - }else - { + } else { tu_edpt_stream_open(&p_cdc->stream.tx, p_cdc->daddr, desc_ep); } @@ -630,49 +730,36 @@ static bool open_ep_stream_pair(cdch_interface_t* p_cdc, tusb_desc_endpoint_t co return true; } -bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) -{ +bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { (void) rhport; - // Only support ACM subclass + // For CDC: only support ACM subclass // Note: Protocol 0xFF can be RNDIS device - if ( TUSB_CLASS_CDC == itf_desc->bInterfaceClass && - CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass) - { + if (TUSB_CLASS_CDC == itf_desc->bInterfaceClass && + CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass) { return acm_open(daddr, itf_desc, max_len); } - #if CFG_TUH_CDC_FTDI || CFG_TUH_CDC_CP210X - else if ( 0xff == itf_desc->bInterfaceClass ) - { + else if (SERIAL_DRIVER_COUNT > 1 && + TUSB_CLASS_VENDOR_SPECIFIC == itf_desc->bInterfaceClass) { uint16_t vid, pid; TU_VERIFY(tuh_vid_pid_get(daddr, &vid, &pid)); - #if CFG_TUH_CDC_FTDI - if (TU_FTDI_VID == vid) { - for (size_t i = 0; i < FTDI_PID_COUNT; i++) { - if (ftdi_pids[i] == pid) { - return ftdi_open(daddr, itf_desc, max_len); + for (size_t dr = 1; dr < SERIAL_DRIVER_COUNT; dr++) { + cdch_serial_driver_t const* driver = &serial_drivers[dr]; + for (size_t i = 0; i < driver->vid_pid_count; i++) { + if (driver->vid_pid_list[i][0] == vid && driver->vid_pid_list[i][1] == pid) { + return driver->open(daddr, itf_desc, max_len); } } } - #endif - - #if CFG_TUH_CDC_CP210X - if (TU_CP210X_VID == vid) { - for (size_t i = 0; i < CP210X_PID_COUNT; i++) { - if (cp210x_pids[i] == pid) { - return cp210x_open(daddr, itf_desc, max_len); - } - } - } - #endif } - #endif return false; } static void set_config_complete(cdch_interface_t * p_cdc, uint8_t idx, uint8_t itf_num) { + TU_LOG_DRV("CDCh Set Configure complete\r\n"); + p_cdc->mounted = true; if (tuh_cdc_mount_cb) tuh_cdc_mount_cb(idx); // Prepare for incoming data @@ -682,9 +769,7 @@ static void set_config_complete(cdch_interface_t * p_cdc, uint8_t idx, uint8_t i usbh_driver_set_config_complete(p_cdc->daddr, itf_num); } - -bool cdch_set_config(uint8_t daddr, uint8_t itf_num) -{ +bool cdch_set_config(uint8_t daddr, uint8_t itf_num) { tusb_control_request_t request; request.wIndex = tu_htole16((uint16_t) itf_num); @@ -713,94 +798,84 @@ enum { CONFIG_ACM_COMPLETE, }; -static bool acm_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) -{ - uint8_t const * p_desc_end = ((uint8_t const*) itf_desc) + max_len; +static bool acm_open(uint8_t daddr, tusb_desc_interface_t const* itf_desc, uint16_t max_len) { + uint8_t const* p_desc_end = ((uint8_t const*) itf_desc) + max_len; - cdch_interface_t * p_cdc = make_new_itf(daddr, itf_desc); + cdch_interface_t* p_cdc = make_new_itf(daddr, itf_desc); TU_VERIFY(p_cdc); - p_cdc->serial_drid = SERIAL_DRIVER_ACM; //------------- Control Interface -------------// - uint8_t const * p_desc = tu_desc_next(itf_desc); + uint8_t const* p_desc = tu_desc_next(itf_desc); // Communication Functional Descriptors - while( (p_desc < p_desc_end) && (TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc)) ) - { - if ( CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT == cdc_functional_desc_typeof(p_desc) ) - { + while ((p_desc < p_desc_end) && (TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc))) { + if (CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT == cdc_functional_desc_typeof(p_desc)) { // save ACM bmCapabilities - p_cdc->acm_capability = ((cdc_desc_func_acm_t const *) p_desc)->bmCapabilities; + p_cdc->acm_capability = ((cdc_desc_func_acm_t const*) p_desc)->bmCapabilities; } p_desc = tu_desc_next(p_desc); } // Open notification endpoint of control interface if any - if (itf_desc->bNumEndpoints == 1) - { + if (itf_desc->bNumEndpoints == 1) { TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)); - tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc; + tusb_desc_endpoint_t const* desc_ep = (tusb_desc_endpoint_t const*) p_desc; - TU_ASSERT( tuh_edpt_open(daddr, desc_ep) ); + TU_ASSERT(tuh_edpt_open(daddr, desc_ep)); p_cdc->ep_notif = desc_ep->bEndpointAddress; p_desc = tu_desc_next(p_desc); } //------------- Data Interface (if any) -------------// - if ( (TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) && - (TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass) ) - { + if ((TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) && + (TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const*) p_desc)->bInterfaceClass)) { // next to endpoint descriptor p_desc = tu_desc_next(p_desc); // data endpoints expected to be in pairs - TU_ASSERT(open_ep_stream_pair(p_cdc, (tusb_desc_endpoint_t const *) p_desc)); + TU_ASSERT(open_ep_stream_pair(p_cdc, (tusb_desc_endpoint_t const*) p_desc)); } return true; } -static void acm_process_config(tuh_xfer_t* xfer) -{ +static void acm_process_config(tuh_xfer_t* xfer) { uintptr_t const state = xfer->user_data; uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); uint8_t const idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num); - cdch_interface_t * p_cdc = get_itf(idx); - TU_ASSERT(p_cdc, ); + cdch_interface_t* p_cdc = get_itf(idx); + TU_ASSERT(p_cdc,); - switch(state) - { + switch (state) { case CONFIG_ACM_SET_CONTROL_LINE_STATE: #if CFG_TUH_CDC_LINE_CONTROL_ON_ENUM - if (p_cdc->acm_capability.support_line_request) - { - TU_ASSERT(acm_set_control_line_state(p_cdc, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, acm_process_config, - CONFIG_ACM_SET_LINE_CODING), ); + if (p_cdc->acm_capability.support_line_request) { + TU_ASSERT(acm_set_control_line_state(p_cdc, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, acm_process_config, CONFIG_ACM_SET_LINE_CODING),); break; } - #endif + #endif TU_ATTR_FALLTHROUGH; case CONFIG_ACM_SET_LINE_CODING: - #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM - if (p_cdc->acm_capability.support_line_request) - { + #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM + if (p_cdc->acm_capability.support_line_request) { cdc_line_coding_t line_coding = CFG_TUH_CDC_LINE_CODING_ON_ENUM; - TU_ASSERT(acm_set_line_coding(p_cdc, &line_coding, acm_process_config, CONFIG_ACM_COMPLETE), ); + TU_ASSERT(acm_set_line_coding(p_cdc, &line_coding, acm_process_config, CONFIG_ACM_COMPLETE),); break; } - #endif + #endif TU_ATTR_FALLTHROUGH; case CONFIG_ACM_COMPLETE: // itf_num+1 to account for data interface as well - set_config_complete(p_cdc, idx, itf_num+1); + set_config_complete(p_cdc, idx, itf_num + 1); break; - default: break; + default: + break; } } @@ -868,6 +943,19 @@ static bool acm_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const return true; } +static bool acm_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + TU_LOG_DRV("CDC ACM Set Data Format\r\n"); + + cdc_line_coding_t line_coding; + line_coding.bit_rate = p_cdc->line_coding.bit_rate; + line_coding.stop_bits = stop_bits; + line_coding.parity = parity; + line_coding.data_bits = data_bits; + + return acm_set_line_coding(p_cdc, &line_coding, complete_cb, user_data); +} + static bool acm_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_VERIFY(p_cdc->acm_capability.support_line_request); cdc_line_coding_t line_coding = p_cdc->line_coding; @@ -897,7 +985,6 @@ static bool ftdi_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint TU_VERIFY(p_cdc); TU_LOG_DRV("FTDI opened\r\n"); - p_cdc->serial_drid = SERIAL_DRIVER_FTDI; // endpoint pair @@ -933,13 +1020,32 @@ static bool ftdi_sio_set_request(cdch_interface_t* p_cdc, uint8_t command, uint1 return tuh_control_xfer(&xfer); } -static bool ftdi_sio_reset(cdch_interface_t* p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +static bool ftdi_sio_reset(cdch_interface_t* p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return ftdi_sio_set_request(p_cdc, FTDI_SIO_RESET, FTDI_SIO_RESET_SIO, complete_cb, user_data); } -static bool ftdi_sio_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +static bool ftdi_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + (void) p_cdc; + (void) stop_bits; + (void) parity; + (void) data_bits; + (void) complete_cb; + (void) user_data; + // TODO not implemented yet + return false; +} + +static bool ftdi_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + (void) p_cdc; + (void) line_coding; + (void) complete_cb; + (void) user_data; + // TODO not implemented yet + return false; +} + +static bool ftdi_sio_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG_DRV("CDC FTDI Set Control Line State\r\n"); p_cdc->user_control_cb = complete_cb; TU_ASSERT(ftdi_sio_set_request(p_cdc, FTDI_SIO_MODEM_CTRL, 0x0300 | line_state, @@ -947,8 +1053,7 @@ static bool ftdi_sio_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state return true; } -static uint32_t ftdi_232bm_baud_base_to_divisor(uint32_t baud, uint32_t base) -{ +static uint32_t ftdi_232bm_baud_base_to_divisor(uint32_t baud, uint32_t base) { const uint8_t divfrac[8] = { 0, 3, 2, 4, 1, 5, 6, 7 }; uint32_t divisor; @@ -968,18 +1073,16 @@ static uint32_t ftdi_232bm_baud_base_to_divisor(uint32_t baud, uint32_t base) return divisor; } -static uint32_t ftdi_232bm_baud_to_divisor(uint32_t baud) -{ +static uint32_t ftdi_232bm_baud_to_divisor(uint32_t baud) { return ftdi_232bm_baud_base_to_divisor(baud, 48000000u); } -static bool ftdi_sio_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +static bool ftdi_sio_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { uint16_t const divisor = (uint16_t) ftdi_232bm_baud_to_divisor(baudrate); - TU_LOG_DRV("CDC FTDI Set BaudRate = %lu, divisor = 0x%04x\r\n", baudrate, divisor); + TU_LOG_DRV("CDC FTDI Set BaudRate = %" PRIu32 ", divisor = 0x%04x\r\n", baudrate, divisor); p_cdc->user_control_cb = complete_cb; - _ftdi_requested_baud = baudrate; + p_cdc->requested_line_coding.bit_rate = baudrate; TU_ASSERT(ftdi_sio_set_request(p_cdc, FTDI_SIO_SET_BAUD_RATE, divisor, complete_cb ? cdch_internal_control_complete : NULL, user_data)); @@ -1001,8 +1104,7 @@ static void ftdi_process_config(tuh_xfer_t* xfer) { case CONFIG_FTDI_MODEM_CTRL: #if CFG_TUH_CDC_LINE_CONTROL_ON_ENUM - TU_ASSERT( - ftdi_sio_set_modem_ctrl(p_cdc, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, ftdi_process_config, CONFIG_FTDI_SET_BAUDRATE),); + TU_ASSERT(ftdi_sio_set_modem_ctrl(p_cdc, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, ftdi_process_config, CONFIG_FTDI_SET_BAUDRATE),); break; #else TU_ATTR_FALLTHROUGH; @@ -1110,16 +1212,36 @@ static bool cp210x_ifc_enable(cdch_interface_t* p_cdc, uint16_t enabled, tuh_xfe return cp210x_set_request(p_cdc, CP210X_IFC_ENABLE, enabled, NULL, 0, complete_cb, user_data); } +static bool cp210x_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + // TODO implement later + (void) p_cdc; + (void) line_coding; + (void) complete_cb; + (void) user_data; + return false; +} + static bool cp210x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - TU_LOG_DRV("CDC CP210x Set BaudRate = %lu\r\n", baudrate); + TU_LOG_DRV("CDC CP210x Set BaudRate = %" PRIu32 "\r\n", baudrate); uint32_t baud_le = tu_htole32(baudrate); p_cdc->user_control_cb = complete_cb; return cp210x_set_request(p_cdc, CP210X_SET_BAUDRATE, 0, (uint8_t *) &baud_le, 4, complete_cb ? cdch_internal_control_complete : NULL, user_data); } -static bool cp210x_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +static bool cp210x_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + (void) p_cdc; + (void) stop_bits; + (void) parity; + (void) data_bits; + (void) complete_cb; + (void) user_data; + // TODO not implemented yet + return false; +} + +static bool cp210x_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG_DRV("CDC CP210x Set Control Line State\r\n"); p_cdc->user_control_cb = complete_cb; return cp210x_set_request(p_cdc, CP210X_SET_MHS, 0x0300 | line_state, NULL, 0, @@ -1159,8 +1281,7 @@ static void cp210x_process_config(tuh_xfer_t* xfer) { case CONFIG_CP210X_SET_DTR_RTS: #if CFG_TUH_CDC_LINE_CONTROL_ON_ENUM - TU_ASSERT( - cp210x_set_modem_ctrl(p_cdc, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, cp210x_process_config, CONFIG_CP210X_COMPLETE),); + TU_ASSERT(cp210x_set_modem_ctrl(p_cdc, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, cp210x_process_config, CONFIG_CP210X_COMPLETE),); break; #else TU_ATTR_FALLTHROUGH; @@ -1176,4 +1297,374 @@ static void cp210x_process_config(tuh_xfer_t* xfer) { #endif +//--------------------------------------------------------------------+ +// CH34x (CH340 & CH341) +//--------------------------------------------------------------------+ + +#if CFG_TUH_CDC_CH34X + +static uint8_t ch34x_get_lcr(uint8_t stop_bits, uint8_t parity, uint8_t data_bits); +static uint16_t ch34x_get_divisor_prescaler(uint32_t baval); + +//------------- control request -------------// + +static bool ch34x_set_request(cdch_interface_t* p_cdc, uint8_t direction, uint8_t request, uint16_t value, + uint16_t index, uint8_t* buffer, uint16_t length, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + tusb_control_request_t const request_setup = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_VENDOR, + .direction = direction & 0x01u + }, + .bRequest = request, + .wValue = tu_htole16 (value), + .wIndex = tu_htole16 (index), + .wLength = tu_htole16 (length) + }; + + // use usbh enum buf since application variable does not live long enough + uint8_t* enum_buf = NULL; + + if (buffer && length > 0) { + enum_buf = usbh_get_enum_buf(); + if (direction == TUSB_DIR_OUT) { + tu_memcpy_s(enum_buf, CFG_TUH_ENUMERATION_BUFSIZE, buffer, length); + } + } + + tuh_xfer_t xfer = { + .daddr = p_cdc->daddr, + .ep_addr = 0, + .setup = &request_setup, + .buffer = enum_buf, + .complete_cb = complete_cb, + .user_data = user_data + }; + + return tuh_control_xfer(&xfer); +} + +static inline bool ch34x_control_out(cdch_interface_t* p_cdc, uint8_t request, uint16_t value, uint16_t index, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + return ch34x_set_request(p_cdc, TUSB_DIR_OUT, request, value, index, NULL, 0, complete_cb, user_data); +} + +static inline bool ch34x_control_in(cdch_interface_t* p_cdc, uint8_t request, uint16_t value, uint16_t index, + uint8_t* buffer, uint16_t buffersize, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + return ch34x_set_request(p_cdc, TUSB_DIR_IN, request, value, index, buffer, buffersize, + complete_cb, user_data); +} + +static inline bool ch34x_write_reg(cdch_interface_t* p_cdc, uint16_t reg, uint16_t reg_value, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + return ch34x_control_out(p_cdc, CH34X_REQ_WRITE_REG, reg, reg_value, complete_cb, user_data); +} + +//static bool ch34x_read_reg_request ( cdch_interface_t* p_cdc, uint16_t reg, +// uint8_t *buffer, uint16_t buffersize, tuh_xfer_cb_t complete_cb, uintptr_t user_data ) +//{ +// return ch34x_control_in ( p_cdc, CH34X_REQ_READ_REG, reg, 0, buffer, buffersize, complete_cb, user_data ); +//} + +static bool ch34x_write_reg_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + uint16_t const div_ps = ch34x_get_divisor_prescaler(baudrate); + TU_VERIFY(div_ps); + TU_ASSERT(ch34x_write_reg(p_cdc, CH34X_REG16_DIVISOR_PRESCALER, div_ps, + complete_cb, user_data)); + return true; +} + +//------------- Driver API -------------// + +// internal control complete to update state such as line state, encoding +static void ch34x_control_complete(tuh_xfer_t* xfer) { + // CH34x only has 1 interface and use wIndex as payload and not for bInterfaceNumber + process_internal_control_complete(xfer, 0); +} + +static bool ch34x_set_data_format(cdch_interface_t* p_cdc, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + p_cdc->requested_line_coding.stop_bits = stop_bits; + p_cdc->requested_line_coding.parity = parity; + p_cdc->requested_line_coding.data_bits = data_bits; + + uint8_t const lcr = ch34x_get_lcr(stop_bits, parity, data_bits); + TU_VERIFY(lcr); + TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_WRITE_REG, CH32X_REG16_LCR2_LCR, lcr, + complete_cb ? ch34x_control_complete : NULL, user_data)); + return true; +} + +static bool ch34x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + p_cdc->requested_line_coding.bit_rate = baudrate; + p_cdc->user_control_cb = complete_cb; + TU_ASSERT(ch34x_write_reg_baudrate(p_cdc, baudrate, + complete_cb ? ch34x_control_complete : NULL, user_data)); + return true; +} + +static void ch34x_set_line_coding_stage1_complete(tuh_xfer_t* xfer) { + // CH34x only has 1 interface and use wIndex as payload and not for bInterfaceNumber + uint8_t const itf_num = 0; + uint8_t const idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num); + cdch_interface_t* p_cdc = get_itf(idx); + TU_ASSERT(p_cdc, ); + + if (xfer->result == XFER_RESULT_SUCCESS) { + // stage 1 success, continue to stage 2 + p_cdc->line_coding.bit_rate = p_cdc->requested_line_coding.bit_rate; + TU_ASSERT(ch34x_set_data_format(p_cdc, p_cdc->requested_line_coding.stop_bits, p_cdc->requested_line_coding.parity, + p_cdc->requested_line_coding.data_bits, ch34x_control_complete, xfer->user_data), ); + } else { + // stage 1 failed, notify user + xfer->complete_cb = p_cdc->user_control_cb; + if (xfer->complete_cb) { + xfer->complete_cb(xfer); + } + } +} + +// 2 stages: set baudrate (stage1) + set data format (stage2) +static bool ch34x_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t const* line_coding, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + p_cdc->requested_line_coding = *line_coding; + p_cdc->user_control_cb = complete_cb; + + if (complete_cb) { + // stage 1 set baudrate + TU_ASSERT(ch34x_write_reg_baudrate(p_cdc, line_coding->bit_rate, + ch34x_set_line_coding_stage1_complete, user_data)); + } else { + // sync call + xfer_result_t result; + + // stage 1 set baudrate + TU_ASSERT(ch34x_write_reg_baudrate(p_cdc, line_coding->bit_rate, NULL, (uintptr_t) &result)); + TU_VERIFY(result == XFER_RESULT_SUCCESS); + p_cdc->line_coding.bit_rate = line_coding->bit_rate; + + // stage 2 set data format + TU_ASSERT(ch34x_set_data_format(p_cdc, line_coding->stop_bits, line_coding->parity, line_coding->data_bits, + NULL, (uintptr_t) &result)); + TU_VERIFY(result == XFER_RESULT_SUCCESS); + p_cdc->line_coding.stop_bits = line_coding->stop_bits; + p_cdc->line_coding.parity = line_coding->parity; + p_cdc->line_coding.data_bits = line_coding->data_bits; + + // update transfer result, user_data is expected to point to xfer_result_t + if (user_data) { + *((xfer_result_t*) user_data) = result; + } + } + + return true; +} + +static bool ch34x_set_modem_ctrl(cdch_interface_t* p_cdc, uint16_t line_state, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + uint8_t control = 0; + if (line_state & CDC_CONTROL_LINE_STATE_RTS) { + control |= CH34X_BIT_RTS; + } + if (line_state & CDC_CONTROL_LINE_STATE_DTR) { + control |= CH34X_BIT_DTR; + } + + // CH34x signals are inverted + control = ~control; + + p_cdc->user_control_cb = complete_cb; + TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_MODEM_CTRL, control, 0, + complete_cb ? ch34x_control_complete : NULL, user_data)); + return true; +} + +//------------- Enumeration -------------// +enum { + CONFIG_CH34X_READ_VERSION = 0, + CONFIG_CH34X_SERIAL_INIT, + CONFIG_CH34X_SPECIAL_REG_WRITE, + CONFIG_CH34X_FLOW_CONTROL, + CONFIG_CH34X_MODEM_CONTROL, + CONFIG_CH34X_COMPLETE +}; + +static bool ch34x_open(uint8_t daddr, tusb_desc_interface_t const* itf_desc, uint16_t max_len) { + // CH34x Interface includes 1 vendor interface + 2 bulk + 1 interrupt endpoints + TU_VERIFY (itf_desc->bNumEndpoints == 3); + TU_VERIFY (sizeof(tusb_desc_interface_t) + 3 * sizeof(tusb_desc_endpoint_t) <= max_len); + + cdch_interface_t* p_cdc = make_new_itf(daddr, itf_desc); + TU_VERIFY (p_cdc); + + TU_LOG_DRV ("CH34x opened\r\n"); + p_cdc->serial_drid = SERIAL_DRIVER_CH34X; + + tusb_desc_endpoint_t const* desc_ep = (tusb_desc_endpoint_t const*) tu_desc_next(itf_desc); + + // data endpoints expected to be in pairs + TU_ASSERT(open_ep_stream_pair(p_cdc, desc_ep)); + desc_ep += 2; + + // Interrupt endpoint: not used for now + TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(desc_ep) && + TUSB_XFER_INTERRUPT == desc_ep->bmAttributes.xfer); + TU_ASSERT(tuh_edpt_open(daddr, desc_ep)); + p_cdc->ep_notif = desc_ep->bEndpointAddress; + + return true; +} + +static void ch34x_process_config(tuh_xfer_t* xfer) { + // CH34x only has 1 interface and use wIndex as payload and not for bInterfaceNumber + uint8_t const itf_num = 0; + uint8_t const idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num); + cdch_interface_t* p_cdc = get_itf(idx); + uintptr_t const state = xfer->user_data; + uint8_t buffer[2]; // TODO remove + TU_ASSERT (p_cdc,); + TU_ASSERT (xfer->result == XFER_RESULT_SUCCESS,); + + switch (state) { + case CONFIG_CH34X_READ_VERSION: + TU_LOG_DRV("[%u] CDCh CH34x attempt to read Chip Version\r\n", p_cdc->daddr); + TU_ASSERT (ch34x_control_in(p_cdc, CH34X_REQ_READ_VERSION, 0, 0, buffer, 2, ch34x_process_config, CONFIG_CH34X_SERIAL_INIT),); + break; + + case CONFIG_CH34X_SERIAL_INIT: { + // handle version read data, set CH34x line coding (incl. baudrate) + uint8_t const version = xfer->buffer[0]; + TU_LOG_DRV("[%u] CDCh CH34x Chip Version = %02x\r\n", p_cdc->daddr, version); + // only versions >= 0x30 are tested, below 0x30 seems having other programming, see drivers from WCH vendor, Linux kernel and FreeBSD + TU_ASSERT (version >= 0x30,); + // init CH34x with line coding + cdc_line_coding_t const line_coding = CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X; + uint16_t const div_ps = ch34x_get_divisor_prescaler(line_coding.bit_rate); + TU_ASSERT(div_ps, ); + uint8_t const lcr = ch34x_get_lcr(line_coding.stop_bits, line_coding.parity, line_coding.data_bits); + TU_ASSERT(lcr, ); + TU_ASSERT (ch34x_control_out(p_cdc, CH34X_REQ_SERIAL_INIT, tu_u16(lcr, 0x9c), div_ps, + ch34x_process_config, CONFIG_CH34X_SPECIAL_REG_WRITE),); + break; + } + + case CONFIG_CH34X_SPECIAL_REG_WRITE: + // overtake line coding and do special reg write, purpose unknown, overtaken from WCH driver + p_cdc->line_coding = ((cdc_line_coding_t) CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X); + TU_ASSERT (ch34x_write_reg(p_cdc, TU_U16(CH341_REG_0x0F, CH341_REG_0x2C), 0x0007, ch34x_process_config, CONFIG_CH34X_FLOW_CONTROL),); + break; + + case CONFIG_CH34X_FLOW_CONTROL: + // no hardware flow control + TU_ASSERT (ch34x_write_reg(p_cdc, TU_U16(CH341_REG_0x27, CH341_REG_0x27), 0x0000, ch34x_process_config, CONFIG_CH34X_MODEM_CONTROL),); + break; + + case CONFIG_CH34X_MODEM_CONTROL: + // !always! set modem controls RTS/DTR (CH34x has no reset state after CH34X_REQ_SERIAL_INIT) + TU_ASSERT (ch34x_set_modem_ctrl(p_cdc, CFG_TUH_CDC_LINE_CONTROL_ON_ENUM, ch34x_process_config, CONFIG_CH34X_COMPLETE),); + break; + + case CONFIG_CH34X_COMPLETE: + set_config_complete(p_cdc, idx, itf_num); + break; + + default: + TU_ASSERT (false,); + break; + } +} + +//------------- CH34x helper -------------// + +// calculate divisor and prescaler for baudrate, return it as 16-bit combined value +static uint16_t ch34x_get_divisor_prescaler(uint32_t baval) { + uint8_t a; + uint8_t b; + uint32_t c; + + TU_VERIFY(baval != 0 && baval <= 2000000, 0); + switch (baval) { + case 921600: + a = 0xf3; + b = 7; + break; + + case 307200: + a = 0xd9; + b = 7; + break; + + default: + if (baval > 6000000 / 255) { + b = 3; + c = 6000000; + } else if (baval > 750000 / 255) { + b = 2; + c = 750000; + } else if (baval > 93750 / 255) { + b = 1; + c = 93750; + } else { + b = 0; + c = 11719; + } + a = (uint8_t) (c / baval); + if (a == 0 || a == 0xFF) { + return 0; + } + if ((c / a - baval) > (baval - c / (a + 1))) { + a++; + } + a = (uint8_t) (256 - a); + break; + } + + // reg divisor = a, reg prescaler = b + // According to linux code we need to set bit 7 of UCHCOM_REG_BPS_PRE, + // otherwise the chip will buffer data. + return (uint16_t) ((uint16_t)a << 8 | 0x80 | b); +} + +// calculate lcr value from data coding +static uint8_t ch34x_get_lcr(uint8_t stop_bits, uint8_t parity, uint8_t data_bits) { + uint8_t lcr = CH34X_LCR_ENABLE_RX | CH34X_LCR_ENABLE_TX; + TU_VERIFY(data_bits >= 5 && data_bits <= 8, 0); + lcr |= (uint8_t) (data_bits - 5); + + switch(parity) { + case CDC_LINE_CODING_PARITY_NONE: + break; + + case CDC_LINE_CODING_PARITY_ODD: + lcr |= CH34X_LCR_ENABLE_PAR; + break; + + case CDC_LINE_CODING_PARITY_EVEN: + lcr |= CH34X_LCR_ENABLE_PAR | CH34X_LCR_PAR_EVEN; + break; + + case CDC_LINE_CODING_PARITY_MARK: + lcr |= CH34X_LCR_ENABLE_PAR | CH34X_LCR_MARK_SPACE; + break; + + case CDC_LINE_CODING_PARITY_SPACE: + lcr |= CH34X_LCR_ENABLE_PAR | CH34X_LCR_MARK_SPACE | CH34X_LCR_PAR_EVEN; + break; + + default: break; + } + + // 1.5 stop bits not supported + TU_VERIFY(stop_bits != CDC_LINE_CODING_STOP_BITS_1_5, 0); + if (stop_bits == CDC_LINE_CODING_STOP_BITS_2) { + lcr |= CH34X_LCR_STOP_BITS_2; + } + + return lcr; +} + + +#endif // CFG_TUH_CDC_CH34X + #endif diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index 19552f1ee..b63dd1530 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -44,7 +44,7 @@ // Set Line Coding on enumeration/mounted, value for cdc_line_coding_t //#ifndef CFG_TUH_CDC_LINE_CODING_ON_ENUM -//#define CFG_TUH_CDC_LINE_CODING_ON_ENUM { 115200, CDC_LINE_CONDING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 } +//#define CFG_TUH_CDC_LINE_CODING_ON_ENUM { 115200, CDC_LINE_CODING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 } //#endif // RX FIFO size @@ -148,8 +148,11 @@ bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_c // Request to set baudrate bool tuh_cdc_set_baudrate(uint8_t idx, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data); -// Request to Set Line Coding (ACM only) -// Should only use if you don't work with serial devices such as FTDI/CP210x +// Request to set data format +bool tuh_cdc_set_data_format(uint8_t idx, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, tuh_xfer_cb_t complete_cb, uintptr_t user_data); + +// Request to Set Line Coding = baudrate + data format +// Note: only implemented by ACM and CH34x, not supported by FTDI and CP210x yet bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data); // Request to Get Line Coding (ACM only) @@ -159,15 +162,13 @@ bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, // Connect by set both DTR, RTS TU_ATTR_ALWAYS_INLINE static inline -bool tuh_cdc_connect(uint8_t idx, tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +bool tuh_cdc_connect(uint8_t idx, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return tuh_cdc_set_control_line_state(idx, CDC_CONTROL_LINE_STATE_DTR | CDC_CONTROL_LINE_STATE_RTS, complete_cb, user_data); } // Disconnect by clear both DTR, RTS TU_ATTR_ALWAYS_INLINE static inline -bool tuh_cdc_disconnect(uint8_t idx, tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +bool tuh_cdc_disconnect(uint8_t idx, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return tuh_cdc_set_control_line_state(idx, 0x00, complete_cb, user_data); } @@ -191,7 +192,8 @@ TU_ATTR_WEAK extern void tuh_cdc_tx_complete_cb(uint8_t idx); //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ -void cdch_init (void); +bool cdch_init (void); +bool cdch_deinit (void); bool cdch_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); bool cdch_set_config (uint8_t dev_addr, uint8_t itf_num); bool cdch_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); diff --git a/src/class/cdc/serial/ch34x.h b/src/class/cdc/serial/ch34x.h new file mode 100644 index 000000000..c18066f57 --- /dev/null +++ b/src/class/cdc/serial/ch34x.h @@ -0,0 +1,84 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2023 Heiko Kuester + * + * 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 _CH34X_H_ +#define _CH34X_H_ + +// There is no official documentation for the CH34x (CH340, CH341) chips. Reference can be found +// - https://github.com/WCHSoftGroup/ch341ser_linux +// - https://github.com/torvalds/linux/blob/master/drivers/usb/serial/ch341.c +// - https://github.com/freebsd/freebsd-src/blob/main/sys/dev/usb/serial/uchcom.c + +// set line_coding @ enumeration +#ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM +#define CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X CFG_TUH_CDC_LINE_CODING_ON_ENUM +#else // this default is necessary to work properly +#define CFG_TUH_CDC_LINE_CODING_ON_ENUM_CH34X { 9600, CDC_LINE_CONDING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 } +#endif + +// USB requests +#define CH34X_REQ_READ_VERSION 0x5F // dec 95 +#define CH34X_REQ_WRITE_REG 0x9A // dec 154 +#define CH34X_REQ_READ_REG 0x95 // dec 149 +#define CH34X_REQ_SERIAL_INIT 0xA1 // dec 161 +#define CH34X_REQ_MODEM_CTRL 0xA4 // dev 164 + +// registers +#define CH34X_REG_BREAK 0x05 +#define CH34X_REG_PRESCALER 0x12 +#define CH34X_REG_DIVISOR 0x13 +#define CH34X_REG_LCR 0x18 +#define CH34X_REG_LCR2 0x25 +#define CH34X_REG_MCR_MSR 0x06 +#define CH34X_REG_MCR_MSR2 0x07 +#define CH34X_NBREAK_BITS 0x01 + +#define CH341_REG_0x0F 0x0F // undocumented register +#define CH341_REG_0x2C 0x2C // undocumented register +#define CH341_REG_0x27 0x27 // hardware flow control (cts/rts) + +#define CH34X_REG16_DIVISOR_PRESCALER TU_U16(CH34X_REG_DIVISOR, CH34X_REG_PRESCALER) +#define CH32X_REG16_LCR2_LCR TU_U16(CH34X_REG_LCR2, CH34X_REG_LCR) + +// modem control bits +#define CH34X_BIT_RTS ( 1 << 6 ) +#define CH34X_BIT_DTR ( 1 << 5 ) + +// line control bits +#define CH34X_LCR_ENABLE_RX 0x80 +#define CH34X_LCR_ENABLE_TX 0x40 +#define CH34X_LCR_MARK_SPACE 0x20 +#define CH34X_LCR_PAR_EVEN 0x10 +#define CH34X_LCR_ENABLE_PAR 0x08 +#define CH34X_LCR_PAR_MASK 0x38 // all parity bits +#define CH34X_LCR_STOP_BITS_2 0x04 +#define CH34X_LCR_CS8 0x03 +#define CH34X_LCR_CS7 0x02 +#define CH34X_LCR_CS6 0x01 +#define CH34X_LCR_CS5 0x00 +#define CH34X_LCR_CS_MASK 0x03 // all CSx bits + +#endif /* _CH34X_H_ */ diff --git a/src/class/cdc/serial/cp210x.h b/src/class/cdc/serial/cp210x.h index b01417092..2c749f522 100644 --- a/src/class/cdc/serial/cp210x.h +++ b/src/class/cdc/serial/cp210x.h @@ -29,8 +29,6 @@ // https://www.silabs.com/documents/public/application-notes/AN571.pdf #define TU_CP210X_VID 0x10C4 -#define TU_CP210X_PID_LIST \ - 0xEA60, 0xEA70 /* Config request codes */ #define CP210X_IFC_ENABLE 0x00 diff --git a/src/class/cdc/serial/ftdi_sio.h b/src/class/cdc/serial/ftdi_sio.h index 6916e4031..0825f0719 100644 --- a/src/class/cdc/serial/ftdi_sio.h +++ b/src/class/cdc/serial/ftdi_sio.h @@ -25,11 +25,8 @@ #ifndef TUSB_FTDI_SIO_H #define TUSB_FTDI_SIO_H -// VID/PID for matching FTDI devices +// VID for matching FTDI devices #define TU_FTDI_VID 0x0403 -#define TU_FTDI_PID_LIST \ - 0x6001, 0x6006, 0x6010, 0x6011, 0x6014, 0x6015, 0x8372, 0xFBFA, \ - 0xcd18 // Commands #define FTDI_SIO_RESET 0 /* Reset the port */ diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index 3e7c13dea..71e7ac2b3 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -160,11 +160,14 @@ void dfu_moded_reset(uint8_t rhport) reset_state(); } -void dfu_moded_init(void) -{ +void dfu_moded_init(void) { dfu_moded_reset(0); } +bool dfu_moded_deinit(void) { + return true; +} + uint16_t dfu_moded_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) { (void) rhport; diff --git a/src/class/dfu/dfu_device.h b/src/class/dfu/dfu_device.h index fecf8596f..00c22ea8b 100644 --- a/src/class/dfu/dfu_device.h +++ b/src/class/dfu/dfu_device.h @@ -86,6 +86,7 @@ TU_ATTR_WEAK void tud_dfu_abort_cb(uint8_t alt); // Internal Class Driver API //--------------------------------------------------------------------+ void dfu_moded_init(void); +bool dfu_moded_deinit(void); void dfu_moded_reset(uint8_t rhport); uint16_t dfu_moded_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/class/dfu/dfu_rt_device.c b/src/class/dfu/dfu_rt_device.c index a940d8d62..3b801b787 100644 --- a/src/class/dfu/dfu_rt_device.c +++ b/src/class/dfu/dfu_rt_device.c @@ -51,8 +51,11 @@ //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ -void dfu_rtd_init(void) -{ +void dfu_rtd_init(void) { +} + +bool dfu_rtd_deinit(void) { + return true; } void dfu_rtd_reset(uint8_t rhport) diff --git a/src/class/dfu/dfu_rt_device.h b/src/class/dfu/dfu_rt_device.h index babaa8214..67eb26d95 100644 --- a/src/class/dfu/dfu_rt_device.h +++ b/src/class/dfu/dfu_rt_device.h @@ -43,6 +43,7 @@ void tud_dfu_runtime_reboot_to_dfu_cb(void); // Internal Class Driver API //--------------------------------------------------------------------+ void dfu_rtd_init(void); +bool dfu_rtd_deinit(void); void dfu_rtd_reset(uint8_t rhport); uint16_t dfu_rtd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool dfu_rtd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/class/hid/hid.h b/src/class/hid/hid.h index fbd3eef38..e949f1f83 100644 --- a/src/class/hid/hid.h +++ b/src/class/hid/hid.h @@ -300,6 +300,19 @@ typedef struct TU_ATTR_PACKED int8_t pan; // using AC Pan } hid_mouse_report_t; + +// Absolute Mouse: same as the Standard (relative) Mouse Report but +// with int16_t instead of int8_t for X and Y coordinates. +typedef struct TU_ATTR_PACKED +{ + uint8_t buttons; /**< buttons mask for currently pressed buttons in the mouse. */ + int16_t x; /**< Current x position of the mouse. */ + int16_t y; /**< Current y position of the mouse. */ + int8_t wheel; /**< Current delta wheel movement on the mouse. */ + int8_t pan; // using AC Pan +} hid_abs_mouse_report_t; + + /// Standard Mouse Buttons Bitmap typedef enum { @@ -684,32 +697,33 @@ enum { /// HID Usage Table - Table 1: Usage Page Summary enum { - HID_USAGE_PAGE_DESKTOP = 0x01, - HID_USAGE_PAGE_SIMULATE = 0x02, - HID_USAGE_PAGE_VIRTUAL_REALITY = 0x03, - HID_USAGE_PAGE_SPORT = 0x04, - HID_USAGE_PAGE_GAME = 0x05, - HID_USAGE_PAGE_GENERIC_DEVICE = 0x06, - HID_USAGE_PAGE_KEYBOARD = 0x07, - HID_USAGE_PAGE_LED = 0x08, - HID_USAGE_PAGE_BUTTON = 0x09, - HID_USAGE_PAGE_ORDINAL = 0x0a, - HID_USAGE_PAGE_TELEPHONY = 0x0b, - HID_USAGE_PAGE_CONSUMER = 0x0c, - HID_USAGE_PAGE_DIGITIZER = 0x0d, - HID_USAGE_PAGE_PID = 0x0f, - HID_USAGE_PAGE_UNICODE = 0x10, - HID_USAGE_PAGE_ALPHA_DISPLAY = 0x14, - HID_USAGE_PAGE_MEDICAL = 0x40, - HID_USAGE_PAGE_MONITOR = 0x80, //0x80 - 0x83 - HID_USAGE_PAGE_POWER = 0x84, // 0x084 - 0x87 - HID_USAGE_PAGE_BARCODE_SCANNER = 0x8c, - HID_USAGE_PAGE_SCALE = 0x8d, - HID_USAGE_PAGE_MSR = 0x8e, - HID_USAGE_PAGE_CAMERA = 0x90, - HID_USAGE_PAGE_ARCADE = 0x91, - HID_USAGE_PAGE_FIDO = 0xF1D0, // FIDO alliance HID usage page - HID_USAGE_PAGE_VENDOR = 0xFF00 // 0xFF00 - 0xFFFF + HID_USAGE_PAGE_DESKTOP = 0x01, + HID_USAGE_PAGE_SIMULATE = 0x02, + HID_USAGE_PAGE_VIRTUAL_REALITY = 0x03, + HID_USAGE_PAGE_SPORT = 0x04, + HID_USAGE_PAGE_GAME = 0x05, + HID_USAGE_PAGE_GENERIC_DEVICE = 0x06, + HID_USAGE_PAGE_KEYBOARD = 0x07, + HID_USAGE_PAGE_LED = 0x08, + HID_USAGE_PAGE_BUTTON = 0x09, + HID_USAGE_PAGE_ORDINAL = 0x0a, + HID_USAGE_PAGE_TELEPHONY = 0x0b, + HID_USAGE_PAGE_CONSUMER = 0x0c, + HID_USAGE_PAGE_DIGITIZER = 0x0d, + HID_USAGE_PAGE_PID = 0x0f, + HID_USAGE_PAGE_UNICODE = 0x10, + HID_USAGE_PAGE_ALPHA_DISPLAY = 0x14, + HID_USAGE_PAGE_MEDICAL = 0x40, + HID_USAGE_PAGE_LIGHTING_AND_ILLUMINATION = 0x59, + HID_USAGE_PAGE_MONITOR = 0x80, //0x80 - 0x83 + HID_USAGE_PAGE_POWER = 0x84, // 0x084 - 0x87 + HID_USAGE_PAGE_BARCODE_SCANNER = 0x8c, + HID_USAGE_PAGE_SCALE = 0x8d, + HID_USAGE_PAGE_MSR = 0x8e, + HID_USAGE_PAGE_CAMERA = 0x90, + HID_USAGE_PAGE_ARCADE = 0x91, + HID_USAGE_PAGE_FIDO = 0xF1D0, // FIDO alliance HID usage page + HID_USAGE_PAGE_VENDOR = 0xFF00 // 0xFF00 - 0xFFFF }; /// HID Usage Table - Table 6: Generic Desktop Page @@ -788,8 +802,7 @@ enum { /// HID Usage Table: Consumer Page (0x0C) /// Only contains controls that supported by Windows (whole list is too long) -enum -{ +enum { // Generic Control HID_USAGE_CONSUMER_CONTROL = 0x0001, @@ -845,9 +858,45 @@ enum HID_USAGE_CONSUMER_AC_PAN = 0x0238, }; +/// HID Usage Table - Lighting And Illumination Page (0x59) +enum { + HID_USAGE_LIGHTING_LAMP_ARRAY = 0x01, + HID_USAGE_LIGHTING_LAMP_ARRAY_ATTRIBUTES_REPORT = 0x02, + HID_USAGE_LIGHTING_LAMP_COUNT = 0x03, + HID_USAGE_LIGHTING_BOUNDING_BOX_WIDTH_IN_MICROMETERS = 0x04, + HID_USAGE_LIGHTING_BOUNDING_BOX_HEIGHT_IN_MICROMETERS = 0x05, + HID_USAGE_LIGHTING_BOUNDING_BOX_DEPTH_IN_MICROMETERS = 0x06, + HID_USAGE_LIGHTING_LAMP_ARRAY_KIND = 0x07, + HID_USAGE_LIGHTING_MIN_UPDATE_INTERVAL_IN_MICROSECONDS = 0x08, + HID_USAGE_LIGHTING_LAMP_ATTRIBUTES_REQUEST_REPORT = 0x20, + HID_USAGE_LIGHTING_LAMP_ID = 0x21, + HID_USAGE_LIGHTING_LAMP_ATTRIBUTES_RESPONSE_REPORT = 0x22, + HID_USAGE_LIGHTING_POSITION_X_IN_MICROMETERS = 0x23, + HID_USAGE_LIGHTING_POSITION_Y_IN_MICROMETERS = 0x24, + HID_USAGE_LIGHTING_POSITION_Z_IN_MICROMETERS = 0x25, + HID_USAGE_LIGHTING_LAMP_PURPOSES = 0x26, + HID_USAGE_LIGHTING_UPDATE_LATENCY_IN_MICROSECONDS = 0x27, + HID_USAGE_LIGHTING_RED_LEVEL_COUNT = 0x28, + HID_USAGE_LIGHTING_GREEN_LEVEL_COUNT = 0x29, + HID_USAGE_LIGHTING_BLUE_LEVEL_COUNT = 0x2A, + HID_USAGE_LIGHTING_INTENSITY_LEVEL_COUNT = 0x2B, + HID_USAGE_LIGHTING_IS_PROGRAMMABLE = 0x2C, + HID_USAGE_LIGHTING_INPUT_BINDING = 0x2D, + HID_USAGE_LIGHTING_LAMP_MULTI_UPDATE_REPORT = 0x50, + HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL = 0x51, + HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL = 0x52, + HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL = 0x53, + HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL = 0x54, + HID_USAGE_LIGHTING_LAMP_UPDATE_FLAGS = 0x55, + HID_USAGE_LIGHTING_LAMP_RANGE_UPDATE_REPORT = 0x60, + HID_USAGE_LIGHTING_LAMP_ID_START = 0x61, + HID_USAGE_LIGHTING_LAMP_ID_END = 0x62, + HID_USAGE_LIGHTING_LAMP_ARRAY_CONTROL_REPORT = 0x70, + HID_USAGE_LIGHTING_AUTONOMOUS_MODE = 0x71, +}; + /// HID Usage Table: FIDO Alliance Page (0xF1D0) -enum -{ +enum { HID_USAGE_FIDO_U2FHID = 0x01, // U2FHID usage for top-level collection HID_USAGE_FIDO_DATA_IN = 0x20, // Raw IN data report HID_USAGE_FIDO_DATA_OUT = 0x21 // Raw OUT data report diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 5637ea6b4..ada01582e 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -39,23 +39,23 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ -typedef struct -{ +typedef struct { uint8_t itf_num; uint8_t ep_in; - uint8_t ep_out; // optional Out endpoint - uint8_t itf_protocol; // Boot mouse or keyboard + uint8_t ep_out; // optional Out endpoint + uint8_t itf_protocol; // Boot mouse or keyboard - uint8_t protocol_mode; // Boot (0) or Report protocol (1) - uint8_t idle_rate; // up to application to handle idle rate uint16_t report_desc_len; + CFG_TUSB_MEM_ALIGN uint8_t protocol_mode; // Boot (0) or Report protocol (1) + CFG_TUSB_MEM_ALIGN uint8_t idle_rate; // up to application to handle idle rate CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_HID_EP_BUFSIZE]; CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_HID_EP_BUFSIZE]; + CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf[CFG_TUD_HID_EP_BUFSIZE]; // TODO save hid descriptor since host can specifically request this after enumeration // Note: HID descriptor may be not available from application after enumeration - tusb_hid_descriptor_hid_t const * hid_descriptor; + tusb_hid_descriptor_hid_t const *hid_descriptor; } hidd_interface_t; CFG_TUD_MEM_SECTION tu_static hidd_interface_t _hidd_itf[CFG_TUD_HID]; @@ -63,12 +63,12 @@ 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) { - for (uint8_t i=0; i < CFG_TUD_HID; i++ ) - { - if ( itf_num == _hidd_itf[i].itf_num ) return i; - } + for (uint8_t i = 0; i < CFG_TUD_HID; i++) { + if (itf_num == _hidd_itf[i].itf_num) + return i; + } - return 0xFF; + return 0xFF; } //--------------------------------------------------------------------+ @@ -81,37 +81,29 @@ bool tud_hid_n_ready(uint8_t instance) return tud_ready() && (ep_in != 0) && !usbd_edpt_busy(rhport, ep_in); } -bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, uint16_t len) +bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const *report, uint16_t len) { uint8_t const rhport = 0; - hidd_interface_t * p_hid = &_hidd_itf[instance]; + hidd_interface_t *p_hid = &_hidd_itf[instance]; // claim endpoint - TU_VERIFY( usbd_edpt_claim(rhport, p_hid->ep_in) ); + TU_VERIFY(usbd_edpt_claim(rhport, p_hid->ep_in)); // prepare data - if (report_id) - { + if (report_id) { p_hid->epin_buf[0] = report_id; - TU_VERIFY(0 == tu_memcpy_s(p_hid->epin_buf+1, CFG_TUD_HID_EP_BUFSIZE-1, report, len)); + TU_VERIFY(0 == tu_memcpy_s(p_hid->epin_buf + 1, CFG_TUD_HID_EP_BUFSIZE - 1, report, len)); len++; - }else - { + } else { TU_VERIFY(0 == tu_memcpy_s(p_hid->epin_buf, CFG_TUD_HID_EP_BUFSIZE, report, len)); } return usbd_edpt_xfer(rhport, p_hid->ep_in, p_hid->epin_buf, len); } -uint8_t tud_hid_n_interface_protocol(uint8_t instance) -{ - return _hidd_itf[instance].itf_protocol; -} +uint8_t tud_hid_n_interface_protocol(uint8_t instance) { return _hidd_itf[instance].itf_protocol; } -uint8_t tud_hid_n_get_protocol(uint8_t instance) -{ - return _hidd_itf[instance].protocol_mode; -} +uint8_t tud_hid_n_get_protocol(uint8_t instance) { return _hidd_itf[instance].protocol_mode; } bool tud_hid_n_keyboard_report(uint8_t instance, uint8_t report_id, uint8_t modifier, uint8_t keycode[6]) { @@ -120,44 +112,51 @@ bool tud_hid_n_keyboard_report(uint8_t instance, uint8_t report_id, uint8_t modi report.modifier = modifier; report.reserved = 0; - if ( keycode ) - { + if (keycode) { memcpy(report.keycode, keycode, sizeof(report.keycode)); - }else - { + } else { tu_memclr(report.keycode, 6); } return tud_hid_n_report(instance, report_id, &report, sizeof(report)); } -bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id, - uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal) +bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal) { - hid_mouse_report_t report = - { + hid_mouse_report_t report = { .buttons = buttons, - .x = x, - .y = y, - .wheel = vertical, - .pan = horizontal + .x = x, + .y = y, + .wheel = vertical, + .pan = horizontal }; return tud_hid_n_report(instance, report_id, &report, sizeof(report)); } -bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, - int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons) { - hid_gamepad_report_t report = - { - .x = x, - .y = y, - .z = z, - .rz = rz, - .rx = rx, - .ry = ry, - .hat = hat, +bool tud_hid_n_abs_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal) +{ + hid_abs_mouse_report_t report = { .buttons = buttons, + .x = x, + .y = y, + .wheel = vertical, + .pan = horizontal + }; + return tud_hid_n_report(instance, report_id, &report, sizeof(report)); +} + +bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons) +{ + hid_gamepad_report_t report = { + .x = x, + .y = y, + .z = z, + .rz = rz, + .rx = rx, + .ry = ry, + .hat = hat, + .buttons = buttons, }; return tud_hid_n_report(instance, report_id, &report, sizeof(report)); @@ -171,59 +170,59 @@ void hidd_init(void) hidd_reset(0); } +bool hidd_deinit(void) +{ + return true; +} + void hidd_reset(uint8_t rhport) { - (void) rhport; + (void)rhport; tu_memclr(_hidd_itf, sizeof(_hidd_itf)); } -uint16_t hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t max_len) - { +uint16_t hidd_open(uint8_t rhport, tusb_desc_interface_t const *desc_itf, uint16_t max_len) +{ TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass, 0); // len = interface + hid + n*endpoints - uint16_t const drv_len = - (uint16_t) (sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + - desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); + uint16_t const drv_len = (uint16_t)(sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); TU_ASSERT(max_len >= drv_len, 0); // Find available interface - hidd_interface_t * p_hid = NULL; + hidd_interface_t *p_hid = NULL; uint8_t hid_id; - for(hid_id=0; hid_idhid_descriptor = (tusb_hid_descriptor_hid_t const *) p_desc; + p_hid->hid_descriptor = (tusb_hid_descriptor_hid_t const *)p_desc; //------------- Endpoint Descriptor -------------// p_desc = tu_desc_next(p_desc); TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, desc_itf->bNumEndpoints, TUSB_XFER_INTERRUPT, &p_hid->ep_out, &p_hid->ep_in), 0); - if ( desc_itf->bInterfaceSubClass == HID_SUBCLASS_BOOT ) p_hid->itf_protocol = desc_itf->bInterfaceProtocol; + if (desc_itf->bInterfaceSubClass == HID_SUBCLASS_BOOT) + p_hid->itf_protocol = desc_itf->bInterfaceProtocol; p_hid->protocol_mode = HID_PROTOCOL_REPORT; // Per Specs: default is report mode - p_hid->itf_num = desc_itf->bInterfaceNumber; + p_hid->itf_num = desc_itf->bInterfaceNumber; // Use offsetof to avoid pointer to the odd/misaligned address - p_hid->report_desc_len = tu_unaligned_read16((uint8_t const*) p_hid->hid_descriptor + offsetof(tusb_hid_descriptor_hid_t, wReportLength)); + p_hid->report_desc_len = tu_unaligned_read16((uint8_t const *)p_hid->hid_descriptor + offsetof(tusb_hid_descriptor_hid_t, wReportLength)); // Prepare for output endpoint - if (p_hid->ep_out) - { - if ( !usbd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf)) ) - { + if (p_hid->ep_out) { + if (!usbd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf))) { TU_LOG_FAILED(); TU_BREAKPOINT(); } @@ -235,144 +234,120 @@ uint16_t hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint1 // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) -bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) +bool hidd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) { TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE); - uint8_t const hid_itf = get_index_by_itfnum((uint8_t) request->wIndex); + uint8_t const hid_itf = get_index_by_itfnum((uint8_t)request->wIndex); TU_VERIFY(hid_itf < CFG_TUD_HID); - hidd_interface_t* p_hid = &_hidd_itf[hid_itf]; + hidd_interface_t *p_hid = &_hidd_itf[hid_itf]; - if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) - { + if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) { //------------- STD Request -------------// - if ( stage == CONTROL_STAGE_SETUP ) - { - uint8_t const desc_type = tu_u16_high(request->wValue); - //uint8_t const desc_index = tu_u16_low (request->wValue); + if (stage == CONTROL_STAGE_SETUP) { + uint8_t const desc_type = tu_u16_high(request->wValue); + // uint8_t const desc_index = tu_u16_low (request->wValue); - if (request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_HID) - { + if (request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_HID) { TU_VERIFY(p_hid->hid_descriptor); - TU_VERIFY(tud_control_xfer(rhport, request, (void*)(uintptr_t) p_hid->hid_descriptor, p_hid->hid_descriptor->bLength)); - } - else if (request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_REPORT) - { - uint8_t const * desc_report = tud_hid_descriptor_report_cb(hid_itf); - tud_control_xfer(rhport, request, (void*)(uintptr_t) desc_report, p_hid->report_desc_len); - } - else - { + TU_VERIFY(tud_control_xfer(rhport, request, (void *)(uintptr_t)p_hid->hid_descriptor, p_hid->hid_descriptor->bLength)); + } else if (request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_REPORT) { + uint8_t const *desc_report = tud_hid_descriptor_report_cb(hid_itf); + tud_control_xfer(rhport, request, (void *)(uintptr_t)desc_report, p_hid->report_desc_len); + } else { return false; // stall unsupported request } } - } - else if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS) - { + } else if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS) { //------------- Class Specific Request -------------// - switch( request->bRequest ) - { - case HID_REQ_CONTROL_GET_REPORT: - if ( stage == CONTROL_STAGE_SETUP ) - { - uint8_t const report_type = tu_u16_high(request->wValue); - uint8_t const report_id = tu_u16_low(request->wValue); + switch (request->bRequest) { + case HID_REQ_CONTROL_GET_REPORT: + if (stage == CONTROL_STAGE_SETUP) { + uint8_t const report_type = tu_u16_high(request->wValue); + uint8_t const report_id = tu_u16_low(request->wValue); - uint8_t* report_buf = p_hid->epin_buf; - uint16_t req_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); + uint8_t *report_buf = p_hid->ctrl_buf; + uint16_t req_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); - uint16_t xferlen = 0; + uint16_t xferlen = 0; - // If host request a specific Report ID, add ID to as 1 byte of response - if ( (report_id != HID_REPORT_TYPE_INVALID) && (req_len > 1) ) - { - *report_buf++ = report_id; - req_len--; + // If host request a specific Report ID, add ID to as 1 byte of response + if ((report_id != HID_REPORT_TYPE_INVALID) && (req_len > 1)) { + *report_buf++ = report_id; + req_len--; - xferlen++; - } - - xferlen += tud_hid_get_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, report_buf, req_len); - TU_ASSERT( xferlen > 0 ); - - tud_control_xfer(rhport, request, p_hid->epin_buf, xferlen); + xferlen++; } + + xferlen += tud_hid_get_report_cb(hid_itf, report_id, (hid_report_type_t)report_type, report_buf, req_len); + TU_ASSERT(xferlen > 0); + + tud_control_xfer(rhport, request, p_hid->ctrl_buf, xferlen); + } break; - case HID_REQ_CONTROL_SET_REPORT: - if ( stage == CONTROL_STAGE_SETUP ) - { - TU_VERIFY(request->wLength <= sizeof(p_hid->epout_buf)); - tud_control_xfer(rhport, request, p_hid->epout_buf, request->wLength); + case HID_REQ_CONTROL_SET_REPORT: + if (stage == CONTROL_STAGE_SETUP) { + TU_VERIFY(request->wLength <= sizeof(p_hid->ctrl_buf)); + tud_control_xfer(rhport, request, p_hid->ctrl_buf, request->wLength); + } else if (stage == CONTROL_STAGE_ACK) { + uint8_t const report_type = tu_u16_high(request->wValue); + uint8_t const report_id = tu_u16_low(request->wValue); + + uint8_t const *report_buf = p_hid->ctrl_buf; + uint16_t report_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); + + // If host request a specific Report ID, extract report ID in buffer before invoking callback + if ((report_id != HID_REPORT_TYPE_INVALID) && (report_len > 1) && (report_id == report_buf[0])) { + report_buf++; + report_len--; } - else if ( stage == CONTROL_STAGE_ACK ) - { - uint8_t const report_type = tu_u16_high(request->wValue); - uint8_t const report_id = tu_u16_low(request->wValue); - uint8_t const* report_buf = p_hid->epout_buf; - uint16_t report_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); - - // If host request a specific Report ID, extract report ID in buffer before invoking callback - if ( (report_id != HID_REPORT_TYPE_INVALID) && (report_len > 1) && (report_id == report_buf[0]) ) - { - report_buf++; - report_len--; - } - - tud_hid_set_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, report_buf, report_len); - } + tud_hid_set_report_cb(hid_itf, report_id, (hid_report_type_t)report_type, report_buf, report_len); + } break; - case HID_REQ_CONTROL_SET_IDLE: - if ( stage == CONTROL_STAGE_SETUP ) - { - p_hid->idle_rate = tu_u16_high(request->wValue); - if ( tud_hid_set_idle_cb ) - { - // stall request if callback return false - TU_VERIFY( tud_hid_set_idle_cb( hid_itf, p_hid->idle_rate) ); - } - - tud_control_status(rhport, request); + case HID_REQ_CONTROL_SET_IDLE: + if (stage == CONTROL_STAGE_SETUP) { + p_hid->idle_rate = tu_u16_high(request->wValue); + if (tud_hid_set_idle_cb) { + // stall request if callback return false + TU_VERIFY(tud_hid_set_idle_cb(hid_itf, p_hid->idle_rate)); } + + tud_control_status(rhport, request); + } break; - case HID_REQ_CONTROL_GET_IDLE: - if ( stage == CONTROL_STAGE_SETUP ) - { - // TODO idle rate of report - tud_control_xfer(rhport, request, &p_hid->idle_rate, 1); - } + case HID_REQ_CONTROL_GET_IDLE: + if (stage == CONTROL_STAGE_SETUP) { + // TODO idle rate of report + tud_control_xfer(rhport, request, &p_hid->idle_rate, 1); + } break; - case HID_REQ_CONTROL_GET_PROTOCOL: - if ( stage == CONTROL_STAGE_SETUP ) - { - tud_control_xfer(rhport, request, &p_hid->protocol_mode, 1); - } + case HID_REQ_CONTROL_GET_PROTOCOL: + if (stage == CONTROL_STAGE_SETUP) { + tud_control_xfer(rhport, request, &p_hid->protocol_mode, 1); + } break; - case HID_REQ_CONTROL_SET_PROTOCOL: - if ( stage == CONTROL_STAGE_SETUP ) - { - tud_control_status(rhport, request); - } - else if ( stage == CONTROL_STAGE_ACK ) - { - p_hid->protocol_mode = (uint8_t) request->wValue; - if (tud_hid_set_protocol_cb) - { - tud_hid_set_protocol_cb(hid_itf, p_hid->protocol_mode); - } + case HID_REQ_CONTROL_SET_PROTOCOL: + if (stage == CONTROL_STAGE_SETUP) { + tud_control_status(rhport, request); + } else if (stage == CONTROL_STAGE_ACK) { + p_hid->protocol_mode = (uint8_t)request->wValue; + if (tud_hid_set_protocol_cb) { + tud_hid_set_protocol_cb(hid_itf, p_hid->protocol_mode); } + } break; - default: return false; // stall unsupported request + default: + return false; // stall unsupported request } - }else - { + } else { return false; // stall unsupported request } @@ -381,31 +356,43 @@ bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { - (void) result; + (void)result; uint8_t instance = 0; - hidd_interface_t * p_hid = _hidd_itf; + hidd_interface_t *p_hid = _hidd_itf; // Identify which interface to use - for (instance = 0; instance < CFG_TUD_HID; instance++) - { + for (instance = 0; instance < CFG_TUD_HID; instance++) { p_hid = &_hidd_itf[instance]; - if ( (ep_addr == p_hid->ep_out) || (ep_addr == p_hid->ep_in) ) break; + if ((ep_addr == p_hid->ep_out) || (ep_addr == p_hid->ep_in)) + break; } TU_ASSERT(instance < CFG_TUD_HID); + // Check if there was a problem + if (XFER_RESULT_SUCCESS != result) { // Inform application about the issue + if (tud_hid_report_fail_cb) { + tud_hid_report_fail_cb(instance, ep_addr, (uint16_t)xferred_bytes); + } + + // Allow a new transfer to be received if issue happened on an OUT endpoint + if (ep_addr == p_hid->ep_out) { + // Prepare the OUT endpoint to be able to receive a new transfer + TU_ASSERT(usbd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf))); + } + + return true; + } + // Sent report successfully - if (ep_addr == p_hid->ep_in) - { - if (tud_hid_report_complete_cb) - { - tud_hid_report_complete_cb(instance, p_hid->epin_buf, (uint16_t) xferred_bytes); + if (ep_addr == p_hid->ep_in) { + if (tud_hid_report_complete_cb) { + tud_hid_report_complete_cb(instance, p_hid->epin_buf, (uint16_t)xferred_bytes); } } - // Received report - else if (ep_addr == p_hid->ep_out) - { - tud_hid_set_report_cb(instance, 0, HID_REPORT_TYPE_INVALID, p_hid->epout_buf, (uint16_t) xferred_bytes); + // Received report successfully + else if (ep_addr == p_hid->ep_out) { + tud_hid_set_report_cb(instance, 0, HID_REPORT_TYPE_OUTPUT, p_hid->epout_buf, (uint16_t)xferred_bytes); TU_ASSERT(usbd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf))); } diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index 17b24def1..fcbf161c4 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -72,6 +72,16 @@ bool tud_hid_n_keyboard_report(uint8_t instance, uint8_t report_id, uint8_t modi // use template layout report as defined by hid_mouse_report_t bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal); +// ABSOLUTE MOUSE: convenient helper to send absolute mouse report if application +// use template layout report as defined by hid_abs_mouse_report_t +bool tud_hid_n_abs_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal); + + +static inline bool tud_hid_abs_mouse_report(uint8_t report_id, uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal) +{ + return tud_hid_n_abs_mouse_report(0, report_id, buttons, x, y, vertical, horizontal); +} + // Gamepad: convenient helper to send gamepad report if application // use template layout report TUD_HID_REPORT_DESC_GAMEPAD bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons); @@ -118,6 +128,8 @@ TU_ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t instance, uint8_t idle_rate); // Note: For composite reports, report[0] is report ID TU_ATTR_WEAK void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len); +// Invoked when a transfer wasn't successful +TU_ATTR_WEAK void tud_hid_report_fail_cb(uint8_t instance, uint8_t ep_addr, uint16_t len); //--------------------------------------------------------------------+ // Inline Functions @@ -266,6 +278,55 @@ static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y HID_COLLECTION_END , \ HID_COLLECTION_END \ +// Absolute Mouse Report Descriptor Template +#define TUD_HID_REPORT_DESC_ABSMOUSE(...) \ + HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_MOUSE ) ,\ + HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\ + /* Report ID if any */\ + __VA_ARGS__ \ + HID_USAGE ( HID_USAGE_DESKTOP_POINTER ) ,\ + HID_COLLECTION ( HID_COLLECTION_PHYSICAL ) ,\ + HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\ + HID_USAGE_MIN ( 1 ) ,\ + HID_USAGE_MAX ( 5 ) ,\ + HID_LOGICAL_MIN ( 0 ) ,\ + HID_LOGICAL_MAX ( 1 ) ,\ + /* Left, Right, Middle, Backward, Forward buttons */ \ + HID_REPORT_COUNT( 5 ) ,\ + HID_REPORT_SIZE ( 1 ) ,\ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ + /* 3 bit padding */ \ + HID_REPORT_COUNT( 1 ) ,\ + HID_REPORT_SIZE ( 3 ) ,\ + HID_INPUT ( HID_CONSTANT ) ,\ + HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ + /* X, Y absolute position [0, 32767] */ \ + HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\ + HID_LOGICAL_MIN ( 0x00 ) ,\ + HID_LOGICAL_MAX_N( 0x7FFF, 2 ) ,\ + HID_REPORT_SIZE ( 16 ) ,\ + HID_REPORT_COUNT ( 2 ) ,\ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ + /* Vertical wheel scroll [-127, 127] */ \ + HID_USAGE ( HID_USAGE_DESKTOP_WHEEL ) ,\ + HID_LOGICAL_MIN ( 0x81 ) ,\ + HID_LOGICAL_MAX ( 0x7f ) ,\ + HID_REPORT_COUNT( 1 ) ,\ + HID_REPORT_SIZE ( 8 ) ,\ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ) ,\ + HID_USAGE_PAGE ( HID_USAGE_PAGE_CONSUMER ), \ + /* Horizontal wheel scroll [-127, 127] */ \ + HID_USAGE_N ( HID_USAGE_CONSUMER_AC_PAN, 2 ), \ + HID_LOGICAL_MIN ( 0x81 ), \ + HID_LOGICAL_MAX ( 0x7f ), \ + HID_REPORT_COUNT( 1 ), \ + HID_REPORT_SIZE ( 8 ), \ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ), \ + HID_COLLECTION_END , \ + HID_COLLECTION_END \ + // Consumer Control Report Descriptor Template #define TUD_HID_REPORT_DESC_CONSUMER(...) \ HID_USAGE_PAGE ( HID_USAGE_PAGE_CONSUMER ) ,\ @@ -402,15 +463,189 @@ static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y HID_OUTPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ HID_COLLECTION_END \ +// HID Lighting and Illumination Report Descriptor Template +// - 1st parameter is report id (required) +// Creates 6 report ids for lighting HID usages in the following order: +// report_id+0: HID_USAGE_LIGHTING_LAMP_ARRAY_ATTRIBUTES_REPORT +// report_id+1: HID_USAGE_LIGHTING_LAMP_ATTRIBUTES_REQUEST_REPORT +// report_id+2: HID_USAGE_LIGHTING_LAMP_ATTRIBUTES_RESPONSE_REPORT +// report_id+3: HID_USAGE_LIGHTING_LAMP_MULTI_UPDATE_REPORT +// report_id+4: HID_USAGE_LIGHTING_LAMP_RANGE_UPDATE_REPORT +// report_id+5: HID_USAGE_LIGHTING_LAMP_ARRAY_CONTROL_REPORT +#define TUD_HID_REPORT_DESC_LIGHTING(report_id) \ + HID_USAGE_PAGE ( HID_USAGE_PAGE_LIGHTING_AND_ILLUMINATION ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ARRAY ),\ + HID_COLLECTION ( HID_COLLECTION_APPLICATION ),\ + /* Lamp Array Attributes Report */ \ + HID_REPORT_ID (report_id ) \ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ARRAY_ATTRIBUTES_REPORT ),\ + HID_COLLECTION ( HID_COLLECTION_LOGICAL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_COUNT ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 65535, 3 ),\ + HID_REPORT_SIZE ( 16 ),\ + HID_REPORT_COUNT ( 1 ),\ + HID_FEATURE ( HID_CONSTANT | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BOUNDING_BOX_WIDTH_IN_MICROMETERS ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BOUNDING_BOX_HEIGHT_IN_MICROMETERS ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BOUNDING_BOX_DEPTH_IN_MICROMETERS ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ARRAY_KIND ),\ + HID_USAGE ( HID_USAGE_LIGHTING_MIN_UPDATE_INTERVAL_IN_MICROSECONDS ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 2147483647, 3 ),\ + HID_REPORT_SIZE ( 32 ),\ + HID_REPORT_COUNT ( 5 ),\ + HID_FEATURE ( HID_CONSTANT | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_COLLECTION_END ,\ + /* Lamp Attributes Request Report */ \ + HID_REPORT_ID ( report_id + 1 ) \ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ATTRIBUTES_REQUEST_REPORT ),\ + HID_COLLECTION ( HID_COLLECTION_LOGICAL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ID ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 65535, 3 ),\ + HID_REPORT_SIZE ( 16 ),\ + HID_REPORT_COUNT ( 1 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_COLLECTION_END ,\ + /* Lamp Attributes Response Report */ \ + HID_REPORT_ID ( report_id + 2 ) \ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ATTRIBUTES_RESPONSE_REPORT ),\ + HID_COLLECTION ( HID_COLLECTION_LOGICAL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ID ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 65535, 3 ),\ + HID_REPORT_SIZE ( 16 ),\ + HID_REPORT_COUNT ( 1 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_USAGE ( HID_USAGE_LIGHTING_POSITION_X_IN_MICROMETERS ),\ + HID_USAGE ( HID_USAGE_LIGHTING_POSITION_Y_IN_MICROMETERS ),\ + HID_USAGE ( HID_USAGE_LIGHTING_POSITION_Z_IN_MICROMETERS ),\ + HID_USAGE ( HID_USAGE_LIGHTING_UPDATE_LATENCY_IN_MICROSECONDS ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_PURPOSES ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 2147483647, 3 ),\ + HID_REPORT_SIZE ( 32 ),\ + HID_REPORT_COUNT ( 5 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_LEVEL_COUNT ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_LEVEL_COUNT ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_LEVEL_COUNT ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_LEVEL_COUNT ),\ + HID_USAGE ( HID_USAGE_LIGHTING_IS_PROGRAMMABLE ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INPUT_BINDING ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 255, 2 ),\ + HID_REPORT_SIZE ( 8 ),\ + HID_REPORT_COUNT ( 6 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_COLLECTION_END ,\ + /* Lamp Multi-Update Report */ \ + HID_REPORT_ID ( report_id + 3 ) \ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_MULTI_UPDATE_REPORT ),\ + HID_COLLECTION ( HID_COLLECTION_LOGICAL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_COUNT ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_UPDATE_FLAGS ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX ( 8 ),\ + HID_REPORT_SIZE ( 8 ),\ + HID_REPORT_COUNT ( 2 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ID ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 65535, 3 ),\ + HID_REPORT_SIZE ( 16 ),\ + HID_REPORT_COUNT ( 8 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 255, 2 ),\ + HID_REPORT_SIZE ( 8 ),\ + HID_REPORT_COUNT ( 32 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_COLLECTION_END ,\ + /* Lamp Range Update Report */ \ + HID_REPORT_ID ( report_id + 4 ) \ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_RANGE_UPDATE_REPORT ),\ + HID_COLLECTION ( HID_COLLECTION_LOGICAL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_UPDATE_FLAGS ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX ( 8 ),\ + HID_REPORT_SIZE ( 8 ),\ + HID_REPORT_COUNT ( 1 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ID_START ),\ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ID_END ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 65535, 3 ),\ + HID_REPORT_SIZE ( 16 ),\ + HID_REPORT_COUNT ( 2 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_USAGE ( HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX_N ( 255, 2 ),\ + HID_REPORT_SIZE ( 8 ),\ + HID_REPORT_COUNT ( 4 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_COLLECTION_END ,\ + /* Lamp Array Control Report */ \ + HID_REPORT_ID ( report_id + 5 ) \ + HID_USAGE ( HID_USAGE_LIGHTING_LAMP_ARRAY_CONTROL_REPORT ),\ + HID_COLLECTION ( HID_COLLECTION_LOGICAL ),\ + HID_USAGE ( HID_USAGE_LIGHTING_AUTONOMOUS_MODE ),\ + HID_LOGICAL_MIN ( 0 ),\ + HID_LOGICAL_MAX ( 1 ),\ + HID_REPORT_SIZE ( 8 ),\ + HID_REPORT_COUNT ( 1 ),\ + HID_FEATURE ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_COLLECTION_END ,\ + HID_COLLECTION_END \ + //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ void hidd_init (void); +bool hidd_deinit (void); void hidd_reset (uint8_t rhport); uint16_t hidd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); bool hidd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); + #ifdef __cplusplus } #endif diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 4253170d4..115a8a4df 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -29,7 +29,7 @@ #if (CFG_TUH_ENABLED && CFG_TUH_HID) #include "host/usbh.h" -#include "host/usbh_classdriver.h" +#include "host/usbh_pvt.h" #include "hid_host.h" @@ -39,22 +39,22 @@ #endif #define TU_LOG_DRV(...) TU_LOG(CFG_TUH_HID_LOG_LEVEL, __VA_ARGS__) + //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ - -typedef struct -{ +typedef struct { uint8_t daddr; uint8_t itf_num; uint8_t ep_in; uint8_t ep_out; + bool mounted; // Enumeration is complete uint8_t itf_protocol; // None, Keyboard, Mouse uint8_t protocol_mode; // Boot (0) or Report protocol (1) - uint8_t report_desc_type; + uint8_t report_desc_type; uint16_t report_desc_len; uint16_t epin_size; @@ -67,81 +67,62 @@ typedef struct CFG_TUH_MEM_SECTION tu_static hidh_interface_t _hidh_itf[CFG_TUH_HID]; +tu_static uint8_t _hidh_default_protocol = HID_PROTOCOL_BOOT; + //--------------------------------------------------------------------+ // Helper //--------------------------------------------------------------------+ - -TU_ATTR_ALWAYS_INLINE static inline -hidh_interface_t* get_hid_itf(uint8_t daddr, uint8_t idx) -{ +TU_ATTR_ALWAYS_INLINE static inline hidh_interface_t* get_hid_itf(uint8_t daddr, uint8_t idx) { TU_ASSERT(daddr > 0 && idx < CFG_TUH_HID, NULL); hidh_interface_t* p_hid = &_hidh_itf[idx]; return (p_hid->daddr == daddr) ? p_hid : NULL; } // Get instance ID by endpoint address -static uint8_t get_idx_by_epaddr(uint8_t daddr, uint8_t ep_addr) -{ - for ( uint8_t idx = 0; idx < CFG_TUH_HID; idx++ ) - { - hidh_interface_t const * p_hid = &_hidh_itf[idx]; - - if ( p_hid->daddr == daddr && - (p_hid->ep_in == ep_addr || p_hid->ep_out == ep_addr) ) - { +static uint8_t get_idx_by_epaddr(uint8_t daddr, uint8_t ep_addr) { + for (uint8_t idx = 0; idx < CFG_TUH_HID; idx++) { + hidh_interface_t const* p_hid = &_hidh_itf[idx]; + if (p_hid->daddr == daddr && + (p_hid->ep_in == ep_addr || p_hid->ep_out == ep_addr)) { return idx; } } - return TUSB_INDEX_INVALID_8; } -static hidh_interface_t* find_new_itf(void) -{ - for(uint8_t i=0; imounted; } -bool tuh_hid_itf_get_info(uint8_t daddr, uint8_t idx, tuh_itf_info_t* info) -{ +bool tuh_hid_itf_get_info(uint8_t daddr, uint8_t idx, tuh_itf_info_t* info) { hidh_interface_t* p_hid = get_hid_itf(daddr, idx); TU_VERIFY(p_hid && info); @@ -149,34 +130,30 @@ bool tuh_hid_itf_get_info(uint8_t daddr, uint8_t idx, tuh_itf_info_t* info) // re-construct descriptor tusb_desc_interface_t* desc = &info->desc; - desc->bLength = sizeof(tusb_desc_interface_t); - desc->bDescriptorType = TUSB_DESC_INTERFACE; + desc->bLength = sizeof(tusb_desc_interface_t); + desc->bDescriptorType = TUSB_DESC_INTERFACE; - desc->bInterfaceNumber = p_hid->itf_num; - desc->bAlternateSetting = 0; - desc->bNumEndpoints = (uint8_t) ((p_hid->ep_in ? 1u : 0u) + (p_hid->ep_out ? 1u : 0u)); - desc->bInterfaceClass = TUSB_CLASS_HID; + desc->bInterfaceNumber = p_hid->itf_num; + desc->bAlternateSetting = 0; + desc->bNumEndpoints = (uint8_t) ((p_hid->ep_in ? 1u : 0u) + (p_hid->ep_out ? 1u : 0u)); + desc->bInterfaceClass = TUSB_CLASS_HID; desc->bInterfaceSubClass = (p_hid->itf_protocol ? HID_SUBCLASS_BOOT : HID_SUBCLASS_NONE); desc->bInterfaceProtocol = p_hid->itf_protocol; - desc->iInterface = 0; // not used yet + desc->iInterface = 0; // not used yet return true; } -uint8_t tuh_hid_itf_get_index(uint8_t daddr, uint8_t itf_num) -{ - for ( uint8_t idx = 0; idx < CFG_TUH_HID; idx++ ) - { - hidh_interface_t const * p_hid = &_hidh_itf[idx]; - - if ( p_hid->daddr == daddr && p_hid->itf_num == itf_num) return idx; +uint8_t tuh_hid_itf_get_index(uint8_t daddr, uint8_t itf_num) { + for (uint8_t idx = 0; idx < CFG_TUH_HID; idx++) { + hidh_interface_t const* p_hid = &_hidh_itf[idx]; + if (p_hid->daddr == daddr && p_hid->itf_num == itf_num) return idx; } return TUSB_INDEX_INVALID_8; } -uint8_t tuh_hid_interface_protocol(uint8_t daddr, uint8_t idx) -{ +uint8_t tuh_hid_interface_protocol(uint8_t daddr, uint8_t idx) { hidh_interface_t* p_hid = get_hid_itf(daddr, idx); return p_hid ? p_hid->itf_protocol : 0; } @@ -184,150 +161,179 @@ uint8_t tuh_hid_interface_protocol(uint8_t daddr, uint8_t idx) //--------------------------------------------------------------------+ // Control Endpoint API //--------------------------------------------------------------------+ - -uint8_t tuh_hid_get_protocol(uint8_t daddr, uint8_t idx) -{ +uint8_t tuh_hid_get_protocol(uint8_t daddr, uint8_t idx) { hidh_interface_t* p_hid = get_hid_itf(daddr, idx); return p_hid ? p_hid->protocol_mode : 0; } -static void set_protocol_complete(tuh_xfer_t* xfer) -{ +static void set_protocol_complete(tuh_xfer_t* xfer) { uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); - uint8_t const daddr = xfer->daddr; - uint8_t const idx = tuh_hid_itf_get_index(daddr, itf_num); + uint8_t const daddr = xfer->daddr; + uint8_t const idx = tuh_hid_itf_get_index(daddr, itf_num); hidh_interface_t* p_hid = get_hid_itf(daddr, idx); - TU_VERIFY(p_hid, ); + TU_VERIFY(p_hid,); - if (XFER_RESULT_SUCCESS == xfer->result) - { + if (XFER_RESULT_SUCCESS == xfer->result) { p_hid->protocol_mode = (uint8_t) tu_le16toh(xfer->setup->wValue); } - if (tuh_hid_set_protocol_complete_cb) - { + if (tuh_hid_set_protocol_complete_cb) { tuh_hid_set_protocol_complete_cb(daddr, idx, p_hid->protocol_mode); } } -static bool _hidh_set_protocol(uint8_t daddr, uint8_t itf_num, uint8_t protocol, tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +void tuh_hid_set_default_protocol(uint8_t protocol) { + _hidh_default_protocol = protocol; +} + +static bool _hidh_set_protocol(uint8_t daddr, uint8_t itf_num, uint8_t protocol, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG_DRV("HID Set Protocol = %d\r\n", protocol); - tusb_control_request_t const request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_OUT - }, - .bRequest = HID_REQ_CONTROL_SET_PROTOCOL, - .wValue = protocol, - .wIndex = itf_num, - .wLength = 0 + tusb_control_request_t const request = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HID_REQ_CONTROL_SET_PROTOCOL, + .wValue = protocol, + .wIndex = itf_num, + .wLength = 0 }; - tuh_xfer_t xfer = - { - .daddr = daddr, - .ep_addr = 0, - .setup = &request, - .buffer = NULL, - .complete_cb = complete_cb, - .user_data = user_data + tuh_xfer_t xfer = { + .daddr = daddr, + .ep_addr = 0, + .setup = &request, + .buffer = NULL, + .complete_cb = complete_cb, + .user_data = user_data }; return tuh_control_xfer(&xfer); } -bool tuh_hid_set_protocol(uint8_t daddr, uint8_t idx, uint8_t protocol) -{ +bool tuh_hid_set_protocol(uint8_t daddr, uint8_t idx, uint8_t protocol) { hidh_interface_t* p_hid = get_hid_itf(daddr, idx); TU_VERIFY(p_hid && p_hid->itf_protocol != HID_ITF_PROTOCOL_NONE); return _hidh_set_protocol(daddr, p_hid->itf_num, protocol, set_protocol_complete, 0); } -static void set_report_complete(tuh_xfer_t* xfer) -{ - TU_LOG_DRV("HID Set Report complete\r\n"); +static void get_report_complete(tuh_xfer_t* xfer) { + TU_LOG_DRV("HID Get Report complete\r\n"); - if (tuh_hid_set_report_complete_cb) - { + if (tuh_hid_get_report_complete_cb) { uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); - uint8_t const idx = tuh_hid_itf_get_index(xfer->daddr, itf_num); + uint8_t const idx = tuh_hid_itf_get_index(xfer->daddr, itf_num); uint8_t const report_type = tu_u16_high(xfer->setup->wValue); - uint8_t const report_id = tu_u16_low(xfer->setup->wValue); + uint8_t const report_id = tu_u16_low(xfer->setup->wValue); + + tuh_hid_get_report_complete_cb(xfer->daddr, idx, report_id, report_type, + (xfer->result == XFER_RESULT_SUCCESS) ? xfer->setup->wLength : 0); + } +} + +bool tuh_hid_get_report(uint8_t daddr, uint8_t idx, uint8_t report_id, uint8_t report_type, void* report, uint16_t len) { + hidh_interface_t* p_hid = get_hid_itf(daddr, idx); + TU_VERIFY(p_hid); + TU_LOG_DRV("HID Get Report: id = %u, type = %u, len = %u\r\n", report_id, report_type, len); + + tusb_control_request_t const request = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN + }, + .bRequest = HID_REQ_CONTROL_GET_REPORT, + .wValue = tu_htole16(tu_u16(report_type, report_id)), + .wIndex = tu_htole16((uint16_t) p_hid->itf_num), + .wLength = len + }; + + tuh_xfer_t xfer = { + .daddr = daddr, + .ep_addr = 0, + .setup = &request, + .buffer = report, + .complete_cb = get_report_complete, + .user_data = 0 + }; + + return tuh_control_xfer(&xfer); +} + +static void set_report_complete(tuh_xfer_t* xfer) { + TU_LOG_DRV("HID Set Report complete\r\n"); + + if (tuh_hid_set_report_complete_cb) { + uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); + uint8_t const idx = tuh_hid_itf_get_index(xfer->daddr, itf_num); + + uint8_t const report_type = tu_u16_high(xfer->setup->wValue); + uint8_t const report_id = tu_u16_low(xfer->setup->wValue); tuh_hid_set_report_complete_cb(xfer->daddr, idx, report_id, report_type, (xfer->result == XFER_RESULT_SUCCESS) ? xfer->setup->wLength : 0); } } -bool tuh_hid_set_report(uint8_t daddr, uint8_t idx, uint8_t report_id, uint8_t report_type, void* report, uint16_t len) -{ +bool tuh_hid_set_report(uint8_t daddr, uint8_t idx, uint8_t report_id, uint8_t report_type, void* report, uint16_t len) { hidh_interface_t* p_hid = get_hid_itf(daddr, idx); TU_VERIFY(p_hid); - TU_LOG_DRV("HID Set Report: id = %u, type = %u, len = %u\r\n", report_id, report_type, len); - tusb_control_request_t const request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_OUT - }, - .bRequest = HID_REQ_CONTROL_SET_REPORT, - .wValue = tu_htole16(tu_u16(report_type, report_id)), - .wIndex = tu_htole16((uint16_t)p_hid->itf_num), - .wLength = len + tusb_control_request_t const request = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HID_REQ_CONTROL_SET_REPORT, + .wValue = tu_htole16(tu_u16(report_type, report_id)), + .wIndex = tu_htole16((uint16_t) p_hid->itf_num), + .wLength = len }; - tuh_xfer_t xfer = - { - .daddr = daddr, - .ep_addr = 0, - .setup = &request, - .buffer = report, - .complete_cb = set_report_complete, - .user_data = 0 + tuh_xfer_t xfer = { + .daddr = daddr, + .ep_addr = 0, + .setup = &request, + .buffer = report, + .complete_cb = set_report_complete, + .user_data = 0 }; return tuh_control_xfer(&xfer); } -static bool _hidh_set_idle(uint8_t daddr, uint8_t itf_num, uint16_t idle_rate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +static bool _hidh_set_idle(uint8_t daddr, uint8_t itf_num, uint16_t idle_rate, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { // SET IDLE request, device can stall if not support this request TU_LOG_DRV("HID Set Idle \r\n"); - tusb_control_request_t const request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_OUT - }, - .bRequest = HID_REQ_CONTROL_SET_IDLE, - .wValue = tu_htole16(idle_rate), - .wIndex = tu_htole16((uint16_t)itf_num), - .wLength = 0 + tusb_control_request_t const request = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HID_REQ_CONTROL_SET_IDLE, + .wValue = tu_htole16(idle_rate), + .wIndex = tu_htole16((uint16_t) itf_num), + .wLength = 0 }; - tuh_xfer_t xfer = - { - .daddr = daddr, - .ep_addr = 0, - .setup = &request, - .buffer = NULL, - .complete_cb = complete_cb, - .user_data = user_data + tuh_xfer_t xfer = { + .daddr = daddr, + .ep_addr = 0, + .setup = &request, + .buffer = NULL, + .complete_cb = complete_cb, + .user_data = user_data }; return tuh_control_xfer(&xfer); @@ -338,68 +344,60 @@ static bool _hidh_set_idle(uint8_t daddr, uint8_t itf_num, uint16_t idle_rate, t //--------------------------------------------------------------------+ // Check if HID interface is ready to receive report -bool tuh_hid_receive_ready(uint8_t dev_addr, uint8_t idx) -{ +bool tuh_hid_receive_ready(uint8_t dev_addr, uint8_t idx) { hidh_interface_t* p_hid = get_hid_itf(dev_addr, idx); TU_VERIFY(p_hid); - return !usbh_edpt_busy(dev_addr, p_hid->ep_in); } -bool tuh_hid_receive_report(uint8_t daddr, uint8_t idx) -{ +bool tuh_hid_receive_report(uint8_t daddr, uint8_t idx) { hidh_interface_t* p_hid = get_hid_itf(daddr, idx); TU_VERIFY(p_hid); // claim endpoint - TU_VERIFY( usbh_edpt_claim(daddr, p_hid->ep_in) ); + TU_VERIFY(usbh_edpt_claim(daddr, p_hid->ep_in)); - if ( !usbh_edpt_xfer(daddr, p_hid->ep_in, p_hid->epin_buf, p_hid->epin_size) ) - { + if (!usbh_edpt_xfer(daddr, p_hid->ep_in, p_hid->epin_buf, p_hid->epin_size)) { usbh_edpt_release(daddr, p_hid->ep_in); return false; } return true; } - -bool tuh_hid_send_ready(uint8_t dev_addr, uint8_t idx) -{ +bool tuh_hid_receive_abort(uint8_t dev_addr, uint8_t idx) { hidh_interface_t* p_hid = get_hid_itf(dev_addr, idx); TU_VERIFY(p_hid); + return tuh_edpt_abort_xfer(dev_addr, p_hid->ep_in); +} +bool tuh_hid_send_ready(uint8_t dev_addr, uint8_t idx) { + hidh_interface_t* p_hid = get_hid_itf(dev_addr, idx); + TU_VERIFY(p_hid); return !usbh_edpt_busy(dev_addr, p_hid->ep_out); } -bool tuh_hid_send_report(uint8_t daddr, uint8_t idx, uint8_t report_id, const void* report, uint16_t len) -{ +bool tuh_hid_send_report(uint8_t daddr, uint8_t idx, uint8_t report_id, const void* report, uint16_t len) { TU_LOG_DRV("HID Send Report %d\r\n", report_id); hidh_interface_t* p_hid = get_hid_itf(daddr, idx); TU_VERIFY(p_hid); - if (p_hid->ep_out == 0) - { + if (p_hid->ep_out == 0) { // This HID does not have an out endpoint (other than control) return false; - } - else if (len > CFG_TUH_HID_EPOUT_BUFSIZE || - (report_id != 0 && len > (CFG_TUH_HID_EPOUT_BUFSIZE - 1))) - { + } else if (len > CFG_TUH_HID_EPOUT_BUFSIZE || + (report_id != 0 && len > (CFG_TUH_HID_EPOUT_BUFSIZE - 1))) { // ep_out buffer is not large enough to hold contents return false; } // claim endpoint - TU_VERIFY( usbh_edpt_claim(daddr, p_hid->ep_out) ); + TU_VERIFY(usbh_edpt_claim(daddr, p_hid->ep_out)); - if (report_id == 0) - { + if (report_id == 0) { // No report ID in transmission memcpy(&p_hid->epout_buf[0], report, len); - } - else - { + } else { p_hid->epout_buf[0] = report_id; memcpy(&p_hid->epout_buf[1], report, len); ++len; // 1 more byte for report_id @@ -407,8 +405,7 @@ bool tuh_hid_send_report(uint8_t daddr, uint8_t idx, uint8_t report_id, const vo TU_LOG3_MEM(p_hid->epout_buf, len, 2); - if ( !usbh_edpt_xfer(daddr, p_hid->ep_out, p_hid->epout_buf, len) ) - { + if (!usbh_edpt_xfer(daddr, p_hid->ep_out, p_hid->epout_buf, len)) { usbh_edpt_release(daddr, p_hid->ep_out); return false; } @@ -419,13 +416,17 @@ bool tuh_hid_send_report(uint8_t daddr, uint8_t idx, uint8_t report_id, const vo //--------------------------------------------------------------------+ // USBH API //--------------------------------------------------------------------+ -void hidh_init(void) -{ +bool hidh_init(void) { + TU_LOG_DRV("sizeof(hidh_interface_t) = %u\r\n", sizeof(hidh_interface_t)); tu_memclr(_hidh_itf, sizeof(_hidh_itf)); + return true; } -bool hidh_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) -{ +bool hidh_deinit(void) { + return true; +} + +bool hidh_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) result; uint8_t const dir = tu_edpt_dir(ep_addr); @@ -434,29 +435,26 @@ bool hidh_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t hidh_interface_t* p_hid = get_hid_itf(daddr, idx); TU_VERIFY(p_hid); - if ( dir == TUSB_DIR_IN ) - { + if (dir == TUSB_DIR_IN) { TU_LOG_DRV(" Get Report callback (%u, %u)\r\n", daddr, idx); TU_LOG3_MEM(p_hid->epin_buf, xferred_bytes, 2); tuh_hid_report_received_cb(daddr, idx, p_hid->epin_buf, (uint16_t) xferred_bytes); - }else - { - if (tuh_hid_report_sent_cb) tuh_hid_report_sent_cb(daddr, idx, p_hid->epout_buf, (uint16_t) xferred_bytes); + } else { + if (tuh_hid_report_sent_cb) { + tuh_hid_report_sent_cb(daddr, idx, p_hid->epout_buf, (uint16_t) xferred_bytes); + } } return true; } -void hidh_close(uint8_t daddr) -{ - for(uint8_t i=0; idaddr == daddr) - { + if (p_hid->daddr == daddr) { TU_LOG_DRV(" HIDh close addr = %u index = %u\r\n", daddr, i); - if(tuh_hid_umount_cb) tuh_hid_umount_cb(daddr, i); - p_hid->daddr = 0; + if (tuh_hid_umount_cb) tuh_hid_umount_cb(daddr, i); + tu_memclr(p_hid, sizeof(hidh_interface_t)); } } } @@ -465,25 +463,22 @@ void hidh_close(uint8_t daddr) // Enumeration //--------------------------------------------------------------------+ -bool hidh_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *desc_itf, uint16_t max_len) -{ +bool hidh_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const* desc_itf, uint16_t max_len) { (void) rhport; (void) max_len; TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass); - TU_LOG_DRV("[%u] HID opening Interface %u\r\n", daddr, desc_itf->bInterfaceNumber); // len = interface + hid + n*endpoints uint16_t const drv_len = (uint16_t) (sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); TU_ASSERT(max_len >= drv_len); - - uint8_t const *p_desc = (uint8_t const *) desc_itf; + uint8_t const* p_desc = (uint8_t const*) desc_itf; //------------- HID descriptor -------------// p_desc = tu_desc_next(p_desc); - tusb_hid_descriptor_hid_t const *desc_hid = (tusb_hid_descriptor_hid_t const *) p_desc; + tusb_hid_descriptor_hid_t const* desc_hid = (tusb_hid_descriptor_hid_t const*) p_desc; TU_ASSERT(HID_DESC_TYPE_HID == desc_hid->bDescriptorType); hidh_interface_t* p_hid = find_new_itf(); @@ -492,38 +487,33 @@ bool hidh_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *desc_ //------------- Endpoint Descriptors -------------// p_desc = tu_desc_next(p_desc); - tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc; + tusb_desc_endpoint_t const* desc_ep = (tusb_desc_endpoint_t const*) p_desc; - for(int i = 0; i < desc_itf->bNumEndpoints; i++) - { + for (int i = 0; i < desc_itf->bNumEndpoints; i++) { TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType); - TU_ASSERT( tuh_edpt_open(daddr, desc_ep) ); + TU_ASSERT(tuh_edpt_open(daddr, desc_ep)); - if(tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) - { - p_hid->ep_in = desc_ep->bEndpointAddress; + if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { + p_hid->ep_in = desc_ep->bEndpointAddress; p_hid->epin_size = tu_edpt_packet_size(desc_ep); - } - else - { - p_hid->ep_out = desc_ep->bEndpointAddress; + } else { + p_hid->ep_out = desc_ep->bEndpointAddress; p_hid->epout_size = tu_edpt_packet_size(desc_ep); } p_desc = tu_desc_next(p_desc); - desc_ep = (tusb_desc_endpoint_t const *) p_desc; + desc_ep = (tusb_desc_endpoint_t const*) p_desc; } - p_hid->itf_num = desc_itf->bInterfaceNumber; + p_hid->itf_num = desc_itf->bInterfaceNumber; // Assume bNumDescriptors = 1 p_hid->report_desc_type = desc_hid->bReportType; - p_hid->report_desc_len = tu_unaligned_read16(&desc_hid->wReportLength); + p_hid->report_desc_len = tu_unaligned_read16(&desc_hid->wReportLength); // Per HID Specs: default is Report protocol, though we will force Boot protocol when set_config - p_hid->protocol_mode = HID_PROTOCOL_BOOT; - if ( HID_SUBCLASS_BOOT == desc_itf->bInterfaceSubClass ) - { + p_hid->protocol_mode = _hidh_default_protocol; + if (HID_SUBCLASS_BOOT == desc_itf->bInterfaceSubClass) { p_hid->itf_protocol = desc_itf->bInterfaceProtocol; } @@ -544,15 +534,14 @@ enum { static void config_driver_mount_complete(uint8_t daddr, uint8_t idx, uint8_t const* desc_report, uint16_t desc_len); static void process_set_config(tuh_xfer_t* xfer); -bool hidh_set_config(uint8_t daddr, uint8_t itf_num) -{ +bool hidh_set_config(uint8_t daddr, uint8_t itf_num) { tusb_control_request_t request; request.wIndex = tu_htole16((uint16_t) itf_num); tuh_xfer_t xfer; - xfer.daddr = daddr; - xfer.result = XFER_RESULT_SUCCESS; - xfer.setup = &request; + xfer.daddr = daddr; + xfer.result = XFER_RESULT_SUCCESS; + xfer.setup = &request; xfer.user_data = CONFG_SET_IDLE; // fake request to kick-off the set config process @@ -561,71 +550,68 @@ bool hidh_set_config(uint8_t daddr, uint8_t itf_num) return true; } -static void process_set_config(tuh_xfer_t* xfer) -{ +static void process_set_config(tuh_xfer_t* xfer) { // Stall is a valid response for SET_IDLE, sometime SET_PROTOCOL as well // therefore we could ignore its result - if ( !(xfer->setup->bRequest == HID_REQ_CONTROL_SET_IDLE || - xfer->setup->bRequest == HID_REQ_CONTROL_SET_PROTOCOL) ) - { - TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, ); + if (!(xfer->setup->bRequest == HID_REQ_CONTROL_SET_IDLE || + xfer->setup->bRequest == HID_REQ_CONTROL_SET_PROTOCOL)) { + TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS,); } uintptr_t const state = xfer->user_data; uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); - uint8_t const daddr = xfer->daddr; + uint8_t const daddr = xfer->daddr; - uint8_t const idx = tuh_hid_itf_get_index(daddr, itf_num); + uint8_t const idx = tuh_hid_itf_get_index(daddr, itf_num); hidh_interface_t* p_hid = get_hid_itf(daddr, idx); - TU_VERIFY(p_hid, ); + TU_VERIFY(p_hid,); - switch(state) - { - case CONFG_SET_IDLE: - { + switch (state) { + case CONFG_SET_IDLE: { // Idle rate = 0 mean only report when there is changes const uint16_t idle_rate = 0; - const uintptr_t next_state = (p_hid->itf_protocol != HID_ITF_PROTOCOL_NONE) ? CONFIG_SET_PROTOCOL : CONFIG_GET_REPORT_DESC; + const uintptr_t next_state = (p_hid->itf_protocol != HID_ITF_PROTOCOL_NONE) + ? CONFIG_SET_PROTOCOL : CONFIG_GET_REPORT_DESC; _hidh_set_idle(daddr, itf_num, idle_rate, process_set_config, next_state); + break; } - break; case CONFIG_SET_PROTOCOL: - _hidh_set_protocol(daddr, p_hid->itf_num, HID_PROTOCOL_BOOT, process_set_config, CONFIG_GET_REPORT_DESC); - break; + _hidh_set_protocol(daddr, p_hid->itf_num, _hidh_default_protocol, process_set_config, CONFIG_GET_REPORT_DESC); + break; case CONFIG_GET_REPORT_DESC: // Get Report Descriptor if possible // using usbh enumeration buffer since report descriptor can be very long - if( p_hid->report_desc_len > CFG_TUH_ENUMERATION_BUFSIZE ) - { + if (p_hid->report_desc_len > CFG_TUH_ENUMERATION_BUFSIZE) { TU_LOG_DRV("HID Skip Report Descriptor since it is too large %u bytes\r\n", p_hid->report_desc_len); // Driver is mounted without report descriptor config_driver_mount_complete(daddr, idx, NULL, 0); - }else - { - tuh_descriptor_get_hid_report(daddr, itf_num, p_hid->report_desc_type, 0, usbh_get_enum_buf(), p_hid->report_desc_len, process_set_config, CONFIG_COMPLETE); + } else { + tuh_descriptor_get_hid_report(daddr, itf_num, p_hid->report_desc_type, 0, + usbh_get_enum_buf(), p_hid->report_desc_len, + process_set_config, CONFIG_COMPLETE); } break; - case CONFIG_COMPLETE: - { + case CONFIG_COMPLETE: { uint8_t const* desc_report = usbh_get_enum_buf(); - uint16_t const desc_len = tu_le16toh(xfer->setup->wLength); + uint16_t const desc_len = tu_le16toh(xfer->setup->wLength); config_driver_mount_complete(daddr, idx, desc_report, desc_len); + break; } - break; - default: break; + default: + break; } } -static void config_driver_mount_complete(uint8_t daddr, uint8_t idx, uint8_t const* desc_report, uint16_t desc_len) -{ +static void config_driver_mount_complete(uint8_t daddr, uint8_t idx, uint8_t const* desc_report, uint16_t desc_len) { hidh_interface_t* p_hid = get_hid_itf(daddr, idx); - TU_VERIFY(p_hid, ); + TU_VERIFY(p_hid,); + p_hid->mounted = true; // enumeration is complete if (tuh_hid_mount_cb) tuh_hid_mount_cb(daddr, idx, desc_report, desc_len); @@ -638,21 +624,19 @@ static void config_driver_mount_complete(uint8_t daddr, uint8_t idx, uint8_t con // Report Descriptor Parser //--------------------------------------------------------------------+ -uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* report_info_arr, uint8_t arr_count, uint8_t const* desc_report, uint16_t desc_len) -{ +uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* report_info_arr, uint8_t arr_count, + uint8_t const* desc_report, uint16_t desc_len) { // Report Item 6.2.2.2 USB HID 1.11 - union TU_ATTR_PACKED - { + union TU_ATTR_PACKED { uint8_t byte; - struct TU_ATTR_PACKED - { - uint8_t size : 2; - uint8_t type : 2; - uint8_t tag : 4; + struct TU_ATTR_PACKED { + uint8_t size : 2; + uint8_t type : 2; + uint8_t tag : 4; }; } header; - tu_memclr(report_info_arr, arr_count*sizeof(tuh_hid_report_info_t)); + tu_memclr(report_info_arr, arr_count * sizeof(tuh_hid_report_info_t)); uint8_t report_num = 0; tuh_hid_report_info_t* info = report_info_arr; @@ -662,114 +646,105 @@ uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* report_info_arr, // uint8_t ri_report_size = 0; uint8_t ri_collection_depth = 0; - - while(desc_len && report_num < arr_count) - { + while (desc_len && report_num < arr_count) { header.byte = *desc_report++; desc_len--; - uint8_t const tag = header.tag; + uint8_t const tag = header.tag; uint8_t const type = header.type; uint8_t const size = header.size; uint8_t const data8 = desc_report[0]; TU_LOG(3, "tag = %d, type = %d, size = %d, data = ", tag, type, size); - for(uint32_t i=0; iusage_page, desc_report, size); - break; + if (ri_collection_depth == 0) memcpy(&info->usage_page, desc_report, size); + break; - case RI_GLOBAL_LOGICAL_MIN : break; - case RI_GLOBAL_LOGICAL_MAX : break; - case RI_GLOBAL_PHYSICAL_MIN : break; - case RI_GLOBAL_PHYSICAL_MAX : break; + case RI_GLOBAL_LOGICAL_MIN: break; + case RI_GLOBAL_LOGICAL_MAX: break; + case RI_GLOBAL_PHYSICAL_MIN: break; + case RI_GLOBAL_PHYSICAL_MAX: break; case RI_GLOBAL_REPORT_ID: info->report_id = data8; - break; + break; case RI_GLOBAL_REPORT_SIZE: // ri_report_size = data8; - break; + break; case RI_GLOBAL_REPORT_COUNT: // ri_report_count = data8; - break; + break; - case RI_GLOBAL_UNIT_EXPONENT : break; - case RI_GLOBAL_UNIT : break; - case RI_GLOBAL_PUSH : break; - case RI_GLOBAL_POP : break; + case RI_GLOBAL_UNIT_EXPONENT: break; + case RI_GLOBAL_UNIT: break; + case RI_GLOBAL_PUSH: break; + case RI_GLOBAL_POP: break; default: break; } - break; + break; case RI_TYPE_LOCAL: - switch(tag) - { + switch (tag) { case RI_LOCAL_USAGE: // only take in account the "usage" before starting REPORT ID - if ( ri_collection_depth == 0 ) info->usage = data8; - break; + if (ri_collection_depth == 0) info->usage = data8; + break; - case RI_LOCAL_USAGE_MIN : break; - case RI_LOCAL_USAGE_MAX : break; - case RI_LOCAL_DESIGNATOR_INDEX : break; - case RI_LOCAL_DESIGNATOR_MIN : break; - case RI_LOCAL_DESIGNATOR_MAX : break; - case RI_LOCAL_STRING_INDEX : break; - case RI_LOCAL_STRING_MIN : break; - case RI_LOCAL_STRING_MAX : break; - case RI_LOCAL_DELIMITER : break; + case RI_LOCAL_USAGE_MIN: break; + case RI_LOCAL_USAGE_MAX: break; + case RI_LOCAL_DESIGNATOR_INDEX: break; + case RI_LOCAL_DESIGNATOR_MIN: break; + case RI_LOCAL_DESIGNATOR_MAX: break; + case RI_LOCAL_STRING_INDEX: break; + case RI_LOCAL_STRING_MIN: break; + case RI_LOCAL_STRING_MAX: break; + case RI_LOCAL_DELIMITER: break; default: break; } - break; + break; - // error + // error default: break; } desc_report += size; - desc_len -= size; + desc_len -= size; } - for ( uint8_t i = 0; i < report_num; i++ ) - { - info = report_info_arr+i; + for (uint8_t i = 0; i < report_num; i++) { + info = report_info_arr + i; TU_LOG_DRV("%u: id = %u, usage_page = %u, usage = %u\r\n", i, info->report_id, info->usage_page, info->usage); } diff --git a/src/class/hid/hid_host.h b/src/class/hid/hid_host.h index 08ad421d2..9681c704b 100644 --- a/src/class/hid/hid_host.h +++ b/src/class/hid/hid_host.h @@ -30,7 +30,7 @@ #include "hid.h" #ifdef __cplusplus - extern "C" { +extern "C" { #endif //--------------------------------------------------------------------+ @@ -47,10 +47,9 @@ #endif -typedef struct -{ - uint8_t report_id; - uint8_t usage; +typedef struct { + uint8_t report_id; + uint8_t usage; uint16_t usage_page; // TODO still use the endpoint size for now @@ -86,7 +85,8 @@ bool tuh_hid_mounted(uint8_t dev_addr, uint8_t idx); // Parse report descriptor into array of report_info struct and return number of reports. // For complicated report, application should write its own parser. -uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* reports_info_arr, uint8_t arr_count, uint8_t const* desc_report, uint16_t desc_len) TU_ATTR_UNUSED; +TU_ATTR_UNUSED uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* reports_info_arr, uint8_t arr_count, + uint8_t const* desc_report, uint16_t desc_len); //--------------------------------------------------------------------+ // Control Endpoint API @@ -97,13 +97,22 @@ uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* reports_info_arr, // Application can use set_protocol() to switch back to Report protocol. uint8_t tuh_hid_get_protocol(uint8_t dev_addr, uint8_t idx); +// Device by default is enumerated in Boot protocol for simplicity. Application +// can use this to modify the default protocol for next enumeration. +void tuh_hid_set_default_protocol(uint8_t protocol); + // Set protocol to HID_PROTOCOL_BOOT (0) or HID_PROTOCOL_REPORT (1) // This function is only supported by Boot interface (tuh_n_hid_interface_protocol() != NONE) bool tuh_hid_set_protocol(uint8_t dev_addr, uint8_t idx, uint8_t protocol); +// Get Report using control endpoint +// report_type is either Input, Output or Feature, (value from hid_report_type_t) +bool tuh_hid_get_report(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, void* report, uint16_t len); + // Set Report using control endpoint // report_type is either Input, Output or Feature, (value from hid_report_type_t) -bool tuh_hid_set_report(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, void* report, uint16_t len); +bool tuh_hid_set_report(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, + void* report, uint16_t len); //--------------------------------------------------------------------+ // Interrupt Endpoint API @@ -117,6 +126,9 @@ bool tuh_hid_receive_ready(uint8_t dev_addr, uint8_t idx); // - false if failed to queue the transfer e.g endpoint is busy bool tuh_hid_receive_report(uint8_t dev_addr, uint8_t idx); +// Abort receiving report on Interrupt Endpoint +bool tuh_hid_receive_abort(uint8_t dev_addr, uint8_t idx); + // Check if HID interface is ready to send report bool tuh_hid_send_ready(uint8_t dev_addr, uint8_t idx); @@ -145,6 +157,10 @@ void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t idx, uint8_t const* re // Invoked when sent report to device successfully via interrupt endpoint TU_ATTR_WEAK void tuh_hid_report_sent_cb(uint8_t dev_addr, uint8_t idx, uint8_t const* report, uint16_t len); +// Invoked when Get Report to device via either control endpoint +// len = 0 indicate there is error in the transfer e.g stalled response +TU_ATTR_WEAK void tuh_hid_get_report_complete_cb(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, uint16_t len); + // Invoked when Sent Report to device via either control endpoint // len = 0 indicate there is error in the transfer e.g stalled response TU_ATTR_WEAK void tuh_hid_set_report_complete_cb(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, uint16_t len); @@ -155,11 +171,12 @@ TU_ATTR_WEAK void tuh_hid_set_protocol_complete_cb(uint8_t dev_addr, uint8_t idx //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ -void hidh_init (void); -bool hidh_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len); -bool hidh_set_config (uint8_t dev_addr, uint8_t itf_num); -bool hidh_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); -void hidh_close (uint8_t dev_addr); +bool hidh_init(void); +bool hidh_deinit(void); +bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const* desc_itf, uint16_t max_len); +bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num); +bool hidh_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); +void hidh_close(uint8_t dev_addr); #ifdef __cplusplus } diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index 052372a93..42905ab0d 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -373,12 +373,10 @@ bool tud_midi_n_packet_write (uint8_t itf, uint8_t const packet[4]) //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ -void midid_init(void) -{ +void midid_init(void) { tu_memclr(_midid_itf, sizeof(_midid_itf)); - for(uint8_t i=0; itx_ff, midi->tx_ff_buf, CFG_TUD_MIDI_TX_BUFSIZE, 1, false); // OBVS. #if CFG_FIFO_MUTEX - tu_fifo_config_mutex(&midi->rx_ff, NULL, osal_mutex_create(&midi->rx_ff_mutex)); - tu_fifo_config_mutex(&midi->tx_ff, osal_mutex_create(&midi->tx_ff_mutex), NULL); + osal_mutex_t mutex_rd = osal_mutex_create(&midi->rx_ff_mutex); + osal_mutex_t mutex_wr = osal_mutex_create(&midi->tx_ff_mutex); + TU_ASSERT(mutex_wr != NULL && mutex_wr != NULL, ); + + tu_fifo_config_mutex(&midi->rx_ff, NULL, mutex_rd); + tu_fifo_config_mutex(&midi->tx_ff, mutex_wr, NULL); #endif } } +bool midid_deinit(void) { + #if CFG_FIFO_MUTEX + for(uint8_t i=0; irx_ff.mutex_rd; + osal_mutex_t mutex_wr = midi->tx_ff.mutex_wr; + + if (mutex_rd) { + osal_mutex_delete(mutex_rd); + tu_fifo_config_mutex(&midi->rx_ff, NULL, NULL); + } + + if (mutex_wr) { + osal_mutex_delete(mutex_wr); + tu_fifo_config_mutex(&midi->tx_ff, NULL, NULL); + } + } + #endif + + return true; +} + void midid_reset(uint8_t rhport) { (void) rhport; diff --git a/src/class/midi/midi_device.h b/src/class/midi/midi_device.h index 1c6f996be..3e89cc0a3 100644 --- a/src/class/midi/midi_device.h +++ b/src/class/midi/midi_device.h @@ -158,6 +158,7 @@ static inline bool tud_midi_packet_write (uint8_t const packet[4]) // Internal Class Driver API //--------------------------------------------------------------------+ void midid_init (void); +bool midid_deinit (void); void midid_reset (uint8_t rhport); uint16_t midid_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool midid_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 2589dcd2c..447560b4d 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -203,7 +203,7 @@ uint8_t rdwr10_validate_cmd(msc_cbw_t const* cbw) //--------------------------------------------------------------------+ // Debug //--------------------------------------------------------------------+ -#if CFG_TUSB_DEBUG >= 2 +#if CFG_TUSB_DEBUG >= CFG_TUD_MSC_LOG_LEVEL TU_ATTR_UNUSED tu_static tu_lookup_entry_t const _msc_scsi_cmd_lookup[] = { @@ -251,11 +251,15 @@ static inline void set_sense_medium_not_present(uint8_t lun) //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ -void mscd_init(void) -{ +void mscd_init(void) { tu_memclr(&_mscd_itf, sizeof(mscd_interface_t)); } +bool mscd_deinit(void) { + // nothing to do + return true; +} + void mscd_reset(uint8_t rhport) { (void) rhport; @@ -685,6 +689,24 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ } break; + case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: + resplen = 0; + + if (tud_msc_prevent_allow_medium_removal_cb) + { + scsi_prevent_allow_medium_removal_t const * prevent_allow = (scsi_prevent_allow_medium_removal_t const *) scsi_cmd; + if ( !tud_msc_prevent_allow_medium_removal_cb(lun, prevent_allow->prohibit_removal, prevent_allow->control) ) + { + // Failed status response + resplen = - 1; + + // set default sense if not set by callback + if ( p_msc->sense_key == 0 ) set_sense_medium_not_present(lun); + } + } + break; + + case SCSI_CMD_READ_CAPACITY_10: { uint32_t block_count; diff --git a/src/class/msc/msc_device.h b/src/class/msc/msc_device.h index 72f95be06..29acd280a 100644 --- a/src/class/msc/msc_device.h +++ b/src/class/msc/msc_device.h @@ -131,6 +131,9 @@ TU_ATTR_WEAK uint8_t tud_msc_get_maxlun_cb(void); // - Start = 1 : active mode, if load_eject = 1 : load disk storage TU_ATTR_WEAK bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject); +//Invoked when we receive the Prevent / Allow Medium Removal command +TU_ATTR_WEAK bool tud_msc_prevent_allow_medium_removal_cb(uint8_t lun, uint8_t prohibit_removal, uint8_t control); + // Invoked when received REQUEST_SENSE TU_ATTR_WEAK int32_t tud_msc_request_sense_cb(uint8_t lun, void* buffer, uint16_t bufsize); @@ -150,6 +153,7 @@ TU_ATTR_WEAK bool tud_msc_is_writable_cb(uint8_t lun); // Internal Class Driver API //--------------------------------------------------------------------+ void mscd_init (void); +bool mscd_deinit (void); void mscd_reset (uint8_t rhport); uint16_t mscd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool mscd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * p_request); diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index 90a58d3d0..ce6e7fb2d 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -29,7 +29,7 @@ #if CFG_TUH_ENABLED && CFG_TUH_MSC #include "host/usbh.h" -#include "host/usbh_classdriver.h" +#include "host/usbh_pvt.h" #include "msc_host.h" @@ -43,16 +43,14 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ -enum -{ +enum { MSC_STAGE_IDLE = 0, MSC_STAGE_CMD, MSC_STAGE_DATA, MSC_STAGE_STATUS, }; -typedef struct -{ +typedef struct { uint8_t itf_num; uint8_t ep_in; uint8_t ep_out; @@ -69,13 +67,13 @@ typedef struct //------------- SCSI -------------// uint8_t stage; - void* buffer; + void* buffer; tuh_msc_complete_cb_t complete_cb; uintptr_t complete_arg; CFG_TUH_MEM_ALIGN msc_cbw_t cbw; CFG_TUH_MEM_ALIGN msc_csw_t csw; -}msch_interface_t; +} msch_interface_t; CFG_TUH_MEM_SECTION static msch_interface_t _msch_itf[CFG_TUH_DEVICE_MAX]; @@ -86,40 +84,34 @@ static uint8_t _msch_buffer[sizeof(scsi_inquiry_resp_t)]; // FIXME potential nul reference TU_ATTR_ALWAYS_INLINE -static inline msch_interface_t* get_itf(uint8_t dev_addr) -{ - return &_msch_itf[dev_addr-1]; +static inline msch_interface_t* get_itf(uint8_t dev_addr) { + return &_msch_itf[dev_addr - 1]; } //--------------------------------------------------------------------+ // PUBLIC API //--------------------------------------------------------------------+ -uint8_t tuh_msc_get_maxlun(uint8_t dev_addr) -{ +uint8_t tuh_msc_get_maxlun(uint8_t dev_addr) { msch_interface_t* p_msc = get_itf(dev_addr); return p_msc->max_lun; } -uint32_t tuh_msc_get_block_count(uint8_t dev_addr, uint8_t lun) -{ +uint32_t tuh_msc_get_block_count(uint8_t dev_addr, uint8_t lun) { msch_interface_t* p_msc = get_itf(dev_addr); return p_msc->capacity[lun].block_count; } -uint32_t tuh_msc_get_block_size(uint8_t dev_addr, uint8_t lun) -{ +uint32_t tuh_msc_get_block_size(uint8_t dev_addr, uint8_t lun) { msch_interface_t* p_msc = get_itf(dev_addr); return p_msc->capacity[lun].block_size; } -bool tuh_msc_mounted(uint8_t dev_addr) -{ +bool tuh_msc_mounted(uint8_t dev_addr) { msch_interface_t* p_msc = get_itf(dev_addr); return p_msc->mounted; } -bool tuh_msc_ready(uint8_t dev_addr) -{ +bool tuh_msc_ready(uint8_t dev_addr) { msch_interface_t* p_msc = get_itf(dev_addr); return p_msc->mounted && !usbh_edpt_busy(dev_addr, p_msc->ep_in) && !usbh_edpt_busy(dev_addr, p_msc->ep_out); } @@ -127,20 +119,20 @@ bool tuh_msc_ready(uint8_t dev_addr) //--------------------------------------------------------------------+ // PUBLIC API: SCSI COMMAND //--------------------------------------------------------------------+ -static inline void cbw_init(msc_cbw_t *cbw, uint8_t lun) -{ +static inline void cbw_init(msc_cbw_t* cbw, uint8_t lun) { tu_memclr(cbw, sizeof(msc_cbw_t)); cbw->signature = MSC_CBW_SIGNATURE; cbw->tag = 0x54555342; // TUSB cbw->lun = lun; } -bool tuh_msc_scsi_command(uint8_t dev_addr, msc_cbw_t const* cbw, void* data, tuh_msc_complete_cb_t complete_cb, uintptr_t arg) -{ - msch_interface_t* p_msc = get_itf(dev_addr); +bool tuh_msc_scsi_command(uint8_t daddr, msc_cbw_t const* cbw, void* data, + tuh_msc_complete_cb_t complete_cb, uintptr_t arg) { + msch_interface_t* p_msc = get_itf(daddr); TU_VERIFY(p_msc->configured); - // TODO claim endpoint + // claim endpoint + TU_VERIFY(usbh_edpt_claim(daddr, p_msc->ep_out)); p_msc->cbw = *cbw; p_msc->stage = MSC_STAGE_CMD; @@ -148,15 +140,18 @@ bool tuh_msc_scsi_command(uint8_t dev_addr, msc_cbw_t const* cbw, void* data, tu p_msc->complete_cb = complete_cb; p_msc->complete_arg = arg; - TU_ASSERT(usbh_edpt_xfer(dev_addr, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t))); + if (!usbh_edpt_xfer(daddr, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t))) { + usbh_edpt_release(daddr, p_msc->ep_out); + return false; + } return true; } -bool tuh_msc_read_capacity(uint8_t dev_addr, uint8_t lun, scsi_read_capacity10_resp_t* response, tuh_msc_complete_cb_t complete_cb, uintptr_t arg) -{ - msch_interface_t* p_msc = get_itf(dev_addr); - TU_VERIFY(p_msc->configured); +bool tuh_msc_read_capacity(uint8_t dev_addr, uint8_t lun, scsi_read_capacity10_resp_t* response, + tuh_msc_complete_cb_t complete_cb, uintptr_t arg) { + msch_interface_t* p_msc = get_itf(dev_addr); + TU_VERIFY(p_msc->configured); msc_cbw_t cbw; cbw_init(&cbw, lun); @@ -169,8 +164,8 @@ bool tuh_msc_read_capacity(uint8_t dev_addr, uint8_t lun, scsi_read_capacity10_r return tuh_msc_scsi_command(dev_addr, &cbw, response, complete_cb, arg); } -bool tuh_msc_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t* response, tuh_msc_complete_cb_t complete_cb, uintptr_t arg) -{ +bool tuh_msc_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t* response, + tuh_msc_complete_cb_t complete_cb, uintptr_t arg) { msch_interface_t* p_msc = get_itf(dev_addr); TU_VERIFY(p_msc->mounted); @@ -181,18 +176,16 @@ bool tuh_msc_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t* respons cbw.dir = TUSB_DIR_IN_MASK; cbw.cmd_len = sizeof(scsi_inquiry_t); - scsi_inquiry_t const cmd_inquiry = - { - .cmd_code = SCSI_CMD_INQUIRY, - .alloc_length = sizeof(scsi_inquiry_resp_t) + scsi_inquiry_t const cmd_inquiry = { + .cmd_code = SCSI_CMD_INQUIRY, + .alloc_length = sizeof(scsi_inquiry_resp_t) }; memcpy(cbw.command, &cmd_inquiry, cbw.cmd_len); return tuh_msc_scsi_command(dev_addr, &cbw, response, complete_cb, arg); } -bool tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, tuh_msc_complete_cb_t complete_cb, uintptr_t arg) -{ +bool tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, tuh_msc_complete_cb_t complete_cb, uintptr_t arg) { msch_interface_t* p_msc = get_itf(dev_addr); TU_VERIFY(p_msc->configured); @@ -200,16 +193,16 @@ bool tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, tuh_msc_complete_cb_ cbw_init(&cbw, lun); cbw.total_bytes = 0; - cbw.dir = TUSB_DIR_OUT; - cbw.cmd_len = sizeof(scsi_test_unit_ready_t); - cbw.command[0] = SCSI_CMD_TEST_UNIT_READY; - cbw.command[1] = lun; // according to wiki TODO need verification + cbw.dir = TUSB_DIR_OUT; + cbw.cmd_len = sizeof(scsi_test_unit_ready_t); + cbw.command[0] = SCSI_CMD_TEST_UNIT_READY; + cbw.command[1] = lun; // according to wiki TODO need verification return tuh_msc_scsi_command(dev_addr, &cbw, NULL, complete_cb, arg); } -bool tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, void *response, tuh_msc_complete_cb_t complete_cb, uintptr_t arg) -{ +bool tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, void* response, + tuh_msc_complete_cb_t complete_cb, uintptr_t arg) { msc_cbw_t cbw; cbw_init(&cbw, lun); @@ -217,73 +210,64 @@ bool tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, void *response, tuh_ms cbw.dir = TUSB_DIR_IN_MASK; cbw.cmd_len = sizeof(scsi_request_sense_t); - scsi_request_sense_t const cmd_request_sense = - { - .cmd_code = SCSI_CMD_REQUEST_SENSE, - .alloc_length = 18 + scsi_request_sense_t const cmd_request_sense = { + .cmd_code = SCSI_CMD_REQUEST_SENSE, + .alloc_length = 18 }; - memcpy(cbw.command, &cmd_request_sense, cbw.cmd_len); return tuh_msc_scsi_command(dev_addr, &cbw, response, complete_cb, arg); } -bool tuh_msc_read10(uint8_t dev_addr, uint8_t lun, void * buffer, uint32_t lba, uint16_t block_count, tuh_msc_complete_cb_t complete_cb, uintptr_t arg) -{ +bool tuh_msc_read10(uint8_t dev_addr, uint8_t lun, void* buffer, uint32_t lba, uint16_t block_count, + tuh_msc_complete_cb_t complete_cb, uintptr_t arg) { msch_interface_t* p_msc = get_itf(dev_addr); TU_VERIFY(p_msc->mounted); msc_cbw_t cbw; cbw_init(&cbw, lun); - cbw.total_bytes = block_count*p_msc->capacity[lun].block_size; - cbw.dir = TUSB_DIR_IN_MASK; - cbw.cmd_len = sizeof(scsi_read10_t); + cbw.total_bytes = block_count * p_msc->capacity[lun].block_size; + cbw.dir = TUSB_DIR_IN_MASK; + cbw.cmd_len = sizeof(scsi_read10_t); - scsi_read10_t const cmd_read10 = - { - .cmd_code = SCSI_CMD_READ_10, - .lba = tu_htonl(lba), - .block_count = tu_htons(block_count) + scsi_read10_t const cmd_read10 = { + .cmd_code = SCSI_CMD_READ_10, + .lba = tu_htonl(lba), + .block_count = tu_htons(block_count) }; - memcpy(cbw.command, &cmd_read10, cbw.cmd_len); return tuh_msc_scsi_command(dev_addr, &cbw, buffer, complete_cb, arg); } -bool tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * buffer, uint32_t lba, uint16_t block_count, tuh_msc_complete_cb_t complete_cb, uintptr_t arg) -{ +bool tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const* buffer, uint32_t lba, uint16_t block_count, + tuh_msc_complete_cb_t complete_cb, uintptr_t arg) { msch_interface_t* p_msc = get_itf(dev_addr); TU_VERIFY(p_msc->mounted); msc_cbw_t cbw; cbw_init(&cbw, lun); - cbw.total_bytes = block_count*p_msc->capacity[lun].block_size; + cbw.total_bytes = block_count * p_msc->capacity[lun].block_size; cbw.dir = TUSB_DIR_OUT; cbw.cmd_len = sizeof(scsi_write10_t); - scsi_write10_t const cmd_write10 = - { - .cmd_code = SCSI_CMD_WRITE_10, - .lba = tu_htonl(lba), - .block_count = tu_htons(block_count) + scsi_write10_t const cmd_write10 = { + .cmd_code = SCSI_CMD_WRITE_10, + .lba = tu_htonl(lba), + .block_count = tu_htons(block_count) }; - memcpy(cbw.command, &cmd_write10, cbw.cmd_len); - return tuh_msc_scsi_command(dev_addr, &cbw, (void*)(uintptr_t) buffer, complete_cb, arg); + return tuh_msc_scsi_command(dev_addr, &cbw, (void*) (uintptr_t) buffer, complete_cb, arg); } #if 0 // MSC interface Reset (not used now) -bool tuh_msc_reset(uint8_t dev_addr) -{ - tusb_control_request_t const new_request = - { - .bmRequestType_bit = - { +bool tuh_msc_reset(uint8_t dev_addr) { + tusb_control_request_t const new_request = { + .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_OUT @@ -300,79 +284,77 @@ bool tuh_msc_reset(uint8_t dev_addr) //--------------------------------------------------------------------+ // CLASS-USBH API //--------------------------------------------------------------------+ -void msch_init(void) -{ +bool msch_init(void) { + TU_LOG_DRV("sizeof(msch_interface_t) = %u\r\n", sizeof(msch_interface_t)); tu_memclr(_msch_itf, sizeof(_msch_itf)); + return true; } -void msch_close(uint8_t dev_addr) -{ - TU_VERIFY(dev_addr <= CFG_TUH_DEVICE_MAX, ); +bool msch_deinit(void) { + return true; +} + +void msch_close(uint8_t dev_addr) { + TU_VERIFY(dev_addr <= CFG_TUH_DEVICE_MAX,); msch_interface_t* p_msc = get_itf(dev_addr); - TU_VERIFY(p_msc->configured, ); + TU_VERIFY(p_msc->configured,); TU_LOG_DRV(" MSCh close addr = %d\r\n", dev_addr); // invoke Application Callback if (p_msc->mounted) { - if(tuh_msc_umount_cb) tuh_msc_umount_cb(dev_addr); + if (tuh_msc_umount_cb) tuh_msc_umount_cb(dev_addr); } tu_memclr(p_msc, sizeof(msch_interface_t)); } -bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes) -{ +bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes) { msch_interface_t* p_msc = get_itf(dev_addr); msc_cbw_t const * cbw = &p_msc->cbw; msc_csw_t * csw = &p_msc->csw; - switch (p_msc->stage) - { + switch (p_msc->stage) { case MSC_STAGE_CMD: // Must be Command Block - TU_ASSERT(ep_addr == p_msc->ep_out && event == XFER_RESULT_SUCCESS && xferred_bytes == sizeof(msc_cbw_t)); + TU_ASSERT(ep_addr == p_msc->ep_out && event == XFER_RESULT_SUCCESS && xferred_bytes == sizeof(msc_cbw_t)); - if ( cbw->total_bytes && p_msc->buffer ) - { + if (cbw->total_bytes && p_msc->buffer) { // Data stage if any p_msc->stage = MSC_STAGE_DATA; - uint8_t const ep_data = (cbw->dir & TUSB_DIR_IN_MASK) ? p_msc->ep_in : p_msc->ep_out; TU_ASSERT(usbh_edpt_xfer(dev_addr, ep_data, p_msc->buffer, (uint16_t) cbw->total_bytes)); - }else - { + } else { // Status stage p_msc->stage = MSC_STAGE_STATUS; TU_ASSERT(usbh_edpt_xfer(dev_addr, p_msc->ep_in, (uint8_t*) &p_msc->csw, (uint16_t) sizeof(msc_csw_t))); } - break; + break; case MSC_STAGE_DATA: // Status stage p_msc->stage = MSC_STAGE_STATUS; TU_ASSERT(usbh_edpt_xfer(dev_addr, p_msc->ep_in, (uint8_t*) &p_msc->csw, (uint16_t) sizeof(msc_csw_t))); - break; + break; case MSC_STAGE_STATUS: // SCSI op is complete p_msc->stage = MSC_STAGE_IDLE; - if (p_msc->complete_cb) - { - tuh_msc_complete_data_t const cb_data = - { - .cbw = cbw, - .csw = csw, - .scsi_data = p_msc->buffer, - .user_arg = p_msc->complete_arg + if (p_msc->complete_cb) { + tuh_msc_complete_data_t const cb_data = { + .cbw = cbw, + .csw = csw, + .scsi_data = p_msc->buffer, + .user_arg = p_msc->complete_arg }; p_msc->complete_cb(dev_addr, &cb_data); } - break; + break; - // unknown state - default: break; + // unknown state + default: + break; } return true; @@ -381,39 +363,35 @@ bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32 //--------------------------------------------------------------------+ // MSC Enumeration //--------------------------------------------------------------------+ - -static void config_get_maxlun_complete (tuh_xfer_t* xfer); -static bool config_test_unit_ready_complete(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_data); +static void config_get_maxlun_complete(tuh_xfer_t* xfer); +static bool config_test_unit_ready_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data); static bool config_request_sense_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data); static bool config_read_capacity_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data); -bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len) -{ +bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const* desc_itf, uint16_t max_len) { (void) rhport; TU_VERIFY (MSC_SUBCLASS_SCSI == desc_itf->bInterfaceSubClass && - MSC_PROTOCOL_BOT == desc_itf->bInterfaceProtocol); + MSC_PROTOCOL_BOT == desc_itf->bInterfaceProtocol); // msc driver length is fixed - uint16_t const drv_len = (uint16_t) (sizeof(tusb_desc_interface_t) + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); + uint16_t const drv_len = (uint16_t) (sizeof(tusb_desc_interface_t) + + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); TU_ASSERT(drv_len <= max_len); msch_interface_t* p_msc = get_itf(dev_addr); - tusb_desc_endpoint_t const * ep_desc = (tusb_desc_endpoint_t const *) tu_desc_next(desc_itf); + tusb_desc_endpoint_t const* ep_desc = (tusb_desc_endpoint_t const*) tu_desc_next(desc_itf); - for(uint32_t i=0; i<2; i++) - { + for (uint32_t i = 0; i < 2; i++) { TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType && TUSB_XFER_BULK == ep_desc->bmAttributes.xfer); TU_ASSERT(tuh_edpt_open(dev_addr, ep_desc)); - if ( tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN ) - { + if (TUSB_DIR_IN == tu_edpt_dir(ep_desc->bEndpointAddress)) { p_msc->ep_in = ep_desc->bEndpointAddress; - }else - { + } else { p_msc->ep_out = ep_desc->bEndpointAddress; } - ep_desc = (tusb_desc_endpoint_t const *) tu_desc_next(ep_desc); + ep_desc = (tusb_desc_endpoint_t const*) tu_desc_next(ep_desc); } p_msc->itf_num = desc_itf->bInterfaceNumber; @@ -430,32 +408,31 @@ bool msch_set_config(uint8_t dev_addr, uint8_t itf_num) { //------------- Get Max Lun -------------// TU_LOG_DRV("MSC Get Max Lun\r\n"); tusb_control_request_t const request = { - .bmRequestType_bit = { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_IN - }, - .bRequest = MSC_REQ_GET_MAX_LUN, - .wValue = 0, - .wIndex = itf_num, - .wLength = 1 + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN + }, + .bRequest = MSC_REQ_GET_MAX_LUN, + .wValue = 0, + .wIndex = itf_num, + .wLength = 1 }; tuh_xfer_t xfer = { - .daddr = dev_addr, - .ep_addr = 0, - .setup = &request, - .buffer = _msch_buffer, - .complete_cb = config_get_maxlun_complete, - .user_data = 0 + .daddr = dev_addr, + .ep_addr = 0, + .setup = &request, + .buffer = _msch_buffer, + .complete_cb = config_get_maxlun_complete, + .user_data = 0 }; TU_ASSERT(tuh_control_xfer(&xfer)); return true; } -static void config_get_maxlun_complete (tuh_xfer_t* xfer) -{ +static void config_get_maxlun_complete(tuh_xfer_t* xfer) { uint8_t const daddr = xfer->daddr; msch_interface_t* p_msc = get_itf(daddr); @@ -471,18 +448,16 @@ static void config_get_maxlun_complete (tuh_xfer_t* xfer) tuh_msc_test_unit_ready(daddr, lun, config_test_unit_ready_complete, 0); } -static bool config_test_unit_ready_complete(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_data) -{ +static bool config_test_unit_ready_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data) { msc_cbw_t const* cbw = cb_data->cbw; msc_csw_t const* csw = cb_data->csw; - if (csw->status == 0) - { + if (csw->status == 0) { // Unit is ready, read its capacity TU_LOG_DRV("SCSI Read Capacity\r\n"); - tuh_msc_read_capacity(dev_addr, cbw->lun, (scsi_read_capacity10_resp_t*) ((void*) _msch_buffer), config_read_capacity_complete, 0); - }else - { + tuh_msc_read_capacity(dev_addr, cbw->lun, (scsi_read_capacity10_resp_t*) ((void*) _msch_buffer), + config_read_capacity_complete, 0); + } else { // Note: During enumeration, some device fails Test Unit Ready and require a few retries // with Request Sense to start working !! // TODO limit number of retries @@ -493,8 +468,7 @@ static bool config_test_unit_ready_complete(uint8_t dev_addr, tuh_msc_complete_d return true; } -static bool config_request_sense_complete(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_data) -{ +static bool config_request_sense_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data) { msc_cbw_t const* cbw = cb_data->cbw; msc_csw_t const* csw = cb_data->csw; @@ -503,8 +477,7 @@ static bool config_request_sense_complete(uint8_t dev_addr, tuh_msc_complete_dat return true; } -static bool config_read_capacity_complete(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_data) -{ +static bool config_read_capacity_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data) { msc_cbw_t const* cbw = cb_data->cbw; msc_csw_t const* csw = cb_data->csw; diff --git a/src/class/msc/msc_host.h b/src/class/msc/msc_host.h index 6c0e5c9dd..9fda566d8 100644 --- a/src/class/msc/msc_host.h +++ b/src/class/msc/msc_host.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_MSC_HOST_H_ -#define _TUSB_MSC_HOST_H_ +#ifndef TUSB_MSC_HOST_H_ +#define TUSB_MSC_HOST_H_ #include "msc.h" @@ -73,7 +73,7 @@ uint32_t tuh_msc_get_block_size(uint8_t dev_addr, uint8_t lun); // Perform a full SCSI command (cbw, data, csw) in non-blocking manner. // Complete callback is invoked when SCSI op is complete. // return true if success, false if there is already pending operation. -bool tuh_msc_scsi_command(uint8_t dev_addr, msc_cbw_t const* cbw, void* data, tuh_msc_complete_cb_t complete_cb, uintptr_t arg); +bool tuh_msc_scsi_command(uint8_t daddr, msc_cbw_t const* cbw, void* data, tuh_msc_complete_cb_t complete_cb, uintptr_t arg); // Perform SCSI Inquiry command // Complete callback is invoked when SCSI op is complete. @@ -113,7 +113,8 @@ TU_ATTR_WEAK void tuh_msc_umount_cb(uint8_t dev_addr); // Internal Class Driver API //--------------------------------------------------------------------+ -void msch_init (void); +bool msch_init (void); +bool msch_deinit (void); bool msch_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len); bool msch_set_config (uint8_t dev_addr, uint8_t itf_num); void msch_close (uint8_t dev_addr); @@ -123,4 +124,4 @@ bool msch_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, ui } #endif -#endif /* _TUSB_MSC_HOST_H_ */ +#endif diff --git a/src/class/net/ecm_rndis_device.c b/src/class/net/ecm_rndis_device.c index 762425732..f7a5fd225 100644 --- a/src/class/net/ecm_rndis_device.c +++ b/src/class/net/ecm_rndis_device.c @@ -132,11 +132,14 @@ void netd_report(uint8_t *buf, uint16_t len) //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ -void netd_init(void) -{ +void netd_init(void) { tu_memclr(&_netd_itf, sizeof(_netd_itf)); } +bool netd_deinit(void) { + return true; +} + void netd_reset(uint8_t rhport) { (void) rhport; diff --git a/src/class/net/ncm.h b/src/class/net/ncm.h index 96ba11fbc..1b987fca0 100644 --- a/src/class/net/ncm.h +++ b/src/class/net/ncm.h @@ -2,6 +2,7 @@ * The MIT License (MIT) * * Copyright (c) 2021, Ha Thach (tinyusb.org) + * Copyright (c) 2024, Hardy Griech * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,22 +25,58 @@ * This file is part of the TinyUSB stack. */ - #ifndef _TUSB_NCM_H_ #define _TUSB_NCM_H_ #include "common/tusb_common.h" -#ifdef __cplusplus - extern "C" { +// NTB buffers size for reception side, must be >> MTU to avoid TCP retransmission (driver issue ?) +// Linux use 2048 as minimal size +#ifndef CFG_TUD_NCM_OUT_NTB_MAX_SIZE + #define CFG_TUD_NCM_OUT_NTB_MAX_SIZE 3200 #endif -// Table 4.3 Data Class Interface Protocol Codes -typedef enum -{ - NCM_DATA_PROTOCOL_NETWORK_TRANSFER_BLOCK = 0x01 -} ncm_data_interface_protocol_code_t; +// NTB buffers size for reception side, must be > MTU +// Linux use 2048 as minimal size +#ifndef CFG_TUD_NCM_IN_NTB_MAX_SIZE + #define CFG_TUD_NCM_IN_NTB_MAX_SIZE 3200 +#endif +// Number of NTB buffers for reception side +// Depending on the configuration, this parameter could be increased with the cost of additional RAM requirements +// On Full-Speed (RP2040) : +// 1 - good performance +// 2 - up to 30% more performance with iperf with small packets +// >2 - no performance gain +// On High-Speed (STM32F7) : +// No performance gain +#ifndef CFG_TUD_NCM_OUT_NTB_N + #define CFG_TUD_NCM_OUT_NTB_N 1 +#endif + +// Number of NTB buffers for transmission side +// Depending on the configuration, this parameter could be increased with the cost of additional RAM requirements +// On Full-Speed (RP2040) : +// 1 - good performance but SystemView shows lost events (on load test) +// 2 - up to 50% more performance with iperf with small packets, "tud_network_can_xmit: request blocked" +// happens from time to time with SystemView +// 3 - "tud_network_can_xmit: request blocked" never happens +// >3 - no performance gain +// On High-Speed (STM32F7) : +// No performance gain +#ifndef CFG_TUD_NCM_IN_NTB_N + #define CFG_TUD_NCM_IN_NTB_N 1 +#endif + +// How many datagrams it is allowed to put into an NTB for transmission side +#ifndef CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB + #define CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB 8 +#endif + +// This tells the host how many datagrams it is allowed to put into an NTB +#ifndef CFG_TUD_NCM_OUT_MAX_DATAGRAMS_PER_NTB + #define CFG_TUD_NCM_OUT_MAX_DATAGRAMS_PER_NTB 6 +#endif // Table 6.2 Class-Specific Request Codes for Network Control Model subclass typedef enum @@ -62,8 +99,65 @@ typedef enum NCM_SET_CRC_MODE = 0x8A, } ncm_request_code_t; -#ifdef __cplusplus - } -#endif +#define NTH16_SIGNATURE 0x484D434E +#define NDP16_SIGNATURE_NCM0 0x304D434E +#define NDP16_SIGNATURE_NCM1 0x314D434E + +typedef struct TU_ATTR_PACKED { + uint16_t wLength; + uint16_t bmNtbFormatsSupported; + uint32_t dwNtbInMaxSize; + uint16_t wNdbInDivisor; + uint16_t wNdbInPayloadRemainder; + uint16_t wNdbInAlignment; + uint16_t wReserved; + uint32_t dwNtbOutMaxSize; + uint16_t wNdbOutDivisor; + uint16_t wNdbOutPayloadRemainder; + uint16_t wNdbOutAlignment; + uint16_t wNtbOutMaxDatagrams; +} ntb_parameters_t; + +typedef struct TU_ATTR_PACKED { + uint32_t dwSignature; + uint16_t wHeaderLength; + uint16_t wSequence; + uint16_t wBlockLength; + uint16_t wNdpIndex; +} nth16_t; + +typedef struct TU_ATTR_PACKED { + uint16_t wDatagramIndex; + uint16_t wDatagramLength; +} ndp16_datagram_t; + +typedef struct TU_ATTR_PACKED { + uint32_t dwSignature; + uint16_t wLength; + uint16_t wNextNdpIndex; + //ndp16_datagram_t datagram[]; +} ndp16_t; + +typedef union TU_ATTR_PACKED { + struct { + nth16_t nth; + ndp16_t ndp; + ndp16_datagram_t ndp_datagram[CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB + 1]; + }; + uint8_t data[CFG_TUD_NCM_IN_NTB_MAX_SIZE]; +} xmit_ntb_t; + +typedef union TU_ATTR_PACKED { + struct { + nth16_t nth; + // only the header is at a guaranteed position + }; + uint8_t data[CFG_TUD_NCM_OUT_NTB_MAX_SIZE]; +} recv_ntb_t; + +struct ncm_notify_t { + tusb_control_request_t header; + uint32_t downlink, uplink; +}; #endif diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 226c42c4e..4b237e4cf 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -1,9 +1,8 @@ /* * The MIT License (MIT) * - * Copyright (c) 2020 Jacob Berg Potter - * Copyright (c) 2020 Peter Lawrence * Copyright (c) 2019 Ha Thach (tinyusb.org) + * Copyright (c) 2024 Hardy Griech * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,12 +25,37 @@ * This file is part of the TinyUSB stack. */ +/** + * Small Glossary (from the spec) + * -------------- + * Datagram - A collection of bytes forming a single item of information, passed as a unit from source to destination. + * NCM - Network Control Model + * NDP - NCM Datagram Pointer: NTB structure that delineates Datagrams (typically Ethernet frames) within an NTB + * NTB - NCM Transfer Block: a data structure for efficient USB encapsulation of one or more datagrams + * Each NTB is designed to be a single USB transfer + * NTH - NTB Header: a data structure at the front of each NTB, which provides the information needed to validate + * the NTB and begin decoding + * + * Some explanations + * ----------------- + * - rhport is the USB port of the device, in most cases "0" + * - itf_data_alt if != 0 -> data xmit/recv are allowed (see spec) + * - ep_in IN endpoints take data from the device intended to go in to the host (the device transmits) + * - ep_out OUT endpoints send data out of the host to the device (the device receives) + */ + #include "tusb_option.h" -#if ( CFG_TUD_ENABLED && CFG_TUD_NCM ) +#if (CFG_TUD_ENABLED && CFG_TUD_NCM) + +#include +#include +#include #include "device/usbd.h" #include "device/usbd_pvt.h" + +#include "ncm.h" #include "net_device.h" // Level where CFG_TUSB_DEBUG must be at least for this driver is logged @@ -41,478 +65,829 @@ #define TU_LOG_DRV(...) TU_LOG(CFG_TUD_NCM_LOG_LEVEL, __VA_ARGS__) -//--------------------------------------------------------------------+ -// MACRO CONSTANT TYPEDEF -//--------------------------------------------------------------------+ +// Alignment must be 4 +#define TUD_NCM_ALIGNMENT 4 +// calculate alignment of xmit datagrams within an NTB +#define XMIT_ALIGN_OFFSET(x) ((TUD_NCM_ALIGNMENT - ((x) & (TUD_NCM_ALIGNMENT - 1))) & (TUD_NCM_ALIGNMENT - 1)) -#define NTH16_SIGNATURE 0x484D434E -#define NDP16_SIGNATURE_NCM0 0x304D434E -#define NDP16_SIGNATURE_NCM1 0x314D434E +//----------------------------------------------------------------------------- +// +// Module global things +// +#define XMIT_NTB_N CFG_TUD_NCM_IN_NTB_N +#define RECV_NTB_N CFG_TUD_NCM_OUT_NTB_N -typedef struct TU_ATTR_PACKED -{ - uint16_t wLength; - uint16_t bmNtbFormatsSupported; - uint32_t dwNtbInMaxSize; - uint16_t wNdbInDivisor; - uint16_t wNdbInPayloadRemainder; - uint16_t wNdbInAlignment; - uint16_t wReserved; - uint32_t dwNtbOutMaxSize; - uint16_t wNdbOutDivisor; - uint16_t wNdbOutPayloadRemainder; - uint16_t wNdbOutAlignment; - uint16_t wNtbOutMaxDatagrams; -} ntb_parameters_t; +typedef struct { + // general + uint8_t ep_in; // endpoint for outgoing datagrams (naming is a little bit confusing) + uint8_t ep_out; // endpoint for incoming datagrams (naming is a little bit confusing) + uint8_t ep_notif; // endpoint for notifications + uint8_t itf_num; // interface number + uint8_t itf_data_alt; // ==0 -> no endpoints, i.e. no network traffic, ==1 -> normal operation with two endpoints (spec, chapter 5.3) + uint8_t rhport; // storage of \a rhport because some callbacks are done without it -typedef struct TU_ATTR_PACKED -{ - uint32_t dwSignature; - uint16_t wHeaderLength; - uint16_t wSequence; - uint16_t wBlockLength; - uint16_t wNdpIndex; -} nth16_t; + // recv handling + CFG_TUSB_MEM_ALIGN recv_ntb_t recv_ntb[RECV_NTB_N]; // actual recv NTBs + recv_ntb_t *recv_free_ntb[RECV_NTB_N]; // free list of recv NTBs + recv_ntb_t *recv_ready_ntb[RECV_NTB_N]; // NTBs waiting for transmission to glue logic + recv_ntb_t *recv_tinyusb_ntb; // buffer for the running transfer TinyUSB -> driver + recv_ntb_t *recv_glue_ntb; // buffer for the running transfer driver -> glue logic + uint16_t recv_glue_ntb_datagram_ndx; // index into \a recv_glue_ntb_datagram -typedef struct TU_ATTR_PACKED -{ - uint16_t wDatagramIndex; - uint16_t wDatagramLength; -} ndp16_datagram_t; - -typedef struct TU_ATTR_PACKED -{ - uint32_t dwSignature; - uint16_t wLength; - uint16_t wNextNdpIndex; - ndp16_datagram_t datagram[]; -} ndp16_t; - -typedef union TU_ATTR_PACKED { - struct { - nth16_t nth; - ndp16_t ndp; - }; - uint8_t data[CFG_TUD_NCM_IN_NTB_MAX_SIZE]; -} transmit_ntb_t; - -struct ecm_notify_struct -{ - tusb_control_request_t header; - uint32_t downlink, uplink; -}; - -typedef struct -{ - uint8_t itf_num; // Index number of Management Interface, +1 for Data Interface - uint8_t itf_data_alt; // Alternate setting of Data Interface. 0 : inactive, 1 : active - - uint8_t ep_notif; - uint8_t ep_in; - uint8_t ep_out; - - const ndp16_t *ndp; - uint8_t num_datagrams, current_datagram_index; + // xmit handling + CFG_TUSB_MEM_ALIGN xmit_ntb_t xmit_ntb[XMIT_NTB_N]; // actual xmit NTBs + xmit_ntb_t *xmit_free_ntb[XMIT_NTB_N]; // free list of xmit NTBs + xmit_ntb_t *xmit_ready_ntb[XMIT_NTB_N]; // NTBs waiting for transmission to TinyUSB + xmit_ntb_t *xmit_tinyusb_ntb; // buffer for the running transfer driver -> TinyUSB + xmit_ntb_t *xmit_glue_ntb; // buffer for the running transfer glue logic -> driver + uint16_t xmit_sequence; // NTB sequence counter + uint16_t xmit_glue_ntb_datagram_ndx; // index into \a xmit_glue_ntb_datagram + // notification handling enum { - REPORT_SPEED, - REPORT_CONNECTED, - REPORT_DONE - } report_state; - bool report_pending; - - uint8_t current_ntb; // Index in transmit_ntb[] that is currently being filled with datagrams - uint8_t datagram_count; // Number of datagrams in transmit_ntb[current_ntb] - uint16_t next_datagram_offset; // Offset in transmit_ntb[current_ntb].data to place the next datagram - uint16_t ntb_in_size; // Maximum size of transmitted (IN to host) NTBs; initially CFG_TUD_NCM_IN_NTB_MAX_SIZE - uint8_t max_datagrams_per_ntb; // Maximum number of datagrams per NTB; initially CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB - - uint16_t nth_sequence; // Sequence number counter for transmitted NTBs - - bool transferring; - + NOTIFICATION_SPEED, + NOTIFICATION_CONNECTED, + NOTIFICATION_DONE + } notification_xmit_state; // state of notification transmission + bool notification_xmit_is_running; // notification is currently transmitted } ncm_interface_t; -//--------------------------------------------------------------------+ -// INTERNAL OBJECT & FUNCTION DECLARATION -//--------------------------------------------------------------------+ +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static ncm_interface_t ncm_interface; -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, - .wNdbInDivisor = 4, - .wNdbInPayloadRemainder = 0, - .wNdbInAlignment = CFG_TUD_NCM_ALIGNMENT, - .wReserved = 0, - .dwNtbOutMaxSize = CFG_TUD_NCM_OUT_NTB_MAX_SIZE, - .wNdbOutDivisor = 4, - .wNdbOutPayloadRemainder = 0, - .wNdbOutAlignment = CFG_TUD_NCM_ALIGNMENT, - .wNtbOutMaxDatagrams = 0 +/** + * This is the NTB parameter structure + * + * \attention + * We are lucky, that byte order is correct + */ +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_parameters = { + .wLength = sizeof(ntb_parameters_t), + .bmNtbFormatsSupported = 0x01,// 16-bit NTB supported + .dwNtbInMaxSize = CFG_TUD_NCM_IN_NTB_MAX_SIZE, + .wNdbInDivisor = 1, + .wNdbInPayloadRemainder = 0, + .wNdbInAlignment = TUD_NCM_ALIGNMENT, + .wReserved = 0, + .dwNtbOutMaxSize = CFG_TUD_NCM_OUT_NTB_MAX_SIZE, + .wNdbOutDivisor = 1, + .wNdbOutPayloadRemainder = 0, + .wNdbOutAlignment = TUD_NCM_ALIGNMENT, + .wNtbOutMaxDatagrams = CFG_TUD_NCM_OUT_MAX_DATAGRAMS_PER_NTB, }; -CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static transmit_ntb_t transmit_ntb[2]; +// Some confusing remarks about wNtbOutMaxDatagrams... +// ==1 -> SystemView packets/s goes up to 2000 and events are lost during startup +// ==0 -> SystemView runs fine, iperf shows in wireshark a lot of error +// ==6 -> SystemView runs fine, iperf also +// >6 -> iperf starts to show errors +// -> 6 seems to be the best value. Why? Don't know, perhaps only on my system? +// +// iperf: for MSS in 100 200 400 800 1200 1450 1500; do iperf -c 192.168.14.1 -e -i 1 -M $MSS -l 8192 -P 1; sleep 2; done +// sysview: SYSTICKS_PER_SEC=35000, IDLE_US=1000, PRINT_MOD=1000 +// -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; - -/* - * Set up the NTB state in ncm_interface to be ready to add datagrams. - */ -static void ncm_prepare_for_tx(void) { - ncm_interface.datagram_count = 0; - // datagrams start after all the headers - ncm_interface.next_datagram_offset = sizeof(nth16_t) + sizeof(ndp16_t) - + ((CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB + 1) * sizeof(ndp16_datagram_t)); -} - -/* - * If not already transmitting, start sending the current NTB to the host and swap buffers - * to start filling the other one with datagrams. - */ -static void ncm_start_tx(void) { - if (ncm_interface.transferring) { - return; - } - - transmit_ntb_t *ntb = &transmit_ntb[ncm_interface.current_ntb]; - size_t ntb_length = ncm_interface.next_datagram_offset; - - // Fill in NTB header - ntb->nth.dwSignature = NTH16_SIGNATURE; - ntb->nth.wHeaderLength = sizeof(nth16_t); - ntb->nth.wSequence = ncm_interface.nth_sequence++; - ntb->nth.wBlockLength = ntb_length; - ntb->nth.wNdpIndex = sizeof(nth16_t); - - // Fill in NDP16 header and terminator - ntb->ndp.dwSignature = NDP16_SIGNATURE_NCM0; - ntb->ndp.wLength = sizeof(ndp16_t) + (ncm_interface.datagram_count + 1) * sizeof(ndp16_datagram_t); - ntb->ndp.wNextNdpIndex = 0; - ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramIndex = 0; - ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramLength = 0; - - // Kick off an endpoint transfer - usbd_edpt_xfer(0, ncm_interface.ep_in, ntb->data, ntb_length); - ncm_interface.transferring = true; - - // Swap to the other NTB and clear it out - ncm_interface.current_ntb = 1 - ncm_interface.current_ntb; - ncm_prepare_for_tx(); -} - -tu_static struct ecm_notify_struct ncm_notify_connected = -{ +//----------------------------------------------------------------------------- +// +// everything about notifications +// +tu_static struct ncm_notify_t ncm_notify_connected = { .header = { .bmRequestType_bit = { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_IN - }, - .bRequest = CDC_NOTIF_NETWORK_CONNECTION, - .wValue = 1 /* Connected */, - .wLength = 0, + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN}, + .bRequest = CDC_NOTIF_NETWORK_CONNECTION, + .wValue = 1 /* Connected */, + .wLength = 0, }, }; -tu_static struct ecm_notify_struct ncm_notify_speed_change = -{ +tu_static struct ncm_notify_t ncm_notify_speed_change = { .header = { .bmRequestType_bit = { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_IN - }, + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN}, .bRequest = CDC_NOTIF_CONNECTION_SPEED_CHANGE, .wLength = 8, }, - .downlink = 10000000, - .uplink = 10000000, + .downlink = TUD_OPT_HIGH_SPEED ? 480000000 : 12000000, + .uplink = TUD_OPT_HIGH_SPEED ? 480000000 : 12000000, }; -void tud_network_recv_renew(void) -{ - if (!ncm_interface.num_datagrams) - { - usbd_edpt_xfer(0, ncm_interface.ep_out, receive_ntb, sizeof(receive_ntb)); +/** + * Transmit next notification to the host (if appropriate). + * Notifications are transferred to the host once during connection setup. + */ +static void notification_xmit(uint8_t rhport, bool force_next) { + TU_LOG_DRV("notification_xmit(%d, %d) - %d %d\n", force_next, rhport, ncm_interface.notification_xmit_state, ncm_interface.notification_xmit_is_running); + + if (!force_next && ncm_interface.notification_xmit_is_running) { return; } - const ndp16_t *ndp = ncm_interface.ndp; - const int i = ncm_interface.current_datagram_index; - ncm_interface.current_datagram_index++; - ncm_interface.num_datagrams--; + if (ncm_interface.notification_xmit_state == NOTIFICATION_SPEED) { + TU_LOG_DRV(" NOTIFICATION_SPEED\n"); + ncm_notify_speed_change.header.wIndex = ncm_interface.itf_num; + usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t *) &ncm_notify_speed_change, sizeof(ncm_notify_speed_change)); + ncm_interface.notification_xmit_state = NOTIFICATION_CONNECTED; + ncm_interface.notification_xmit_is_running = true; + } else if (ncm_interface.notification_xmit_state == NOTIFICATION_CONNECTED) { + TU_LOG_DRV(" NOTIFICATION_CONNECTED\n"); + ncm_notify_connected.header.wIndex = ncm_interface.itf_num; + usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t *) &ncm_notify_connected, sizeof(ncm_notify_connected)); + ncm_interface.notification_xmit_state = NOTIFICATION_DONE; + ncm_interface.notification_xmit_is_running = true; + } else { + TU_LOG_DRV(" NOTIFICATION_FINISHED\n"); + } +} // notification_xmit - tud_network_recv_cb(receive_ntb + ndp->datagram[i].wDatagramIndex, ndp->datagram[i].wDatagramLength); +//----------------------------------------------------------------------------- +// +// everything about packet transmission (driver -> TinyUSB) +// + +/** + * Put NTB into the transmitter free list. + */ +static void xmit_put_ntb_into_free_list(xmit_ntb_t *free_ntb) { + TU_LOG_DRV("xmit_put_ntb_into_free_list() - %p\n", ncm_interface.xmit_tinyusb_ntb); + + if (free_ntb == NULL) { // can happen due to ZLPs + return; + } + + for (int i = 0; i < XMIT_NTB_N; ++i) { + if (ncm_interface.xmit_free_ntb[i] == NULL) { + ncm_interface.xmit_free_ntb[i] = free_ntb; + return; + } + } + TU_LOG_DRV("(EE) xmit_put_ntb_into_free_list - no entry in free list\n");// this should not happen +} // xmit_put_ntb_into_free_list + +/** + * Get an NTB from the free list + */ +static xmit_ntb_t *xmit_get_free_ntb(void) { + TU_LOG_DRV("xmit_get_free_ntb()\n"); + + for (int i = 0; i < XMIT_NTB_N; ++i) { + if (ncm_interface.xmit_free_ntb[i] != NULL) { + xmit_ntb_t *free = ncm_interface.xmit_free_ntb[i]; + ncm_interface.xmit_free_ntb[i] = NULL; + return free; + } + } + return NULL; +} // xmit_get_free_ntb + +/** + * Put a filled NTB into the ready list + */ +static void xmit_put_ntb_into_ready_list(xmit_ntb_t *ready_ntb) { + TU_LOG_DRV("xmit_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->nth.wBlockLength); + + for (int i = 0; i < XMIT_NTB_N; ++i) { + if (ncm_interface.xmit_ready_ntb[i] == NULL) { + ncm_interface.xmit_ready_ntb[i] = ready_ntb; + return; + } + } + TU_LOG_DRV("(EE) xmit_put_ntb_into_ready_list: ready list full\n");// this should not happen +} // xmit_put_ntb_into_ready_list + +/** + * Get the next NTB from the ready list (and remove it from the list). + * If the ready list is empty, return NULL. + */ +static xmit_ntb_t *xmit_get_next_ready_ntb(void) { + xmit_ntb_t *r = NULL; + + r = ncm_interface.xmit_ready_ntb[0]; + memmove(ncm_interface.xmit_ready_ntb + 0, ncm_interface.xmit_ready_ntb + 1, sizeof(ncm_interface.xmit_ready_ntb) - sizeof(ncm_interface.xmit_ready_ntb[0])); + ncm_interface.xmit_ready_ntb[XMIT_NTB_N - 1] = NULL; + + TU_LOG_DRV("recv_get_next_ready_ntb: %p\n", r); + return r; +} // xmit_get_next_ready_ntb + +/** + * Transmit a ZLP if required + * + * \note + * Insertion of the ZLPs is a little bit different then described in the spec. + * But the below implementation actually works. Don't know if this is a spec + * or TinyUSB issue. + * + * \pre + * This must be called from netd_xfer_cb() so that ep_in is ready + */ +static bool xmit_insert_required_zlp(uint8_t rhport, uint32_t xferred_bytes) { + TU_LOG_DRV("xmit_insert_required_zlp(%d,%d)\n", rhport, xferred_bytes); + + if (xferred_bytes == 0 || xferred_bytes % CFG_TUD_NET_ENDPOINT_SIZE != 0) { + return false; + } + + TU_ASSERT(ncm_interface.itf_data_alt == 1, false); + TU_ASSERT(!usbd_edpt_busy(rhport, ncm_interface.ep_in), false); + + TU_LOG_DRV("xmit_insert_required_zlp! (%u)\n", (unsigned) xferred_bytes); + + // start transmission of the ZLP + usbd_edpt_xfer(rhport, ncm_interface.ep_in, NULL, 0); + + return true; +} // xmit_insert_required_zlp + +/** + * Start transmission if it there is a waiting packet and if can be done from interface side. + */ +static void xmit_start_if_possible(uint8_t rhport) { + TU_LOG_DRV("xmit_start_if_possible()\n"); + + if (ncm_interface.xmit_tinyusb_ntb != NULL) { + TU_LOG_DRV(" !xmit_start_if_possible 1\n"); + return; + } + if (ncm_interface.itf_data_alt != 1) { + TU_LOG_DRV("(EE) !xmit_start_if_possible 2\n"); + return; + } + if (usbd_edpt_busy(rhport, ncm_interface.ep_in)) { + TU_LOG_DRV(" !xmit_start_if_possible 3\n"); + return; + } + + ncm_interface.xmit_tinyusb_ntb = xmit_get_next_ready_ntb(); + if (ncm_interface.xmit_tinyusb_ntb == NULL) { + if (ncm_interface.xmit_glue_ntb == NULL || ncm_interface.xmit_glue_ntb_datagram_ndx == 0) { + // -> really nothing is waiting + return; + } + ncm_interface.xmit_tinyusb_ntb = ncm_interface.xmit_glue_ntb; + ncm_interface.xmit_glue_ntb = NULL; + } + + #if CFG_TUD_NCM_LOG_LEVEL >= 3 + { + uint16_t len = ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength; + TU_LOG_BUF(3, ncm_interface.xmit_tinyusb_ntb->data[i], len); + } + #endif + + if (ncm_interface.xmit_glue_ntb_datagram_ndx != 1) { + TU_LOG_DRV(">> %d %d\n", ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength, ncm_interface.xmit_glue_ntb_datagram_ndx); + } + + // Kick off an endpoint transfer + usbd_edpt_xfer(0, ncm_interface.ep_in, ncm_interface.xmit_tinyusb_ntb->data, ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength); +} // xmit_start_if_possible + +/** + * check if a new datagram fits into the current NTB + */ +static bool xmit_requested_datagram_fits_into_current_ntb(uint16_t datagram_size) { + TU_LOG_DRV("xmit_requested_datagram_fits_into_current_ntb(%d) - %p %p\n", datagram_size, ncm_interface.xmit_tinyusb_ntb, ncm_interface.xmit_glue_ntb); + + if (ncm_interface.xmit_glue_ntb == NULL) { + return false; + } + if (ncm_interface.xmit_glue_ntb_datagram_ndx >= CFG_TUD_NCM_IN_MAX_DATAGRAMS_PER_NTB) { + return false; + } + if (ncm_interface.xmit_glue_ntb->nth.wBlockLength + datagram_size + XMIT_ALIGN_OFFSET(datagram_size) > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { + return false; + } + return true; +} // xmit_requested_datagram_fits_into_current_ntb + +/** + * Setup an NTB for the glue logic + */ +static bool xmit_setup_next_glue_ntb(void) { + TU_LOG_DRV("xmit_setup_next_glue_ntb - %p\n", ncm_interface.xmit_glue_ntb); + + if (ncm_interface.xmit_glue_ntb != NULL) { + // put NTB into waiting list (the new datagram did not fit in) + xmit_put_ntb_into_ready_list(ncm_interface.xmit_glue_ntb); + } + + ncm_interface.xmit_glue_ntb = xmit_get_free_ntb();// get next buffer (if any) + if (ncm_interface.xmit_glue_ntb == NULL) { + TU_LOG_DRV(" xmit_setup_next_glue_ntb - nothing free\n");// should happen rarely + return false; + } + + ncm_interface.xmit_glue_ntb_datagram_ndx = 0; + + xmit_ntb_t *ntb = ncm_interface.xmit_glue_ntb; + + // Fill in NTB header + ntb->nth.dwSignature = NTH16_SIGNATURE; + ntb->nth.wHeaderLength = sizeof(ntb->nth); + ntb->nth.wSequence = ncm_interface.xmit_sequence++; + ntb->nth.wBlockLength = sizeof(ntb->nth) + sizeof(ntb->ndp) + sizeof(ntb->ndp_datagram); + ntb->nth.wNdpIndex = sizeof(ntb->nth); + + // Fill in NDP16 header and terminator + ntb->ndp.dwSignature = NDP16_SIGNATURE_NCM0; + ntb->ndp.wLength = sizeof(ntb->ndp) + sizeof(ntb->ndp_datagram); + ntb->ndp.wNextNdpIndex = 0; + + memset(ntb->ndp_datagram, 0, sizeof(ntb->ndp_datagram)); + return true; +} // xmit_setup_next_glue_ntb + +//----------------------------------------------------------------------------- +// +// all the recv_*() stuff (TinyUSB -> driver -> glue logic) +// + +/** + * Return pointer to an available receive buffer or NULL. + * Returned buffer (if any) has the size \a CFG_TUD_NCM_OUT_NTB_MAX_SIZE. + */ +static recv_ntb_t *recv_get_free_ntb(void) { + TU_LOG_DRV("recv_get_free_ntb()\n"); + + for (int i = 0; i < RECV_NTB_N; ++i) { + if (ncm_interface.recv_free_ntb[i] != NULL) { + recv_ntb_t *free = ncm_interface.recv_free_ntb[i]; + ncm_interface.recv_free_ntb[i] = NULL; + return free; + } + } + return NULL; +} // recv_get_free_ntb + +/** + * Get the next NTB from the ready list (and remove it from the list). + * If the ready list is empty, return NULL. + */ +static recv_ntb_t *recv_get_next_ready_ntb(void) { + recv_ntb_t *r = NULL; + + r = ncm_interface.recv_ready_ntb[0]; + memmove(ncm_interface.recv_ready_ntb + 0, ncm_interface.recv_ready_ntb + 1, sizeof(ncm_interface.recv_ready_ntb) - sizeof(ncm_interface.recv_ready_ntb[0])); + ncm_interface.recv_ready_ntb[RECV_NTB_N - 1] = NULL; + + TU_LOG_DRV("recv_get_next_ready_ntb: %p\n", r); + return r; +} // recv_get_next_ready_ntb + +/** + * Put NTB into the receiver free list. + */ +static void recv_put_ntb_into_free_list(recv_ntb_t *free_ntb) { + TU_LOG_DRV("recv_put_ntb_into_free_list(%p)\n", free_ntb); + + for (int i = 0; i < RECV_NTB_N; ++i) { + if (ncm_interface.recv_free_ntb[i] == NULL) { + ncm_interface.recv_free_ntb[i] = free_ntb; + return; + } + } + TU_LOG_DRV("(EE) recv_put_ntb_into_free_list - no entry in free list\n");// this should not happen +} // recv_put_ntb_into_free_list + +/** + * \a ready_ntb holds a validated NTB, + * put this buffer into the waiting list. + */ +static void recv_put_ntb_into_ready_list(recv_ntb_t *ready_ntb) { + TU_LOG_DRV("recv_put_ntb_into_ready_list(%p) %d\n", ready_ntb, ready_ntb->nth.wBlockLength); + + for (int i = 0; i < RECV_NTB_N; ++i) { + if (ncm_interface.recv_ready_ntb[i] == NULL) { + ncm_interface.recv_ready_ntb[i] = ready_ntb; + return; + } + } + TU_LOG_DRV("(EE) recv_put_ntb_into_ready_list: ready list full\n");// this should not happen +} // recv_put_ntb_into_ready_list + +/** + * If possible, start a new reception TinyUSB -> driver. + */ +static void recv_try_to_start_new_reception(uint8_t rhport) { + TU_LOG_DRV("recv_try_to_start_new_reception(%d)\n", rhport); + + if (ncm_interface.itf_data_alt != 1) { + return; + } + if (ncm_interface.recv_tinyusb_ntb != NULL) { + return; + } + if (usbd_edpt_busy(rhport, ncm_interface.ep_out)) { + return; + } + + ncm_interface.recv_tinyusb_ntb = recv_get_free_ntb(); + if (ncm_interface.recv_tinyusb_ntb == NULL) { + return; + } + + // initiate transfer + TU_LOG_DRV(" start reception\n"); + bool r = usbd_edpt_xfer(rhport, ncm_interface.ep_out, ncm_interface.recv_tinyusb_ntb->data, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); + if (!r) { + recv_put_ntb_into_free_list(ncm_interface.recv_tinyusb_ntb); + ncm_interface.recv_tinyusb_ntb = NULL; + } +} // recv_try_to_start_new_reception + +/** + * Validate incoming datagram. + * \return true if valid + * + * \note + * \a ndp16->wNextNdpIndex != 0 is not supported + */ +static bool recv_validate_datagram(const recv_ntb_t *ntb, uint32_t len) { + const nth16_t *nth16 = &(ntb->nth); + + TU_LOG_DRV("recv_validate_datagram(%p, %d)\n", ntb, (int) len); + + // check header + if (nth16->wHeaderLength != sizeof(nth16_t)) { + TU_LOG_DRV("(EE) ill nth16 length: %d\n", nth16->wHeaderLength); + return false; + } + if (nth16->dwSignature != NTH16_SIGNATURE) { + TU_LOG_DRV("(EE) ill signature: 0x%08x\n", (unsigned) nth16->dwSignature); + return false; + } + if (len < sizeof(nth16_t) + sizeof(ndp16_t) + 2 * sizeof(ndp16_datagram_t)) { + TU_LOG_DRV("(EE) ill min len: %d\n", len); + return false; + } + if (nth16->wBlockLength > len) { + TU_LOG_DRV("(EE) ill block length: %d > %d\n", nth16->wBlockLength, len); + return false; + } + if (nth16->wBlockLength > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { + TU_LOG_DRV("(EE) ill block length2: %d > %d\n", nth16->wBlockLength, CFG_TUD_NCM_OUT_NTB_MAX_SIZE); + return false; + } + if (nth16->wNdpIndex < sizeof(nth16) || nth16->wNdpIndex > len - (sizeof(ndp16_t) + 2 * sizeof(ndp16_datagram_t))) { + TU_LOG_DRV("(EE) ill position of first ndp: %d (%d)\n", nth16->wNdpIndex, len); + return false; + } + + // check (first) NDP(16) + const ndp16_t *ndp16 = (const ndp16_t *) (ntb->data + nth16->wNdpIndex); + + if (ndp16->wLength < sizeof(ndp16_t) + 2 * sizeof(ndp16_datagram_t)) { + TU_LOG_DRV("(EE) ill ndp16 length: %d\n", ndp16->wLength); + return false; + } + if (ndp16->dwSignature != NDP16_SIGNATURE_NCM0 && ndp16->dwSignature != NDP16_SIGNATURE_NCM1) { + TU_LOG_DRV("(EE) ill signature: 0x%08x\n", (unsigned) ndp16->dwSignature); + return false; + } + if (ndp16->wNextNdpIndex != 0) { + TU_LOG_DRV("(EE) cannot handle wNextNdpIndex!=0 (%d)\n", ndp16->wNextNdpIndex); + return false; + } + + const ndp16_datagram_t *ndp16_datagram = (const ndp16_datagram_t *) (ntb->data + nth16->wNdpIndex + sizeof(ndp16_t)); + int ndx = 0; + uint16_t max_ndx = (uint16_t) ((ndp16->wLength - sizeof(ndp16_t)) / sizeof(ndp16_datagram_t)); + + if (max_ndx > 2) { // number of datagrams in NTB > 1 + TU_LOG_DRV("<< %d (%d)\n", max_ndx - 1, ntb->nth.wBlockLength); + } + if (ndp16_datagram[max_ndx - 1].wDatagramIndex != 0 || ndp16_datagram[max_ndx - 1].wDatagramLength != 0) { + TU_LOG_DRV(" max_ndx != 0\n"); + return false; + } + while (ndp16_datagram[ndx].wDatagramIndex != 0 && ndp16_datagram[ndx].wDatagramLength != 0) { + TU_LOG_DRV(" << %d %d\n", ndp16_datagram[ndx].wDatagramIndex, ndp16_datagram[ndx].wDatagramLength); + if (ndp16_datagram[ndx].wDatagramIndex > len) { + TU_LOG_DRV("(EE) ill start of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex, len); + return false; + } + if (ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength > len) { + TU_LOG_DRV("(EE) ill end of datagram[%d]: %d (%d)\n", ndx, ndp16_datagram[ndx].wDatagramIndex + ndp16_datagram[ndx].wDatagramLength, len); + return false; + } + ++ndx; + } + + #if CFG_TUD_NCM_LOG_LEVEL >= 3 + TU_LOG_BUF(3, ntb->data[i], len); + #endif + + // -> ntb contains a valid packet structure + // ok... I did not check for garbage within the datagram indices... + return true; +} // recv_validate_datagram + +/** + * Transfer the next (pending) datagram to the glue logic and return receive buffer if empty. + */ +static void recv_transfer_datagram_to_glue_logic(void) { + TU_LOG_DRV("recv_transfer_datagram_to_glue_logic()\n"); + + if (ncm_interface.recv_glue_ntb == NULL) { + ncm_interface.recv_glue_ntb = recv_get_next_ready_ntb(); + TU_LOG_DRV(" new buffer for glue logic: %p\n", ncm_interface.recv_glue_ntb); + ncm_interface.recv_glue_ntb_datagram_ndx = 0; + } + + if (ncm_interface.recv_glue_ntb != NULL) { + const ndp16_datagram_t *ndp16_datagram = (ndp16_datagram_t *) (ncm_interface.recv_glue_ntb->data + ncm_interface.recv_glue_ntb->nth.wNdpIndex + sizeof(ndp16_t)); + + if (ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramIndex == 0) { + TU_LOG_DRV("(EE) SOMETHING WENT WRONG 1\n"); + } else if (ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramLength == 0) { + TU_LOG_DRV("(EE) SOMETHING WENT WRONG 2\n"); + } else { + uint16_t datagramIndex = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramIndex; + uint16_t datagramLength = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx].wDatagramLength; + + TU_LOG_DRV(" recv[%d] - %d %d\n", ncm_interface.recv_glue_ntb_datagram_ndx, datagramIndex, datagramLength); + if (tud_network_recv_cb(ncm_interface.recv_glue_ntb->data + datagramIndex, datagramLength)) { + // send datagram successfully to glue logic + TU_LOG_DRV(" OK\n"); + datagramIndex = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx + 1].wDatagramIndex; + datagramLength = ndp16_datagram[ncm_interface.recv_glue_ntb_datagram_ndx + 1].wDatagramLength; + + if (datagramIndex != 0 && datagramLength != 0) { + // -> next datagram + ++ncm_interface.recv_glue_ntb_datagram_ndx; + } else { + // end of datagrams reached + recv_put_ntb_into_free_list(ncm_interface.recv_glue_ntb); + ncm_interface.recv_glue_ntb = NULL; + } + } + } + } +} // recv_transfer_datagram_to_glue_logic + +//----------------------------------------------------------------------------- +// +// all the tud_network_*() stuff (glue logic -> driver) +// + +/** + * Check if the glue logic is allowed to call tud_network_xmit(). + * This function also fetches a next buffer if required, so that tud_network_xmit() is ready for copy + * and transmission operation. + */ +bool tud_network_can_xmit(uint16_t size) { + TU_LOG_DRV("tud_network_can_xmit(%d)\n", size); + + TU_ASSERT(size <= CFG_TUD_NCM_OUT_NTB_MAX_SIZE - (sizeof(nth16_t) + sizeof(ndp16_t) + 2 * sizeof(ndp16_datagram_t)), false); + + if (xmit_requested_datagram_fits_into_current_ntb(size) || xmit_setup_next_glue_ntb()) { + // -> everything is fine + return true; + } + xmit_start_if_possible(ncm_interface.rhport); + TU_LOG_DRV("(II) tud_network_can_xmit: request blocked\n");// could happen if all xmit buffers are full (but should happen rarely) + return false; +} // tud_network_can_xmit + +/** + * Put a datagram into a waiting NTB. + * If currently no transmission is started, then initiate transmission. + */ +void tud_network_xmit(void *ref, uint16_t arg) { + TU_LOG_DRV("tud_network_xmit(%p, %d)\n", ref, arg); + + if (ncm_interface.xmit_glue_ntb == NULL) { + TU_LOG_DRV("(EE) tud_network_xmit: no buffer\n");// must not happen (really) + return; + } + + xmit_ntb_t *ntb = ncm_interface.xmit_glue_ntb; + + // copy new datagram to the end of the current NTB + uint16_t size = tud_network_xmit_cb(ntb->data + ntb->nth.wBlockLength, ref, arg); + + // correct NTB internals + ntb->ndp_datagram[ncm_interface.xmit_glue_ntb_datagram_ndx].wDatagramIndex = ntb->nth.wBlockLength; + ntb->ndp_datagram[ncm_interface.xmit_glue_ntb_datagram_ndx].wDatagramLength = size; + ncm_interface.xmit_glue_ntb_datagram_ndx += 1; + + ntb->nth.wBlockLength += (uint16_t) (size + XMIT_ALIGN_OFFSET(size)); + + if (ntb->nth.wBlockLength > CFG_TUD_NCM_OUT_NTB_MAX_SIZE) { + TU_LOG_DRV("(EE) tud_network_xmit: buffer overflow\n"); // must not happen (really) + return; + } + + xmit_start_if_possible(ncm_interface.rhport); +} // tud_network_xmit + +/** + * Keep the receive logic busy and transfer pending packets to the glue logic. + */ +void tud_network_recv_renew(void) { + TU_LOG_DRV("tud_network_recv_renew()\n"); + + recv_transfer_datagram_to_glue_logic(); + recv_try_to_start_new_reception(ncm_interface.rhport); +} // tud_network_recv_renew + +/** + * Same as tud_network_recv_renew() but knows \a rhport + */ +void tud_network_recv_renew_r(uint8_t rhport) { + TU_LOG_DRV("tud_network_recv_renew_r(%d)\n", rhport); + + ncm_interface.rhport = rhport; + tud_network_recv_renew(); +} // tud_network_recv_renew + +//----------------------------------------------------------------------------- +// +// all the netd_*() stuff (interface TinyUSB -> driver) +// +/** + * Initialize the driver data structures. + * Might be called several times. + */ +void netd_init(void) { + TU_LOG_DRV("netd_init()\n"); + + memset(&ncm_interface, 0, sizeof(ncm_interface)); + + for (int i = 0; i < XMIT_NTB_N; ++i) { + ncm_interface.xmit_free_ntb[i] = ncm_interface.xmit_ntb + i; + } + for (int i = 0; i < RECV_NTB_N; ++i) { + ncm_interface.recv_free_ntb[i] = ncm_interface.recv_ntb + i; + } +} // netd_init + +/** + * Deinit driver + */ +bool netd_deinit(void) { + return true; } -//--------------------------------------------------------------------+ -// USBD Driver API -//--------------------------------------------------------------------+ - -void netd_init(void) -{ - tu_memclr(&ncm_interface, sizeof(ncm_interface)); - ncm_interface.ntb_in_size = CFG_TUD_NCM_IN_NTB_MAX_SIZE; - ncm_interface.max_datagrams_per_ntb = CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB; - ncm_prepare_for_tx(); -} - -void netd_reset(uint8_t rhport) -{ +/** + * Resets the port. + * In this driver this is the same as netd_init() + */ +void netd_reset(uint8_t rhport) { (void) rhport; netd_init(); -} +} // netd_reset -uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) -{ - // confirm interface hasn't already been allocated - TU_ASSERT(0 == ncm_interface.ep_notif, 0); +/** + * Open the USB interface. + * - parse the USB descriptor \a TUD_CDC_NCM_DESCRIPTOR for itfnum and endpoints + * - a specific order of elements in the descriptor is tested. + * + * \note + * Actually all of the information could be read directly from \a itf_desc, because the + * structure and the values are well known. But we do it this way. + * + * \post + * - \a itf_num set + * - \a ep_notif, \a ep_in and \a ep_out are set + * - USB interface is open + */ +uint16_t netd_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { + TU_ASSERT(ncm_interface.ep_notif == 0, 0);// assure that the interface is only opened once - //------------- Management Interface -------------// - ncm_interface.itf_num = itf_desc->bInterfaceNumber; + ncm_interface.itf_num = itf_desc->bInterfaceNumber;// management interface + // skip the two first entries and the following TUSB_DESC_CS_INTERFACE entries uint16_t drv_len = sizeof(tusb_desc_interface_t); - uint8_t const * p_desc = tu_desc_next( itf_desc ); - - // Communication Functional Descriptors - while ( TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) && drv_len <= max_len ) - { + uint8_t const *p_desc = tu_desc_next(itf_desc); + while (tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE && drv_len <= max_len) { drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); + p_desc = tu_desc_next(p_desc); } - // notification endpoint (if any) - if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) ) - { - TU_ASSERT( usbd_edpt_open(rhport, (tusb_desc_endpoint_t const *) p_desc), 0 ); + // get notification endpoint + TU_ASSERT(tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT, 0); + TU_ASSERT(usbd_edpt_open(rhport, (tusb_desc_endpoint_t const *) p_desc), 0); + ncm_interface.ep_notif = ((tusb_desc_endpoint_t const *) p_desc)->bEndpointAddress; + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); - ncm_interface.ep_notif = ((tusb_desc_endpoint_t const *) p_desc)->bEndpointAddress; + // skip the following TUSB_DESC_INTERFACE entries (which must be TUSB_CLASS_CDC_DATA) + while (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && drv_len <= max_len) { + tusb_desc_interface_t const *data_itf_desc = (tusb_desc_interface_t const *) p_desc; + TU_ASSERT(data_itf_desc->bInterfaceClass == TUSB_CLASS_CDC_DATA, 0); drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); + p_desc = tu_desc_next(p_desc); } - //------------- Data Interface -------------// - // - CDC-NCM data interface has 2 alternate settings - // - 0 : zero endpoints for inactive (default) - // - 1 : IN & OUT endpoints for transfer of NTBs - TU_ASSERT(TUSB_DESC_INTERFACE == tu_desc_type(p_desc), 0); - - do - { - tusb_desc_interface_t const * data_itf_desc = (tusb_desc_interface_t const *) p_desc; - TU_ASSERT(TUSB_CLASS_CDC_DATA == data_itf_desc->bInterfaceClass, 0); - - drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); - } while((TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) && (drv_len <= max_len)); - - // Pair of endpoints - TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(p_desc), 0); - - TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &ncm_interface.ep_out, &ncm_interface.ep_in) ); - - drv_len += 2*sizeof(tusb_desc_endpoint_t); + // a TUSB_DESC_ENDPOINT (actually two) must follow, open these endpoints + TU_ASSERT(tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT, 0); + TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &ncm_interface.ep_out, &ncm_interface.ep_in)); + drv_len += 2 * sizeof(tusb_desc_endpoint_t); return drv_len; -} +} // netd_open -static void ncm_report(void) -{ - uint8_t const rhport = 0; - if (ncm_interface.report_state == REPORT_SPEED) { - ncm_notify_speed_change.header.wIndex = ncm_interface.itf_num; - usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t *) &ncm_notify_speed_change, sizeof(ncm_notify_speed_change)); - ncm_interface.report_state = REPORT_CONNECTED; - ncm_interface.report_pending = true; - } else if (ncm_interface.report_state == REPORT_CONNECTED) { - ncm_notify_connected.header.wIndex = ncm_interface.itf_num; - usbd_edpt_xfer(rhport, ncm_interface.ep_notif, (uint8_t *) &ncm_notify_connected, sizeof(ncm_notify_connected)); - ncm_interface.report_state = REPORT_DONE; - ncm_interface.report_pending = true; +/** + * Handle TinyUSB requests to process transfer events. + */ +bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { + (void) result; + + if (ep_addr == ncm_interface.ep_out) { + // new NTB received + // - make the NTB valid + // - if ready transfer datagrams to the glue logic for further processing + // - if there is a free receive buffer, initiate reception + if (!recv_validate_datagram(ncm_interface.recv_tinyusb_ntb, xferred_bytes)) { + // verification failed: ignore NTB and return it to free + TU_LOG_DRV("(EE) VALIDATION FAILED. WHAT CAN WE DO IN THIS CASE?\n"); + } else { + // packet ok -> put it into ready list + recv_put_ntb_into_ready_list(ncm_interface.recv_tinyusb_ntb); + } + ncm_interface.recv_tinyusb_ntb = NULL; + tud_network_recv_renew_r(rhport); + } else if (ep_addr == ncm_interface.ep_in) { + // transmission of an NTB finished + // - free the transmitted NTB buffer + // - insert ZLPs when necessary + // - if there is another transmit NTB waiting, try to start transmission + xmit_put_ntb_into_free_list(ncm_interface.xmit_tinyusb_ntb); + ncm_interface.xmit_tinyusb_ntb = NULL; + if (!xmit_insert_required_zlp(rhport, xferred_bytes)) { + xmit_start_if_possible(rhport); + } + } else if (ep_addr == ncm_interface.ep_notif) { + // next transfer on notification channel + notification_xmit(rhport, true); } -} -TU_ATTR_WEAK void tud_network_link_state_cb(bool state) -{ - (void)state; -} + return true; +} // netd_xfer_cb -// Handle class control request -// return false to stall control endpoint (e.g unsupported request) -bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) -{ - if ( stage != CONTROL_STAGE_SETUP ) return true; +/** + * Respond to TinyUSB control requests. + * At startup transmission of notification packets are done here. + */ +bool netd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) { + if (stage != CONTROL_STAGE_SETUP) { + return true; + } - switch ( request->bmRequestType_bit.type ) - { + switch (request->bmRequestType_bit.type) { case TUSB_REQ_TYPE_STANDARD: - switch ( request->bRequest ) - { - case TUSB_REQ_GET_INTERFACE: - { - uint8_t const req_itfnum = (uint8_t) request->wIndex; - TU_VERIFY(ncm_interface.itf_num + 1 == req_itfnum); + + switch (request->bRequest) { + case TUSB_REQ_GET_INTERFACE: { + TU_VERIFY(ncm_interface.itf_num + 1 == request->wIndex, false); tud_control_xfer(rhport, request, &ncm_interface.itf_data_alt, 1); - } - break; + } break; - case TUSB_REQ_SET_INTERFACE: - { - uint8_t const req_itfnum = (uint8_t) request->wIndex; - uint8_t const req_alt = (uint8_t) request->wValue; + case TUSB_REQ_SET_INTERFACE: { + TU_VERIFY(ncm_interface.itf_num + 1 == request->wIndex && request->wValue < 2, false); - // Only valid for Data Interface with Alternate is either 0 or 1 - TU_VERIFY(ncm_interface.itf_num + 1 == req_itfnum && req_alt < 2); + ncm_interface.itf_data_alt = (uint8_t) request->wValue; - if (req_alt != ncm_interface.itf_data_alt) { - ncm_interface.itf_data_alt = req_alt; - - if (ncm_interface.itf_data_alt) { - if (!usbd_edpt_busy(rhport, ncm_interface.ep_out)) { - tud_network_recv_renew(); // prepare for incoming datagrams - } - if (!ncm_interface.report_pending) { - ncm_report(); - } - } - - tud_network_link_state_cb(ncm_interface.itf_data_alt); + if (ncm_interface.itf_data_alt == 1) { + tud_network_recv_renew_r(rhport); + notification_xmit(rhport, false); } - tud_control_status(rhport, request); - } - break; + } break; - // unsupported request - default: return false; + // unsupported request + default: + return false; } break; case TUSB_REQ_TYPE_CLASS: - TU_VERIFY (ncm_interface.itf_num == request->wIndex); + TU_VERIFY(ncm_interface.itf_num == request->wIndex, false); + switch (request->bRequest) { + case NCM_GET_NTB_PARAMETERS: { + // transfer NTB parameters to host. + tud_control_xfer(rhport, request, (void *) (uintptr_t) &ntb_parameters, sizeof(ntb_parameters)); + } break; - if (NCM_GET_NTB_PARAMETERS == request->bRequest) - { - tud_control_xfer(rhport, request, (void*)(uintptr_t) &ntb_parameters, sizeof(ntb_parameters)); + // unsupported request + default: + return false; } - break; - // unsupported request - default: return false; + default: + return false; } return true; -} +} // netd_control_xfer_cb -static void handle_incoming_datagram(uint32_t len) -{ - uint32_t size = len; - - if (len == 0) { - return; - } - - TU_ASSERT(size >= sizeof(nth16_t), ); - - const nth16_t *hdr = (const nth16_t *)receive_ntb; - TU_ASSERT(hdr->dwSignature == NTH16_SIGNATURE, ); - TU_ASSERT(hdr->wNdpIndex >= sizeof(nth16_t) && (hdr->wNdpIndex + sizeof(ndp16_t)) <= len, ); - - const ndp16_t *ndp = (const ndp16_t *)(receive_ntb + hdr->wNdpIndex); - TU_ASSERT(ndp->dwSignature == NDP16_SIGNATURE_NCM0 || ndp->dwSignature == NDP16_SIGNATURE_NCM1, ); - TU_ASSERT(hdr->wNdpIndex + ndp->wLength <= len, ); - - int num_datagrams = (ndp->wLength - 12) / 4; - ncm_interface.current_datagram_index = 0; - ncm_interface.num_datagrams = 0; - ncm_interface.ndp = ndp; - for (int i = 0; i < num_datagrams && ndp->datagram[i].wDatagramIndex && ndp->datagram[i].wDatagramLength; i++) - { - ncm_interface.num_datagrams++; - } - - tud_network_recv_renew(); -} - -bool netd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) -{ - (void) rhport; - (void) result; - - /* new datagram receive_ntb */ - if (ep_addr == ncm_interface.ep_out ) - { - handle_incoming_datagram(xferred_bytes); - } - - /* data transmission finished */ - if (ep_addr == ncm_interface.ep_in ) - { - if (ncm_interface.transferring) { - ncm_interface.transferring = false; - } - - // If there are datagrams queued up that we tried to send while this NTB was being emitted, send them now - if (ncm_interface.datagram_count && ncm_interface.itf_data_alt == 1) { - ncm_start_tx(); - } - } - - if (ep_addr == ncm_interface.ep_notif ) - { - ncm_interface.report_pending = false; - ncm_report(); - } - - return true; -} - -// poll network driver for its ability to accept another packet to transmit -bool tud_network_can_xmit(uint16_t size) -{ - TU_VERIFY(ncm_interface.itf_data_alt == 1); - - if (ncm_interface.datagram_count >= ncm_interface.max_datagrams_per_ntb) { - TU_LOG_DRV("NTB full [by count]\r\n"); - return false; - } - - size_t next_datagram_offset = ncm_interface.next_datagram_offset; - if (next_datagram_offset + size > ncm_interface.ntb_in_size) { - TU_LOG_DRV("ntb full [by size]\r\n"); - return false; - } - - return true; -} - -void tud_network_xmit(void *ref, uint16_t arg) -{ - transmit_ntb_t *ntb = &transmit_ntb[ncm_interface.current_ntb]; - size_t next_datagram_offset = ncm_interface.next_datagram_offset; - - uint16_t size = tud_network_xmit_cb(ntb->data + next_datagram_offset, ref, arg); - - ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramIndex = ncm_interface.next_datagram_offset; - ntb->ndp.datagram[ncm_interface.datagram_count].wDatagramLength = size; - - ncm_interface.datagram_count++; - next_datagram_offset += size; - - // round up so the next datagram is aligned correctly - next_datagram_offset += (CFG_TUD_NCM_ALIGNMENT - 1); - next_datagram_offset -= (next_datagram_offset % CFG_TUD_NCM_ALIGNMENT); - - ncm_interface.next_datagram_offset = next_datagram_offset; - - ncm_start_tx(); -} - -#endif +#endif // ( CFG_TUD_ENABLED && CFG_TUD_NCM ) diff --git a/src/class/net/net_device.h b/src/class/net/net_device.h index 399916355..4c9a92f2d 100644 --- a/src/class/net/net_device.h +++ b/src/class/net/net_device.h @@ -28,14 +28,13 @@ #ifndef _TUSB_NET_DEVICE_H_ #define _TUSB_NET_DEVICE_H_ +#include #include "class/cdc/cdc.h" #if CFG_TUD_ECM_RNDIS && CFG_TUD_NCM #error "Cannot enable both ECM_RNDIS and NCM network drivers" #endif -#include "ncm.h" - /* declared here, NOT in usb_descriptors.c, so that the driver can intelligently ZLP as needed */ #define CFG_TUD_NET_ENDPOINT_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) @@ -44,21 +43,13 @@ #define CFG_TUD_NET_MTU 1514 #endif -#ifndef CFG_TUD_NCM_IN_NTB_MAX_SIZE -#define CFG_TUD_NCM_IN_NTB_MAX_SIZE 3200 -#endif -#ifndef CFG_TUD_NCM_OUT_NTB_MAX_SIZE -#define CFG_TUD_NCM_OUT_NTB_MAX_SIZE 3200 -#endif +// Table 4.3 Data Class Interface Protocol Codes +typedef enum +{ + NCM_DATA_PROTOCOL_NETWORK_TRANSFER_BLOCK = 0x01 +} ncm_data_interface_protocol_code_t; -#ifndef CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB -#define CFG_TUD_NCM_MAX_DATAGRAMS_PER_NTB 8 -#endif - -#ifndef CFG_TUD_NCM_ALIGNMENT -#define CFG_TUD_NCM_ALIGNMENT 4 -#endif #ifdef __cplusplus extern "C" { @@ -96,15 +87,11 @@ void tud_network_init_cb(void); // TODO removed later since it is not part of tinyusb stack extern uint8_t tud_network_mac_address[6]; -//------------- NCM -------------// - -// callback to client providing optional indication of internal state of network driver -void tud_network_link_state_cb(bool state); - //--------------------------------------------------------------------+ // INTERNAL USBD-CLASS DRIVER API //--------------------------------------------------------------------+ void netd_init (void); +bool netd_deinit (void); void netd_reset (uint8_t rhport); uint16_t netd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool netd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/class/usbtmc/usbtmc.h b/src/class/usbtmc/usbtmc.h index 090ab3c4a..327de087c 100644 --- a/src/class/usbtmc/usbtmc.h +++ b/src/class/usbtmc/usbtmc.h @@ -183,6 +183,23 @@ typedef enum { } usmtmc_request_type_enum; +typedef enum { + // The last and first valid bNotify1 for use by the USBTMC class specification. + USBTMC_bNOTIFY1_USBTMC_FIRST = 0x00, + USBTMC_bNOTIFY1_USBTMC_LAST = 0x3F, + + // The last and first valid bNotify1 for use by vendors. + USBTMC_bNOTIFY1_VENDOR_SPECIFIC_FIRST = 0x40, + USBTMC_bNOTIFY1_VENDOR_SPECIFIC_LAST = 0x7F, + + // The last and first valid bNotify1 for use by USBTMC subclass specifications. + USBTMC_bNOTIFY1_SUBCLASS_FIRST = 0x80, + USBTMC_bNOTIFY1_SUBCLASS_LAST = 0xFF, + + // From the USB488 Subclass Specification, Section 3.4. + USB488_bNOTIFY1_SRQ = 0x81, +} usbtmc_int_in_payload_format; + typedef enum { USBTMC_STATUS_SUCCESS = 0x01, USBTMC_STATUS_PENDING = 0x02, @@ -303,6 +320,14 @@ typedef struct TU_ATTR_PACKED TU_VERIFY_STATIC(sizeof(usbtmc_read_stb_rsp_488_t) == 3u, "struct wrong length"); +typedef struct TU_ATTR_PACKED +{ + uint8_t bNotify1; // Must be USB488_bNOTIFY1_SRQ + uint8_t StatusByte; +} usbtmc_srq_interrupt_488_t; + +TU_VERIFY_STATIC(sizeof(usbtmc_srq_interrupt_488_t) == 2u, "struct wrong length"); + typedef struct TU_ATTR_PACKED { struct TU_ATTR_PACKED diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 573654d58..129ff465d 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -86,6 +86,11 @@ tu_static char logMsg[150]; // imposes a minimum buffer size of 32 bytes. #define USBTMCD_BUFFER_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +// Interrupt endpoint buffer size, default to 2 bytes as USB488 specification. +#ifndef CFG_TUD_USBTMC_INT_EP_SIZE +#define CFG_TUD_USBTMC_INT_EP_SIZE 2 +#endif + /* * The state machine does not allow simultaneous reading and writing. This is * consistent with USBTMC. @@ -124,13 +129,15 @@ typedef struct uint8_t ep_bulk_in; uint8_t ep_bulk_out; uint8_t ep_int_in; + uint32_t ep_bulk_in_wMaxPacketSize; + uint32_t ep_bulk_out_wMaxPacketSize; // IN buffer is only used for first packet, not the remainder // in order to deal with prepending header CFG_TUSB_MEM_ALIGN uint8_t ep_bulk_in_buf[USBTMCD_BUFFER_SIZE]; - uint32_t ep_bulk_in_wMaxPacketSize; // OUT buffer receives one packet at a time CFG_TUSB_MEM_ALIGN uint8_t ep_bulk_out_buf[USBTMCD_BUFFER_SIZE]; - uint32_t ep_bulk_out_wMaxPacketSize; + // Buffer int msg to ensure alignment and placement correctness + CFG_TUSB_MEM_ALIGN uint8_t ep_int_in_buf[CFG_TUD_USBTMC_INT_EP_SIZE]; uint32_t transfer_size_remaining; // also used for requested length for bulk IN. uint32_t transfer_size_sent; // To keep track of data bytes that have been queued in FIFO (not header bytes) @@ -240,6 +247,19 @@ bool tud_usbtmc_transmit_dev_msg_data( return true; } +bool tud_usbtmc_transmit_notification_data(const void * data, size_t len) +{ +#ifndef NDEBUG + TU_ASSERT(len > 0); + TU_ASSERT(usbtmc_state.ep_int_in != 0); +#endif + TU_VERIFY(usbd_edpt_busy(usbtmc_state.rhport, usbtmc_state.ep_int_in)); + + TU_VERIFY(tu_memcpy_s(usbtmc_state.ep_int_in_buf, sizeof(usbtmc_state.ep_int_in_buf), data, len) == 0); + TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_int_in, usbtmc_state.ep_int_in_buf, (uint16_t)len)); + return true; +} + void usbtmcd_init_cb(void) { usbtmc_state.capabilities = tud_usbtmc_get_capabilities_cb(); @@ -260,6 +280,13 @@ void usbtmcd_init_cb(void) usbtmcLock = osal_mutex_create(&usbtmcLockBuffer); } +bool usbtmcd_deinit(void) { + #if OSAL_MUTEX_REQUIRED + osal_mutex_delete(usbtmcLock); + #endif + return true; +} + uint16_t usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) { (void)rhport; @@ -353,7 +380,7 @@ uint16_t usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, // processing a command (such as a clear). Returns true if it was // in the NAK state and successfully transitioned to the ACK wait // state. -bool tud_usbtmc_start_bus_read() +bool tud_usbtmc_start_bus_read(void) { usbtmcd_state_enum oldState = usbtmc_state.state; switch(oldState) @@ -540,9 +567,10 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint case STATE_TX_INITIATED: if(usbtmc_state.transfer_size_remaining >= sizeof(usbtmc_state.ep_bulk_in_buf)) { - // FIXME! This removes const below! + // Copy buffer to ensure alignment correctness + memcpy(usbtmc_state.ep_bulk_in_buf, usbtmc_state.devInBuffer, sizeof(usbtmc_state.ep_bulk_in_buf)); TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, - (void*)(uintptr_t) usbtmc_state.devInBuffer, sizeof(usbtmc_state.ep_bulk_in_buf))); + usbtmc_state.ep_bulk_in_buf, sizeof(usbtmc_state.ep_bulk_in_buf))); usbtmc_state.devInBuffer += sizeof(usbtmc_state.ep_bulk_in_buf); usbtmc_state.transfer_size_remaining -= sizeof(usbtmc_state.ep_bulk_in_buf); usbtmc_state.transfer_size_sent += sizeof(usbtmc_state.ep_bulk_in_buf); @@ -578,7 +606,9 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint } } else if (ep_addr == usbtmc_state.ep_int_in) { - // Good? + if (tud_usbtmc_notification_complete_cb) { + TU_VERIFY(tud_usbtmc_notification_complete_cb()); + } return true; } return false; diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h index c1298ddb8..b85ef12b5 100644 --- a/src/class/usbtmc/usbtmc_device.h +++ b/src/class/usbtmc/usbtmc_device.h @@ -73,6 +73,10 @@ bool tud_usbtmc_check_abort_bulk_in_cb(usbtmc_check_abort_bulk_rsp_t *rsp); bool tud_usbtmc_check_abort_bulk_out_cb(usbtmc_check_abort_bulk_rsp_t *rsp); bool tud_usbtmc_check_clear_cb(usbtmc_get_clear_status_rsp_t *rsp); +// The interrupt-IN endpoint buffer was transmitted to the host. Use +// tud_usbtmc_transmit_notification_data to send another notification. +TU_ATTR_WEAK bool tud_usbtmc_notification_complete_cb(void); + // Indicator pulse should be 0.5 to 1.0 seconds long TU_ATTR_WEAK bool tud_usbtmc_indicator_pulse_cb(tusb_control_request_t const * msg, uint8_t *tmcResult); @@ -82,31 +86,33 @@ TU_ATTR_WEAK bool tud_usbtmc_msg_trigger_cb(usbtmc_msg_generic_t* msg); //TU_ATTR_WEAK bool tud_usbtmc_app_go_to_local_cb(); #endif -/******************************************* - * Called from app - * - * We keep a reference to the buffer, so it MUST not change until the app is - * notified that the transfer is complete. - ******************************************/ - +// Called from app +// +// We keep a reference to the buffer, so it MUST not change until the app is +// notified that the transfer is complete. bool tud_usbtmc_transmit_dev_msg_data( const void * data, size_t len, bool endOfMessage, bool usingTermChar); +// Buffers a notification to be sent to the host. The data starts +// with the bNotify1 field, see the USBTMC Specification, Table 13. +// +// If the previous notification data has not yet been sent, this +// returns false. +// +// Requires an interrupt endpoint in the interface. +bool tud_usbtmc_transmit_notification_data(const void * data, size_t len); + bool tud_usbtmc_start_bus_read(void); /* "callbacks" from USB device core */ +void usbtmcd_init_cb(void); +bool usbtmcd_deinit(void); uint16_t usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); void usbtmcd_reset_cb(uint8_t rhport); bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); -void usbtmcd_init_cb(void); - -/************************************************************ - * USBTMC Descriptor Templates - *************************************************************/ - #endif /* CLASS_USBTMC_USBTMC_DEVICE_H_ */ diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index 389a29696..56ef098c7 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -36,6 +36,8 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ +#define BULK_PACKET_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) + typedef struct { uint8_t itf_num; @@ -49,10 +51,8 @@ typedef struct uint8_t rx_ff_buf[CFG_TUD_VENDOR_RX_BUFSIZE]; uint8_t tx_ff_buf[CFG_TUD_VENDOR_TX_BUFSIZE]; -#if CFG_FIFO_MUTEX - osal_mutex_def_t rx_ff_mutex; - osal_mutex_def_t tx_ff_mutex; -#endif + OSAL_MUTEX_DEF(rx_ff_mutex); + OSAL_MUTEX_DEF(tx_ff_mutex); // Endpoint Transfer buffer CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_VENDOR_EPSIZE]; @@ -171,25 +171,49 @@ uint32_t tud_vendor_n_write_available (uint8_t itf) //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ -void vendord_init(void) -{ +void vendord_init(void) { tu_memclr(_vendord_itf, sizeof(_vendord_itf)); - for(uint8_t i=0; irx_ff, p_itf->rx_ff_buf, CFG_TUD_VENDOR_RX_BUFSIZE, 1, false); tu_fifo_config(&p_itf->tx_ff, p_itf->tx_ff_buf, CFG_TUD_VENDOR_TX_BUFSIZE, 1, false); -#if CFG_FIFO_MUTEX - tu_fifo_config_mutex(&p_itf->rx_ff, NULL, osal_mutex_create(&p_itf->rx_ff_mutex)); - tu_fifo_config_mutex(&p_itf->tx_ff, osal_mutex_create(&p_itf->tx_ff_mutex), NULL); -#endif + #if OSAL_MUTEX_REQUIRED + osal_mutex_t mutex_rd = osal_mutex_create(&p_itf->rx_ff_mutex); + osal_mutex_t mutex_wr = osal_mutex_create(&p_itf->tx_ff_mutex); + TU_ASSERT(mutex_rd && mutex_wr,); + + tu_fifo_config_mutex(&p_itf->rx_ff, NULL, mutex_rd); + tu_fifo_config_mutex(&p_itf->tx_ff, mutex_wr, NULL); + #endif } } +bool vendord_deinit(void) { + #if OSAL_MUTEX_REQUIRED + for(uint8_t i=0; irx_ff.mutex_rd; + osal_mutex_t mutex_wr = p_itf->tx_ff.mutex_wr; + + if (mutex_rd) { + osal_mutex_delete(mutex_rd); + tu_fifo_config_mutex(&p_itf->rx_ff, NULL, NULL); + } + + if (mutex_wr) { + osal_mutex_delete(mutex_wr); + tu_fifo_config_mutex(&p_itf->tx_ff, NULL, NULL); + } + } + #endif + + return true; +} + void vendord_reset(uint8_t rhport) { (void) rhport; @@ -251,7 +275,6 @@ uint16_t vendord_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, ui bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { - (void) rhport; (void) result; uint8_t itf = 0; @@ -278,7 +301,18 @@ bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint { if (tud_vendor_tx_cb) tud_vendor_tx_cb(itf, (uint16_t) xferred_bytes); // Send complete, try to send more if possible - tud_vendor_n_write_flush(itf); + if ( 0 == tud_vendor_n_write_flush(itf) ) + { + // If there is no data left, a ZLP should be sent if + // xferred_bytes is multiple of EP Packet size and not zero + if ( !tu_fifo_count(&p_itf->tx_ff) && xferred_bytes && (0 == (xferred_bytes & (BULK_PACKET_SIZE-1))) ) + { + if ( usbd_edpt_claim(rhport, p_itf->ep_in) ) + { + usbd_edpt_xfer(rhport, p_itf->ep_in, NULL, 0); + } + } + } } return true; diff --git a/src/class/vendor/vendor_device.h b/src/class/vendor/vendor_device.h index d239406b4..cd69ec7c6 100644 --- a/src/class/vendor/vendor_device.h +++ b/src/class/vendor/vendor_device.h @@ -139,6 +139,7 @@ static inline uint32_t tud_vendor_write_available (void) // Internal Class Driver API //--------------------------------------------------------------------+ void vendord_init(void); +bool vendord_deinit(void); void vendord_reset(uint8_t rhport); uint16_t vendord_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); diff --git a/src/class/video/video.h b/src/class/video/video.h index d9880c291..b8a9b6369 100644 --- a/src/class/video/video.h +++ b/src/class/video/video.h @@ -29,6 +29,10 @@ #include "common/tusb_common.h" +enum { + VIDEO_BCD_1_50 = 0x0150, +}; + // Table 3-19 Color Matching Descriptor typedef enum { VIDEO_COLOR_PRIMARIES_UNDEFINED = 0x00, @@ -156,22 +160,23 @@ typedef enum { /* A.9.1 VideoControl Interface Control Selectors */ typedef enum { VIDEO_VC_CTL_UNDEFINED = 0x00, - VIDEO_VC_CTL_VIDEO_POWER_MODE, - VIDEO_VC_CTL_REQUEST_ERROR_CODE, + VIDEO_VC_CTL_VIDEO_POWER_MODE, // 0x01 + VIDEO_VC_CTL_REQUEST_ERROR_CODE, // 0x02 } video_interface_control_selector_t; /* A.9.8 VideoStreaming Interface Control Selectors */ typedef enum { VIDEO_VS_CTL_UNDEFINED = 0x00, - VIDEO_VS_CTL_PROBE, - VIDEO_VS_CTL_COMMIT, - VIDEO_VS_CTL_STILL_PROBE, - VIDEO_VS_CTL_STILL_COMMIT, - VIDEO_VS_CTL_STILL_IMAGE_TRIGGER, - VIDEO_VS_CTL_STREAM_ERROR_CODE, - VIDEO_VS_CTL_GENERATE_KEY_FRAME, - VIDEO_VS_CTL_UPDATE_FRAME_SEGMENT, - VIDEO_VS_CTL_SYNCH_DELAY_CONTROL, + VIDEO_VS_CTL_PROBE, // 0x01 + VIDEO_VS_CTL_COMMIT, // 0x02 + VIDEO_VS_CTL_STILL_PROBE, // 0x03 + VIDEO_VS_CTL_STILL_COMMIT, // 0x04 + VIDEO_VS_CTL_STILL_IMAGE_TRIGGER, // 0x05 + VIDEO_VS_CTL_STREAM_ERROR_CODE, // 0x06 + VIDEO_VS_CTL_GENERATE_KEY_FRAME, // 0x07 + VIDEO_VS_CTL_UPDATE_FRAME_SEGMENT, // 0x08 + VIDEO_VS_CTL_SYNCH_DELAY_CONTROL, // 0x09 + } video_interface_streaming_selector_t; /* B. Terminal Types */ @@ -198,55 +203,98 @@ typedef enum { } video_terminal_type_t; //--------------------------------------------------------------------+ -// Descriptors +// Video Control (VC) Descriptors //--------------------------------------------------------------------+ /* 2.3.4.2 */ +#define tusb_desc_video_control_header_nitf_t(_nitf) \ + struct TU_ATTR_PACKED { \ + uint8_t bLength; \ + uint8_t bDescriptorType; \ + uint8_t bDescriptorSubType; \ + uint16_t bcdUVC; \ + uint16_t wTotalLength; \ + uint32_t dwClockFrequency; /* deprecated */ \ + uint8_t bInCollection; \ + uint8_t baInterfaceNr[_nitf]; \ + } + +typedef tusb_desc_video_control_header_nitf_t() tusb_desc_video_control_header_t; +typedef tusb_desc_video_control_header_nitf_t(1) tusb_desc_video_control_header_1itf_t; +typedef tusb_desc_video_control_header_nitf_t(2) tusb_desc_video_control_header_2itf_t; +typedef tusb_desc_video_control_header_nitf_t(3) tusb_desc_video_control_header_3itf_t; +typedef tusb_desc_video_control_header_nitf_t(4) tusb_desc_video_control_header_4itf_t; + typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubType; - uint16_t bcdUVC; - uint16_t wTotalLength; - uint32_t dwClockFrequency; - uint8_t bInCollection; - uint8_t baInterfaceNr[]; -} tusb_desc_cs_video_ctl_itf_hdr_t; + uint8_t bTerminalID; + uint16_t wTerminalType; + uint8_t bAssocTerminal; + uint8_t iTerminal; +} tusb_desc_video_control_input_terminal_t; + +TU_VERIFY_STATIC(sizeof(tusb_desc_video_control_input_terminal_t) == 8, "size is not correct"); -/* 2.4.3.3 */ typedef struct TU_ATTR_PACKED { - uint8_t bHeaderLength; - union { - uint8_t bmHeaderInfo; - struct { - uint8_t FrameID: 1; - uint8_t EndOfFrame: 1; - uint8_t PresentationTime: 1; - uint8_t SourceClockReference: 1; - uint8_t PayloadSpecific: 1; - uint8_t StillImage: 1; - uint8_t Error: 1; - uint8_t EndOfHeader: 1; - }; - }; -} tusb_video_payload_header_t; + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bTerminalID; + uint16_t wTerminalType; + uint8_t bAssocTerminal; + uint8_t bSourceID; + uint8_t iTerminal; +} tusb_desc_video_control_output_terminal_t; + +TU_VERIFY_STATIC(sizeof(tusb_desc_video_control_output_terminal_t) == 9, "size is not correct"); + +typedef struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bTerminalID; + uint16_t wTerminalType; + uint8_t bAssocTerminal; + uint8_t iTerminal; + + uint16_t wObjectiveFocalLengthMin; + uint16_t wObjectiveFocalLengthMax; + uint16_t wOcularFocalLength; + uint8_t bControlSize; + uint8_t bmControls[3]; +} tusb_desc_video_control_camera_terminal_t; + +TU_VERIFY_STATIC(sizeof(tusb_desc_video_control_camera_terminal_t) == 18, "size is not correct"); + +//--------------------------------------------------------------------+ +// Video Streaming (VS) Descriptors +//--------------------------------------------------------------------+ /* 3.9.2.1 */ -typedef struct TU_ATTR_PACKED { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bDescriptorSubType; - uint8_t bNumFormats; - uint16_t wTotalLength; - uint8_t bEndpointAddress; - uint8_t bmInfo; - uint8_t bTerminalLink; - uint8_t bStillCaptureMethod; - uint8_t bTriggerSupport; - uint8_t bTriggerUsage; - uint8_t bControlSize; - uint8_t bmaControls[]; -} tusb_desc_cs_video_stm_itf_in_hdr_t; +#define tusb_desc_video_streaming_input_header_nbyte_t(_nb) \ + struct TU_ATTR_PACKED { \ + uint8_t bLength; \ + uint8_t bDescriptorType; \ + uint8_t bDescriptorSubType; \ + uint8_t bNumFormats; /* Number of video payload Format descriptors for this interface */ \ + uint16_t wTotalLength; \ + uint8_t bEndpointAddress; \ + uint8_t bmInfo; /* Bit 0: dynamic format change supported */ \ + uint8_t bTerminalLink; \ + uint8_t bStillCaptureMethod; \ + uint8_t bTriggerSupport; /* Hardware trigger supported */ \ + uint8_t bTriggerUsage; \ + uint8_t bControlSize; /* sizeof of each control item */ \ + uint8_t bmaControls[_nb]; \ + } + +typedef tusb_desc_video_streaming_input_header_nbyte_t() tusb_desc_video_streaming_input_header_t; +typedef tusb_desc_video_streaming_input_header_nbyte_t(1) tusb_desc_video_streaming_input_header_1byte_t; +typedef tusb_desc_video_streaming_input_header_nbyte_t(2) tusb_desc_video_streaming_input_header_2byte_t; +typedef tusb_desc_video_streaming_input_header_nbyte_t(3) tusb_desc_video_streaming_input_header_3byte_t; +typedef tusb_desc_video_streaming_input_header_nbyte_t(4) tusb_desc_video_streaming_input_header_4byte_t; /* 3.9.2.2 */ typedef struct TU_ATTR_PACKED { @@ -259,7 +307,7 @@ typedef struct TU_ATTR_PACKED { uint8_t bTerminalLink; uint8_t bControlSize; uint8_t bmaControls[]; -} tusb_desc_cs_video_stm_itf_out_hdr_t; +} tusb_desc_video_streaming_output_header_t; typedef struct TU_ATTR_PACKED { uint8_t bLength; @@ -285,14 +333,33 @@ typedef struct TU_ATTR_PACKED { uint8_t bmaControls[]; } output; }; -} tusb_desc_cs_video_stm_itf_hdr_t; +} tusb_desc_video_streaming_inout_header_t; +// 3.9.2.6 Color Matching Descriptor +typedef struct TU_ATTR_PACKED { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bColorPrimaries; + uint8_t bTransferCharacteristics; + uint8_t bMatrixCoefficients; +} tusb_desc_video_streaming_color_matching_t; + +TU_VERIFY_STATIC(sizeof(tusb_desc_video_streaming_color_matching_t) == 6, "size is not correct"); + +//--------------------------------------------------------------------+ +// Format and Frame Descriptor +// Note: bFormatIndex & bFrameIndex are 1-based index +//--------------------------------------------------------------------+ + +//------------- Uncompressed -------------// +// Uncompressed payload specs: 3.1.1 format descriptor typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubType; uint8_t bFormatIndex; - uint8_t bNumFrameDescriptors; + uint8_t bNumFrameDescriptors; // Number of frame descriptors for this format uint8_t guidFormat[16]; uint8_t bBitsPerPixel; uint8_t bDefaultFrameIndex; @@ -300,22 +367,69 @@ typedef struct TU_ATTR_PACKED { uint8_t bAspectRatioY; uint8_t bmInterlaceFlags; uint8_t bCopyProtect; -} tusb_desc_cs_video_fmt_uncompressed_t; +} tusb_desc_video_format_uncompressed_t; +TU_VERIFY_STATIC(sizeof(tusb_desc_video_format_uncompressed_t) == 27, "size is not correct"); + +// Uncompressed payload specs: 3.1.2 frame descriptor +#define tusb_desc_video_frame_uncompressed_nint_t(_nint) \ + struct TU_ATTR_PACKED { \ + uint8_t bLength; \ + uint8_t bDescriptorType; \ + uint8_t bDescriptorSubType; \ + uint8_t bFrameIndex; \ + uint8_t bmCapabilities; \ + uint16_t wWidth; \ + uint16_t wHeight; \ + uint32_t dwMinBitRate; \ + uint32_t dwMaxBitRate; \ + uint32_t dwMaxVideoFrameBufferSize; /* deprecated in 1.5 */ \ + uint32_t dwDefaultFrameInterval; /* 100ns unit */\ + uint8_t bFrameIntervalType; \ + uint32_t dwFrameInterval[_nint]; \ + } + +typedef tusb_desc_video_frame_uncompressed_nint_t() tusb_desc_video_frame_uncompressed_t; +typedef tusb_desc_video_frame_uncompressed_nint_t(1) tusb_desc_video_frame_uncompressed_1int_t; +typedef tusb_desc_video_frame_uncompressed_nint_t(2) tusb_desc_video_frame_uncompressed_2int_t; +typedef tusb_desc_video_frame_uncompressed_nint_t(3) tusb_desc_video_frame_uncompressed_3int_t; +typedef tusb_desc_video_frame_uncompressed_nint_t(4) tusb_desc_video_frame_uncompressed_4int_t; + +// continuous = 3 intervals: min, max, step +typedef tusb_desc_video_frame_uncompressed_3int_t tusb_desc_video_frame_uncompressed_continuous_t; + +TU_VERIFY_STATIC(sizeof(tusb_desc_video_frame_uncompressed_continuous_t) == 38, "size is not correct"); + +//------------- MJPEG -------------// +// MJPEG payload specs: 3.1.1 format descriptor typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubType; uint8_t bFormatIndex; uint8_t bNumFrameDescriptors; - uint8_t bmFlags; + uint8_t bmFlags; // Bit 0: fixed size samples (1 = yes) uint8_t bDefaultFrameIndex; uint8_t bAspectRatioX; uint8_t bAspectRatioY; uint8_t bmInterlaceFlags; uint8_t bCopyProtect; -} tusb_desc_cs_video_fmt_mjpeg_t; +} tusb_desc_video_format_mjpeg_t; +TU_VERIFY_STATIC(sizeof(tusb_desc_video_format_mjpeg_t) == 11, "size is not correct"); + +// MJPEG payload specs: 3.1.2 frame descriptor (same as uncompressed) +typedef tusb_desc_video_frame_uncompressed_t tusb_desc_video_frame_mjpeg_t; +typedef tusb_desc_video_frame_uncompressed_1int_t tusb_desc_video_frame_mjpeg_1int_t; +typedef tusb_desc_video_frame_uncompressed_2int_t tusb_desc_video_frame_mjpeg_2int_t; +typedef tusb_desc_video_frame_uncompressed_3int_t tusb_desc_video_frame_mjpeg_3int_t; +typedef tusb_desc_video_frame_uncompressed_4int_t tusb_desc_video_frame_mjpeg_4int_t; + +// continuous = 3 intervals: min, max, step +typedef tusb_desc_video_frame_mjpeg_3int_t tusb_desc_video_frame_mjpeg_continuous_t; + +//------------- DV -------------// +// DV payload specs: 3.1.1 typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; @@ -323,8 +437,9 @@ typedef struct TU_ATTR_PACKED { uint8_t bFormatIndex; uint32_t dwMaxVideoFrameBufferSize; /* deprecated */ uint8_t bFormatType; -} tusb_desc_cs_video_fmt_dv_t; +} tusb_desc_video_format_dv_t; +// Frame Based payload specs: 3.1.1 typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; @@ -339,25 +454,7 @@ typedef struct TU_ATTR_PACKED { uint8_t bmInterlaceFlags; uint8_t bCopyProtect; uint8_t bVaribaleSize; -} tusb_desc_cs_video_fmt_frame_based_t; - -typedef struct TU_ATTR_PACKED { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bDescriptorSubType; - uint8_t bFrameIndex; - uint8_t bmCapabilities; - uint16_t wWidth; - uint16_t wHeight; - uint32_t dwMinBitRate; - uint32_t dwMaxBitRate; - uint32_t dwMaxVideoFrameBufferSize; /* deprecated */ - uint32_t dwDefaultFrameInterval; - uint8_t bFrameIntervalType; - uint32_t dwFrameInterval[]; -} tusb_desc_cs_video_frm_uncompressed_t; - -typedef tusb_desc_cs_video_frm_uncompressed_t tusb_desc_cs_video_frm_mjpeg_t; +} tusb_desc_video_format_framebased_t; typedef struct TU_ATTR_PACKED { uint8_t bLength; @@ -373,12 +470,30 @@ typedef struct TU_ATTR_PACKED { uint8_t bFrameIntervalType; uint32_t dwBytesPerLine; uint32_t dwFrameInterval[]; -} tusb_desc_cs_video_frm_frame_based_t; +} tusb_desc_video_frame_framebased_t; //--------------------------------------------------------------------+ // Requests //--------------------------------------------------------------------+ +/* 2.4.3.3 */ +typedef struct TU_ATTR_PACKED { + uint8_t bHeaderLength; + union { + uint8_t bmHeaderInfo; + struct { + uint8_t FrameID: 1; + uint8_t EndOfFrame: 1; + uint8_t PresentationTime: 1; + uint8_t SourceClockReference: 1; + uint8_t PayloadSpecific: 1; + uint8_t StillImage: 1; + uint8_t Error: 1; + uint8_t EndOfHeader: 1; + }; + }; +} tusb_video_payload_header_t; + /* 4.3.1.1 */ typedef struct TU_ATTR_PACKED { union { @@ -537,7 +652,7 @@ TU_VERIFY_STATIC( sizeof(video_probe_and_commit_control_t) == 48, "size is not c /* Motion-JPEG 3.1.1 Table 3-2 and 3-4 */ #define TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_DISC(_frmidx, _cap, _width, _height, _minbr, _maxbr, _maxfrmbufsz, _frminterval, ...) \ TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_DISC_LEN + (TU_ARGS_NUM(__VA_ARGS__)) * 4, \ - TUSB_DESC_CS_INTERFACE, VIDEO_CS_VS_INTERFACE_FRAME_MJPEG, \ + TUSB_DESC_CS_INTERFACE, VIDEO_CS_ITF_VS_FRAME_MJPEG, \ _frmidx, _cap, U16_TO_U8S_LE(_width), U16_TO_U8S_LE(_height), U32_TO_U8S_LE(_minbr), U32_TO_U8S_LE(_maxbr), \ U32_TO_U8S_LE(_maxfrmbufsz), U32_TO_U8S_LE(_frminterval), (TU_ARGS_NUM(__VA_ARGS__)), __VA_ARGS__ diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 3b29454a3..4218835aa 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -50,17 +50,17 @@ typedef struct { tusb_desc_interface_t std; - tusb_desc_cs_video_ctl_itf_hdr_t ctl; + tusb_desc_video_control_header_t ctl; } tusb_desc_vc_itf_t; typedef struct { tusb_desc_interface_t std; - tusb_desc_cs_video_stm_itf_hdr_t stm; + tusb_desc_video_streaming_inout_header_t stm; } tusb_desc_vs_itf_t; typedef union { - tusb_desc_cs_video_ctl_itf_hdr_t ctl; - tusb_desc_cs_video_stm_itf_hdr_t stm; + tusb_desc_video_control_header_t ctl; + tusb_desc_video_streaming_inout_header_t stm; } tusb_desc_video_itf_hdr_t; typedef struct TU_ATTR_PACKED { @@ -78,9 +78,9 @@ typedef union { uint8_t bFormatIndex; uint8_t bNumFrameDescriptors; }; - tusb_desc_cs_video_fmt_uncompressed_t uncompressed; - tusb_desc_cs_video_fmt_mjpeg_t mjpeg; - tusb_desc_cs_video_fmt_frame_based_t frame_based; + tusb_desc_video_format_uncompressed_t uncompressed; + tusb_desc_video_format_mjpeg_t mjpeg; + tusb_desc_video_format_framebased_t frame_based; } tusb_desc_cs_video_fmt_t; typedef union { @@ -93,9 +93,9 @@ typedef union { uint16_t wWidth; uint16_t wHeight; }; - tusb_desc_cs_video_frm_uncompressed_t uncompressed; - tusb_desc_cs_video_frm_mjpeg_t mjpeg; - tusb_desc_cs_video_frm_frame_based_t frame_based; + tusb_desc_video_frame_uncompressed_t uncompressed; + tusb_desc_video_frame_mjpeg_t mjpeg; + tusb_desc_video_frame_framebased_t frame_based; } tusb_desc_cs_video_frm_t; /* video streaming interface */ @@ -114,6 +114,8 @@ typedef struct TU_ATTR_PACKED { uint32_t max_payload_transfer_size; uint8_t error_code;/* error code */ uint8_t state; /* 0:probing 1:committed 2:streaming */ + + video_probe_and_commit_control_t probe_commit_payload; /* Probe and Commit control */ /*------------- From this point, data is not cleared by bus reset -------------*/ CFG_TUSB_MEM_ALIGN uint8_t ep_buf[CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE]; /* EP transfer buffer for streaming */ } videod_streaming_interface_t; @@ -143,13 +145,65 @@ CFG_TUD_MEM_SECTION tu_static videod_streaming_interface_t _videod_streaming_itf 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 */ +//--------------------------------------------------------------------+ +// Debug +//--------------------------------------------------------------------+ +#if CFG_TUSB_DEBUG >= CFG_TUD_VIDEO_LOG_LEVEL + +static tu_lookup_entry_t const tu_lookup_video_request[] = { + {.key = VIDEO_REQUEST_UNDEFINED, .data = "Undefined"}, + {.key = VIDEO_REQUEST_SET_CUR, .data = "SetCur"}, + {.key = VIDEO_REQUEST_SET_CUR_ALL, .data = "SetCurAll"}, + {.key = VIDEO_REQUEST_GET_CUR, .data = "GetCur"}, + {.key = VIDEO_REQUEST_GET_MIN, .data = "GetMin"}, + {.key = VIDEO_REQUEST_GET_MAX, .data = "GetMax"}, + {.key = VIDEO_REQUEST_GET_RES, .data = "GetRes"}, + {.key = VIDEO_REQUEST_GET_LEN, .data = "GetLen"}, + {.key = VIDEO_REQUEST_GET_INFO, .data = "GetInfo"}, + {.key = VIDEO_REQUEST_GET_DEF, .data = "GetDef"}, + {.key = VIDEO_REQUEST_GET_CUR_ALL, .data = "GetCurAll"}, + {.key = VIDEO_REQUEST_GET_MIN_ALL, .data = "GetMinAll"}, + {.key = VIDEO_REQUEST_GET_MAX_ALL, .data = "GetMaxAll"}, + {.key = VIDEO_REQUEST_GET_RES_ALL, .data = "GetResAll"}, + {.key = VIDEO_REQUEST_GET_DEF_ALL, .data = "GetDefAll"}, +}; + +static tu_lookup_table_t const tu_table_video_request = { + .count = TU_ARRAY_SIZE(tu_lookup_video_request), + .items = tu_lookup_video_request +}; + +static char const* const tu_str_video_vc_control_selector[] = { + "Undefined", + "Video Power Mode", + "Request Error Code", +}; + +static char const* const tu_str_video_vs_control_selector[] = { + "Undefined", + "Probe", + "Commit", + "Still Probe", + "Still Commit", + "Still Image Trigger", + "Stream Error Code", + "Generate Key Frame", + "Update Frame Segment", + "Sync Delay", +}; + +#endif + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ + /** Get interface number from the interface descriptor * * @param[in] desc interface descriptor * * @return bInterfaceNumber */ -static inline uint8_t _desc_itfnum(void const *desc) -{ +static inline uint8_t _desc_itfnum(void const *desc) { return ((uint8_t const*)desc)[2]; } @@ -158,8 +212,7 @@ static inline uint8_t _desc_itfnum(void const *desc) * @param[in] desc endpoint descriptor * * @return bEndpointAddress */ -static inline uint8_t _desc_ep_addr(void const *desc) -{ +static inline uint8_t _desc_ep_addr(void const *desc) { return ((uint8_t const*)desc)[2]; } @@ -169,8 +222,7 @@ static inline uint8_t _desc_ep_addr(void const *desc) * @param[in] stm_idx index number of streaming interface * * @return instance */ -static videod_streaming_interface_t* _get_instance_streaming(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) -{ +static videod_streaming_interface_t* _get_instance_streaming(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) { videod_interface_t *ctl = &_videod_itf[ctl_idx]; if (!ctl->beg) return NULL; videod_streaming_interface_t *stm = &_videod_streaming_itf[ctl->stm[stm_idx]]; @@ -178,13 +230,11 @@ static videod_streaming_interface_t* _get_instance_streaming(uint_fast8_t ctl_id return stm; } -static tusb_desc_vc_itf_t const* _get_desc_vc(videod_interface_t const *self) -{ +static tusb_desc_vc_itf_t const* _get_desc_vc(videod_interface_t const *self) { return (tusb_desc_vc_itf_t const *)(self->beg + self->cur); } -static tusb_desc_vs_itf_t const* _get_desc_vs(videod_streaming_interface_t const *self) -{ +static tusb_desc_vs_itf_t const* _get_desc_vs(videod_streaming_interface_t const *self) { if (!self->desc.cur) return NULL; uint8_t const *desc = _videod_itf[self->index_vc].beg; return (tusb_desc_vs_itf_t const*)(desc + self->desc.cur); @@ -198,8 +248,7 @@ static tusb_desc_vs_itf_t const* _get_desc_vs(videod_streaming_interface_t const * * @return The pointer for interface descriptor. * @retval end did not found interface descriptor */ -static void const* _find_desc(void const *beg, void const *end, uint_fast8_t desc_type) -{ +static void const* _find_desc(void const *beg, void const *end, uint_fast8_t desc_type) { void const *cur = beg; while ((cur < end) && (desc_type != tu_desc_type(cur))) { cur = tu_desc_next(cur); @@ -207,6 +256,24 @@ static void const* _find_desc(void const *beg, void const *end, uint_fast8_t des return cur; } +/** Find the first descriptor of two given types + * + * @param[in] beg The head of descriptor byte array. + * @param[in] end The tail of descriptor byte array. + * @param[in] desc_type_0 The first target descriptor type. + * @param[in] desc_type_1 The second target descriptor type. + * + * @return The pointer for interface descriptor. + * @retval end did not found interface descriptor */ +static void const* _find_desc_2_type(void const *beg, void const *end, uint_fast8_t desc_type_0, uint_fast8_t desc_type_1) +{ + void const *cur = beg; + while ((cur < end) && (desc_type_0 != tu_desc_type(cur)) && (desc_type_1 != tu_desc_type(cur))) { + cur = tu_desc_next(cur); + } + return cur; +} + /** Find the first descriptor specified by the arguments * * @param[in] beg The head of descriptor byte array. @@ -220,8 +287,7 @@ static void const* _find_desc(void const *beg, void const *end, uint_fast8_t des static void const* _find_desc_3(void const *beg, void const *end, uint_fast8_t desc_type, uint_fast8_t element_0, - uint_fast8_t element_1) -{ + uint_fast8_t element_1) { for (void const *cur = beg; cur < end; cur = _find_desc(cur, end, desc_type)) { uint8_t const *p = (uint8_t const *)cur; if ((p[2] == element_0) && (p[3] == element_1)) { @@ -233,19 +299,22 @@ static void const* _find_desc_3(void const *beg, void const *end, } /** Return the next interface descriptor which has another interface number. + * If there are multiple VC interfaces, there will be an IAD descriptor before + * the next interface descriptor. Check both the IAD descriptor and the interface + * descriptor. + * 3.1 Descriptor Layout Overview * * @param[in] beg The head of descriptor byte array. * @param[in] end The tail of descriptor byte array. * * @return The pointer for interface descriptor. * @retval end did not found interface descriptor */ -static void const* _next_desc_itf(void const *beg, void const *end) -{ +static void const* _next_desc_itf(void const *beg, void const *end) { void const *cur = beg; uint_fast8_t itfnum = ((tusb_desc_interface_t const*)cur)->bInterfaceNumber; while ((cur < end) && (itfnum == ((tusb_desc_interface_t const*)cur)->bInterfaceNumber)) { - cur = _find_desc(tu_desc_next(cur), end, TUSB_DESC_INTERFACE); + cur = _find_desc_2_type(tu_desc_next(cur), end, TUSB_DESC_INTERFACE, TUSB_DESC_INTERFACE_ASSOCIATION); } return cur; } @@ -391,8 +460,10 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm case VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED: param->wCompQuality = 1; /* 1 to 10000 */ break; - case VIDEO_CS_ITF_VS_FORMAT_MJPEG: + + case VIDEO_CS_ITF_VS_FORMAT_MJPEG: break; + default: return false; } @@ -413,9 +484,11 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm case VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED: frame_size = (uint_fast32_t)frm->wWidth * frm->wHeight * fmt->uncompressed.bBitsPerPixel / 8; break; + case VIDEO_CS_ITF_VS_FORMAT_MJPEG: frame_size = (uint_fast32_t)frm->wWidth * frm->wHeight * 16 / 8; /* YUV422 */ break; + default: break; } param->dwMaxVideoFrameSize = frame_size; @@ -434,8 +507,9 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm uint_fast32_t interval_ms = interval / 10000; TU_ASSERT(interval_ms); uint_fast32_t payload_size = (frame_size + interval_ms - 1) / interval_ms + 2; - if (CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE < payload_size) + if (CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE < payload_size) { payload_size = CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE; + } param->dwMaxPayloadTransferSize = payload_size; return true; } @@ -455,10 +529,12 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * if (_get_desc_vs(stm)) param->bFormatIndex = _get_desc_vs(stm)->stm.bNumFormats; break; + case VIDEO_REQUEST_GET_MIN: case VIDEO_REQUEST_GET_DEF: param->bFormatIndex = 1; break; + default: return false; } /* Set the parameters determined by the format */ @@ -487,18 +563,22 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * case VIDEO_REQUEST_GET_MAX: frmnum = fmt->bNumFrameDescriptors; break; + case VIDEO_REQUEST_GET_MIN: frmnum = 1; break; + case VIDEO_REQUEST_GET_DEF: switch (fmt->bDescriptorSubType) { - case VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED: - frmnum = fmt->uncompressed.bDefaultFrameIndex; - break; - case VIDEO_CS_ITF_VS_FORMAT_MJPEG: - frmnum = fmt->mjpeg.bDefaultFrameIndex; - break; - default: return false; + case VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED: + frmnum = fmt->uncompressed.bDefaultFrameIndex; + break; + + case VIDEO_CS_ITF_VS_FORMAT_MJPEG: + frmnum = fmt->mjpeg.bDefaultFrameIndex; + break; + + default: return false; } break; default: return false; @@ -511,9 +591,11 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * case VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED: frame_size = (uint_fast32_t)frm->wWidth * frm->wHeight * fmt->uncompressed.bBitsPerPixel / 8; break; + case VIDEO_CS_ITF_VS_FORMAT_MJPEG: frame_size = (uint_fast32_t)frm->wWidth * frm->wHeight * 16 / 8; /* YUV422 */ break; + default: return false; } param->dwMaxVideoFrameSize = frame_size; @@ -529,41 +611,43 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * uint_fast32_t interval, interval_ms; switch (request) { - case VIDEO_REQUEST_GET_MAX: - { - uint_fast32_t min_interval, max_interval; - uint_fast8_t num_intervals = frm->uncompressed.bFrameIntervalType; - max_interval = num_intervals ? frm->uncompressed.dwFrameInterval[num_intervals - 1]: frm->uncompressed.dwFrameInterval[1]; - min_interval = frm->uncompressed.dwFrameInterval[0]; - interval = max_interval; - interval_ms = min_interval / 10000; - } + case VIDEO_REQUEST_GET_MAX: { + uint_fast32_t min_interval, max_interval; + uint_fast8_t num_intervals = frm->uncompressed.bFrameIntervalType; + max_interval = num_intervals ? frm->uncompressed.dwFrameInterval[num_intervals - 1]: frm->uncompressed.dwFrameInterval[1]; + min_interval = frm->uncompressed.dwFrameInterval[0]; + interval = max_interval; + interval_ms = min_interval / 10000; break; - case VIDEO_REQUEST_GET_MIN: - { - uint_fast32_t min_interval, max_interval; - uint_fast8_t num_intervals = frm->uncompressed.bFrameIntervalType; - max_interval = num_intervals ? frm->uncompressed.dwFrameInterval[num_intervals - 1]: frm->uncompressed.dwFrameInterval[1]; - min_interval = frm->uncompressed.dwFrameInterval[0]; - interval = min_interval; - interval_ms = max_interval / 10000; - } + } + + case VIDEO_REQUEST_GET_MIN: { + uint_fast32_t min_interval, max_interval; + uint_fast8_t num_intervals = frm->uncompressed.bFrameIntervalType; + max_interval = num_intervals ? frm->uncompressed.dwFrameInterval[num_intervals - 1]: frm->uncompressed.dwFrameInterval[1]; + min_interval = frm->uncompressed.dwFrameInterval[0]; + interval = min_interval; + interval_ms = max_interval / 10000; break; + } + case VIDEO_REQUEST_GET_DEF: interval = frm->uncompressed.dwDefaultFrameInterval; interval_ms = interval / 10000; break; - case VIDEO_REQUEST_GET_RES: - { - uint_fast8_t num_intervals = frm->uncompressed.bFrameIntervalType; - if (num_intervals) { - interval = 0; - } else { - interval = frm->uncompressed.dwFrameInterval[2]; - interval_ms = interval / 10000; - } + + case VIDEO_REQUEST_GET_RES: { + uint_fast8_t num_intervals = frm->uncompressed.bFrameIntervalType; + if (num_intervals) { + interval = 0; + interval_ms = 0; + } else { + interval = frm->uncompressed.dwFrameInterval[2]; + interval_ms = interval / 10000; } break; + } + default: return false; } param->dwFrameInterval = interval; @@ -577,8 +661,9 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * } else { payload_size = (frame_size + interval_ms - 1) / interval_ms + 2; } - if (CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE < payload_size) + if (CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE < payload_size) { payload_size = CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE; + } param->dwMaxPayloadTransferSize = payload_size; } return true; @@ -651,13 +736,11 @@ static bool _open_vc_itf(uint8_t rhport, videod_interface_t *self, uint_fast8_t return true; } -static bool _init_vs_configuration(videod_streaming_interface_t *stm) -{ +static bool _init_vs_configuration(videod_streaming_interface_t *stm) { /* initialize streaming settings */ stm->state = VS_STATE_PROBING; stm->max_payload_transfer_size = 0; - video_probe_and_commit_control_t *param = - (video_probe_and_commit_control_t *)&stm->ep_buf; + video_probe_and_commit_control_t *param = &stm->probe_commit_payload; tu_memclr(param, sizeof(*param)); return _update_streaming_parameters(stm, param); } @@ -672,15 +755,20 @@ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint TU_LOG_DRV(" reopen VS %d\r\n", altnum); uint8_t const *desc = _videod_itf[stm->index_vc].beg; +#ifndef TUP_DCD_EDPT_ISO_ALLOC /* Close endpoints of previous settings. */ for (i = 0; i < TU_ARRAY_SIZE(stm->desc.ep); ++i) { uint_fast16_t ofs_ep = stm->desc.ep[i]; if (!ofs_ep) break; - uint8_t ep_adr = _desc_ep_addr(desc + ofs_ep); - usbd_edpt_close(rhport, ep_adr); - stm->desc.ep[i] = 0; - TU_LOG_DRV(" close EP%02x\r\n", ep_adr); + tusb_desc_endpoint_t const *ep = (tusb_desc_endpoint_t const*)(desc + ofs_ep); + /* Only ISO endpoints needs to be closed */ + if(ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) { + stm->desc.ep[i] = 0; + usbd_edpt_close(rhport, ep->bEndpointAddress); + TU_LOG_DRV(" close EP%02x\r\n", ep->bEndpointAddress); + } } +#endif /* clear transfer management information */ stm->buffer = NULL; @@ -705,16 +793,18 @@ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint TU_ASSERT(cur < end); tusb_desc_endpoint_t const *ep = (tusb_desc_endpoint_t const*)cur; uint_fast32_t max_size = stm->max_payload_transfer_size; - if (altnum) { - if ((TUSB_XFER_ISOCHRONOUS == ep->bmAttributes.xfer) && - (tu_edpt_packet_size(ep) < max_size)) { - /* FS must be less than or equal to max packet size */ - return false; - } + if (altnum && (TUSB_XFER_ISOCHRONOUS == ep->bmAttributes.xfer)) { + /* FS must be less than or equal to max packet size */ + TU_VERIFY (tu_edpt_packet_size(ep) >= max_size); +#ifdef TUP_DCD_EDPT_ISO_ALLOC + usbd_edpt_iso_activate(rhport, ep); +#else + TU_ASSERT(usbd_edpt_open(rhport, ep)); +#endif } else { TU_VERIFY(TUSB_XFER_BULK == ep->bmAttributes.xfer); + TU_ASSERT(usbd_edpt_open(rhport, ep)); } - TU_ASSERT(usbd_edpt_open(rhport, ep)); stm->desc.ep[i] = (uint16_t) (cur - desc); TU_LOG_DRV(" open EP%02x\r\n", _desc_ep_addr(cur)); } @@ -734,6 +824,7 @@ static uint_fast16_t _prepare_in_payload(videod_streaming_interface_t *stm) if (hdr_len + remaining < pkt_len) { pkt_len = hdr_len + remaining; } + TU_ASSERT(pkt_len >= hdr_len); uint_fast16_t data_len = pkt_len - hdr_len; memcpy(&stm->ep_buf[hdr_len], stm->buffer + stm->offset, data_len); stm->offset += data_len; @@ -750,6 +841,7 @@ static int handle_video_ctl_std_req(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request, uint_fast8_t ctl_idx) { + TU_LOG_DRV("\r\n"); switch (request->bRequest) { case TUSB_REQ_GET_INTERFACE: if (stage == CONTROL_STAGE_SETUP) @@ -787,7 +879,10 @@ static int handle_video_ctl_cs_req(uint8_t rhport, uint8_t stage, videod_interface_t *self = &_videod_itf[ctl_idx]; /* 4.2.1 Interface Control Request */ - switch (TU_U16_HIGH(request->wValue)) { + uint8_t const ctrl_sel = TU_U16_HIGH(request->wValue); + TU_LOG_DRV("%s_Control(%s)\r\n", tu_str_video_vc_control_selector[ctrl_sel], tu_lookup_find(&tu_table_video_request, request->bRequest)); + + switch (ctrl_sel) { case VIDEO_VC_CTL_VIDEO_POWER_MODE: switch (request->bRequest) { case VIDEO_REQUEST_SET_CUR: @@ -851,19 +946,19 @@ static int handle_video_ctl_req(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request, uint_fast8_t ctl_idx) { - uint_fast8_t entity_id; switch (request->bmRequestType_bit.type) { case TUSB_REQ_TYPE_STANDARD: return handle_video_ctl_std_req(rhport, stage, request, ctl_idx); - case TUSB_REQ_TYPE_CLASS: - entity_id = TU_U16_HIGH(request->wIndex); + case TUSB_REQ_TYPE_CLASS: { + uint_fast8_t entity_id = TU_U16_HIGH(request->wIndex); if (!entity_id) { return handle_video_ctl_cs_req(rhport, stage, request, ctl_idx); } else { TU_VERIFY(_find_desc_entity(_get_desc_vc(&_videod_itf[ctl_idx]), entity_id), VIDEO_ERROR_INVALID_REQUEST); return VIDEO_ERROR_NONE; } + } default: return VIDEO_ERROR_INVALID_REQUEST; @@ -874,6 +969,7 @@ static int handle_video_stm_std_req(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request, uint_fast8_t stm_idx) { + TU_LOG_DRV("\r\n"); videod_streaming_interface_t *self = &_videod_streaming_itf[stm_idx]; switch (request->bRequest) { case TUSB_REQ_GET_INTERFACE: @@ -889,8 +985,7 @@ static int handle_video_stm_std_req(uint8_t rhport, uint8_t stage, return VIDEO_ERROR_NONE; case TUSB_REQ_SET_INTERFACE: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(_open_vs_itf(rhport, self, request->wValue), VIDEO_ERROR_UNKNOWN); tud_control_status(rhport, request); } @@ -904,26 +999,26 @@ static int handle_video_stm_std_req(uint8_t rhport, uint8_t stage, static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request, - uint_fast8_t stm_idx) -{ + uint_fast8_t stm_idx) { (void)rhport; videod_streaming_interface_t *self = &_videod_streaming_itf[stm_idx]; + uint8_t const ctrl_sel = TU_U16_HIGH(request->wValue); + TU_LOG_DRV("%s_Control(%s)\r\n", tu_str_video_vs_control_selector[ctrl_sel], tu_lookup_find(&tu_table_video_request, request->bRequest)); + /* 4.2.1 Interface Control Request */ - switch (TU_U16_HIGH(request->wValue)) { + switch (ctrl_sel) { case VIDEO_VS_CTL_STREAM_ERROR_CODE: switch (request->bRequest) { case VIDEO_REQUEST_GET_CUR: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { /* TODO */ TU_VERIFY(tud_control_xfer(rhport, request, &self->error_code, sizeof(uint8_t)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; case VIDEO_REQUEST_GET_INFO: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)(uintptr_t) &_cap_get, sizeof(_cap_get)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; @@ -935,25 +1030,23 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, case VIDEO_VS_CTL_PROBE: if (self->state != VS_STATE_PROBING) { self->state = VS_STATE_PROBING; - _init_vs_configuration(self); } + switch (request->bRequest) { case VIDEO_REQUEST_SET_CUR: if (stage == CONTROL_STAGE_SETUP) { - TU_VERIFY(sizeof(video_probe_and_commit_control_t) >= request->wLength, VIDEO_ERROR_UNKNOWN); - TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), + TU_VERIFY(tud_control_xfer(rhport, request, &self->probe_commit_payload, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); } else if (stage == CONTROL_STAGE_DATA) { - TU_VERIFY(_update_streaming_parameters(self, (video_probe_and_commit_control_t*)self->ep_buf), + TU_VERIFY(_update_streaming_parameters(self, &self->probe_commit_payload), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE); } return VIDEO_ERROR_NONE; case VIDEO_REQUEST_GET_CUR: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(request->wLength, VIDEO_ERROR_UNKNOWN); - TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); + TU_VERIFY(tud_control_xfer(rhport, request, &self->probe_commit_payload, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; @@ -961,19 +1054,16 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, case VIDEO_REQUEST_GET_MAX: case VIDEO_REQUEST_GET_RES: case VIDEO_REQUEST_GET_DEF: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(request->wLength, VIDEO_ERROR_UNKNOWN); - video_probe_and_commit_control_t tmp; - tmp = *(video_probe_and_commit_control_t*)&self->ep_buf; + video_probe_and_commit_control_t tmp = self->probe_commit_payload; TU_VERIFY(_negotiate_streaming_parameters(self, request->bRequest, &tmp), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE); TU_VERIFY(tud_control_xfer(rhport, request, &tmp, sizeof(tmp)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; case VIDEO_REQUEST_GET_LEN: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(2 == request->wLength, VIDEO_ERROR_UNKNOWN); uint16_t len = sizeof(video_probe_and_commit_control_t); TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)&len, sizeof(len)), VIDEO_ERROR_UNKNOWN); @@ -981,8 +1071,7 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, return VIDEO_ERROR_NONE; case VIDEO_REQUEST_GET_INFO: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(1 == request->wLength, VIDEO_ERROR_UNKNOWN); TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)(uintptr_t)&_cap_get_set, sizeof(_cap_get_set)), VIDEO_ERROR_UNKNOWN); } @@ -996,10 +1085,9 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, switch (request->bRequest) { case VIDEO_REQUEST_SET_CUR: if (stage == CONTROL_STAGE_SETUP) { - TU_VERIFY(sizeof(video_probe_and_commit_control_t) >= request->wLength, VIDEO_ERROR_UNKNOWN); - TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); + TU_VERIFY(tud_control_xfer(rhport, request, &self->probe_commit_payload, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); } else if (stage == CONTROL_STAGE_DATA) { - video_probe_and_commit_control_t *param = (video_probe_and_commit_control_t*)self->ep_buf; + video_probe_and_commit_control_t *param = &self->probe_commit_payload; TU_VERIFY(_update_streaming_parameters(self, param), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE); /* Set the negotiated value */ self->max_payload_transfer_size = param->dwMaxPayloadTransferSize; @@ -1021,16 +1109,14 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, return VIDEO_ERROR_NONE; case VIDEO_REQUEST_GET_CUR: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(request->wLength, VIDEO_ERROR_UNKNOWN); - TU_VERIFY(tud_control_xfer(rhport, request, self->ep_buf, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); + TU_VERIFY(tud_control_xfer(rhport, request, &self->probe_commit_payload, sizeof(video_probe_and_commit_control_t)), VIDEO_ERROR_UNKNOWN); } return VIDEO_ERROR_NONE; case VIDEO_REQUEST_GET_LEN: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(2 == request->wLength, VIDEO_ERROR_UNKNOWN); uint16_t len = sizeof(video_probe_and_commit_control_t); TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)&len, sizeof(len)), VIDEO_ERROR_UNKNOWN); @@ -1038,8 +1124,7 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage, return VIDEO_ERROR_NONE; case VIDEO_REQUEST_GET_INFO: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { TU_VERIFY(1 == request->wLength, VIDEO_ERROR_UNKNOWN); TU_VERIFY(tud_control_xfer(rhport, request, (uint8_t*)(uintptr_t) &_cap_get_set, sizeof(_cap_get_set)), VIDEO_ERROR_UNKNOWN); } @@ -1101,6 +1186,16 @@ bool tud_video_n_streaming(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) videod_streaming_interface_t *stm = _get_instance_streaming(ctl_idx, stm_idx); if (!stm || !stm->desc.ep[0]) return false; if (stm->state == VS_STATE_PROBING) return false; + +#ifdef TUP_DCD_EDPT_ISO_ALLOC + uint8_t const *desc = _videod_itf[stm->index_vc].beg; + uint_fast16_t ofs_ep = stm->desc.ep[0]; + tusb_desc_endpoint_t const *ep = (tusb_desc_endpoint_t const*)(desc + ofs_ep); + if (ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) { + if (stm->state == VS_STATE_COMMITTED) return false; + } +#endif + return true; } @@ -1140,8 +1235,7 @@ bool tud_video_n_frame_xfer(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, void *bu //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ -void videod_init(void) -{ +void videod_init(void) { for (uint_fast8_t i = 0; i < CFG_TUD_VIDEO; ++i) { videod_interface_t* ctl = &_videod_itf[i]; tu_memclr(ctl, sizeof(*ctl)); @@ -1152,8 +1246,11 @@ void videod_init(void) } } -void videod_reset(uint8_t rhport) -{ +bool videod_deinit(void) { + return true; +} + +void videod_reset(uint8_t rhport) { (void) rhport; for (uint_fast8_t i = 0; i < CFG_TUD_VIDEO; ++i) { videod_interface_t* ctl = &_videod_itf[i]; @@ -1165,8 +1262,7 @@ void videod_reset(uint8_t rhport) } } -uint16_t videod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) -{ +uint16_t videod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) { TU_VERIFY((TUSB_CLASS_VIDEO == itf_desc->bInterfaceClass) && (VIDEO_SUBCLASS_CONTROL == itf_desc->bInterfaceSubClass) && (VIDEO_ITF_PROTOCOL_15 == itf_desc->bInterfaceProtocol), 0); @@ -1208,12 +1304,30 @@ uint16_t videod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin cur = _next_desc_itf(cur, end); stm->desc.end = (uint16_t) ((uintptr_t)cur - (uintptr_t)itf_desc); stm->state = VS_STATE_PROBING; +#ifdef TUP_DCD_EDPT_ISO_ALLOC + /* Allocate ISO endpoints */ + uint16_t ep_size = 0; + uint16_t ep_addr = 0; + uint8_t const *p_desc = (uint8_t const*)itf_desc + stm->desc.beg; + uint8_t const *p_desc_end = (uint8_t const*)itf_desc + stm->desc.end; + while (p_desc < p_desc_end) { + if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) { + tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) p_desc; + if (desc_ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) { + ep_addr = desc_ep->bEndpointAddress; + ep_size = TU_MAX(tu_edpt_packet_size(desc_ep), ep_size); + } + } + p_desc = tu_desc_next(p_desc); + } + if(ep_addr > 0 && ep_size > 0) usbd_edpt_iso_alloc(rhport, ep_addr, ep_size); +#endif if (0 == stm_idx && 1 == bInCollection) { /* If there is only one streaming interface and no alternate settings, * host may not issue set_interface so open the streaming interface here. */ uint8_t const *sbeg = (uint8_t const*)itf_desc + stm->desc.beg; uint8_t const *send = (uint8_t const*)itf_desc + stm->desc.end; - if (end == _find_desc_itf(sbeg, send, _desc_itfnum(sbeg), 1)) { + if (send == _find_desc_itf(sbeg, send, _desc_itfnum(sbeg), 1)) { TU_VERIFY(_open_vs_itf(rhport, stm, 0), 0); } } @@ -1225,8 +1339,7 @@ uint16_t videod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) -bool videod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) -{ +bool videod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) { int err; TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE); uint_fast8_t itfnum = tu_u16_low(request->wIndex); @@ -1239,6 +1352,7 @@ bool videod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_ } if (itf < CFG_TUD_VIDEO) { + TU_LOG_DRV(" VC[%d]: ", itf); err = handle_video_ctl_req(rhport, stage, request, itf); _videod_itf[itf].error_code = (uint8_t)err; if (err) return false; @@ -1254,6 +1368,7 @@ bool videod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_ } if (itf < CFG_TUD_VIDEO_STREAMING) { + TU_LOG_DRV(" VS[%d]: ", itf); err = handle_video_stm_req(rhport, stage, request, itf); _videod_streaming_itf[itf].error_code = (uint8_t)err; if (err) return false; @@ -1262,8 +1377,7 @@ bool videod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_ return false; } -bool videod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) -{ +bool videod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void)result; (void)xferred_bytes; /* find streaming handle */ diff --git a/src/class/video/video_device.h b/src/class/video/video_device.h index ee2fcb9d5..92930c013 100644 --- a/src/class/video/video_device.h +++ b/src/class/video/video_device.h @@ -85,6 +85,7 @@ TU_ATTR_WEAK int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, // INTERNAL USBD-CLASS DRIVER API //--------------------------------------------------------------------+ void videod_init (void); +bool videod_deinit (void); void videod_reset (uint8_t rhport); uint16_t videod_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool videod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 25f85e501..0d4082c03 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -37,6 +37,7 @@ #define TU_ARRAY_SIZE(_arr) ( sizeof(_arr) / sizeof(_arr[0]) ) #define TU_MIN(_x, _y) ( ( (_x) < (_y) ) ? (_x) : (_y) ) #define TU_MAX(_x, _y) ( ( (_x) > (_y) ) ? (_x) : (_y) ) +#define TU_DIV_CEIL(n, d) (((n) + (d) - 1) / (d)) #define TU_U16(_high, _low) ((uint16_t) (((_high) << 8) | (_low))) #define TU_U16_HIGH(_u16) ((uint8_t) (((_u16) >> 8) & 0x00ff)) @@ -64,6 +65,7 @@ // Standard Headers #include #include +#include #include #include #include @@ -75,8 +77,6 @@ #include "tusb_types.h" #include "tusb_debug.h" -#include "tusb_timeout.h" // TODO remove - //--------------------------------------------------------------------+ // Optional API implemented by application if needed // TODO move to a more ovious place/file @@ -122,13 +122,11 @@ TU_ATTR_ALWAYS_INLINE static inline int tu_memcpy_s(void *dest, size_t destsz, c //------------- Bytes -------------// -TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_u32(uint8_t b3, uint8_t b2, uint8_t b1, uint8_t b0) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_u32(uint8_t b3, uint8_t b2, uint8_t b1, uint8_t b0) { return ( ((uint32_t) b3) << 24) | ( ((uint32_t) b2) << 16) | ( ((uint32_t) b1) << 8) | b0; } -TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_u16(uint8_t high, uint8_t low) -{ +TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_u16(uint8_t high, uint8_t low) { return (uint16_t) ((((uint16_t) high) << 8) | low); } @@ -159,11 +157,12 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_max16 (uint16_t x, uint16_t y) { TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_max32 (uint32_t x, uint32_t y) { return (x > y) ? x : y; } //------------- Align -------------// -TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align(uint32_t value, uint32_t alignment) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align(uint32_t value, uint32_t alignment) { return value & ((uint32_t) ~(alignment-1)); } +TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align4 (uint32_t value) { return (value & 0xFFFFFFFCUL); } +TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align8 (uint32_t value) { return (value & 0xFFFFFFF8UL); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align16 (uint32_t value) { return (value & 0xFFFFFFF0UL); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align32 (uint32_t value) { return (value & 0xFFFFFFE0UL); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align4k (uint32_t value) { return (value & 0xFFFFF000UL); } diff --git a/src/common/tusb_compiler.h b/src/common/tusb_compiler.h index 6f07bdd53..0d5570b1c 100644 --- a/src/common/tusb_compiler.h +++ b/src/common/tusb_compiler.h @@ -56,7 +56,7 @@ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L #define TU_VERIFY_STATIC _Static_assert #elif defined(__CCRX__) - #define TU_VERIFY_STATIC(const_expr, _mess) typedef char TU_XSTRCAT(Line, __LINE__)[(const_expr) ? 1 : 0]; + #define TU_VERIFY_STATIC(const_expr, _mess) typedef char TU_XSTRCAT(_verify_static_, _TU_COUNTER_)[(const_expr) ? 1 : 0]; #else #define TU_VERIFY_STATIC(const_expr, _mess) enum { TU_XSTRCAT(_verify_static_, _TU_COUNTER_) = 1/(!!(const_expr)) } #endif diff --git a/src/common/tusb_debug.h b/src/common/tusb_debug.h index 36507041f..2e9f1d9cd 100644 --- a/src/common/tusb_debug.h +++ b/src/common/tusb_debug.h @@ -43,7 +43,7 @@ #if CFG_TUSB_DEBUG // Enum to String for debugging purposes -#if CFG_TUSB_DEBUG >= 2 +#if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL || CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL extern char const* const tu_str_speed[]; extern char const* const tu_str_std_request[]; extern char const* const tu_str_xfer_result[]; @@ -58,16 +58,15 @@ void tu_print_mem(void const *buf, uint32_t count, uint8_t indent); #define tu_printf printf #endif -static inline void tu_print_arr(uint8_t const* buf, uint32_t bufsize) -{ +static inline void tu_print_buf(uint8_t const* buf, uint32_t bufsize) { for(uint32_t i=0; i= 2 #define TU_LOG2 TU_LOG1 #define TU_LOG2_MEM TU_LOG1_MEM - #define TU_LOG2_ARR TU_LOG1_ARR - #define TU_LOG2_PTR TU_LOG1_PTR + #define TU_LOG2_BUF TU_LOG1_BUF #define TU_LOG2_INT TU_LOG1_INT #define TU_LOG2_HEX TU_LOG1_HEX #endif @@ -95,30 +92,25 @@ static inline void tu_print_arr(uint8_t const* buf, uint32_t bufsize) #if CFG_TUSB_DEBUG >= 3 #define TU_LOG3 TU_LOG1 #define TU_LOG3_MEM TU_LOG1_MEM - #define TU_LOG3_ARR TU_LOG1_ARR - #define TU_LOG3_PTR TU_LOG1_PTR + #define TU_LOG3_BUF TU_LOG1_BUF #define TU_LOG3_INT TU_LOG1_INT #define TU_LOG3_HEX TU_LOG1_HEX #endif -typedef struct -{ +typedef struct { uint32_t key; const char* data; } tu_lookup_entry_t; -typedef struct -{ +typedef struct { uint16_t count; tu_lookup_entry_t const* items; } tu_lookup_table_t; -static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint32_t key) -{ +static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint32_t key) { tu_static char not_found[11]; - for(uint16_t i=0; icount; i++) - { + for(uint16_t i=0; icount; i++) { if (p_table->items[i].key == key) return p_table->items[i].data; } @@ -133,7 +125,7 @@ static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint3 #ifndef TU_LOG #define TU_LOG(n, ...) #define TU_LOG_MEM(n, ...) - #define TU_LOG_PTR(n, ...) + #define TU_LOG_BUF(n, ...) #define TU_LOG_INT(n, ...) #define TU_LOG_HEX(n, ...) #define TU_LOG_LOCATION() @@ -144,14 +136,14 @@ static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint3 #define TU_LOG0(...) #define TU_LOG0_MEM(...) -#define TU_LOG0_PTR(...) +#define TU_LOG0_BUF(...) #define TU_LOG0_INT(...) #define TU_LOG0_HEX(...) #ifndef TU_LOG1 #define TU_LOG1(...) #define TU_LOG1_MEM(...) - #define TU_LOG1_PTR(...) + #define TU_LOG1_BUF(...) #define TU_LOG1_INT(...) #define TU_LOG1_HEX(...) #endif @@ -159,7 +151,7 @@ static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint3 #ifndef TU_LOG2 #define TU_LOG2(...) #define TU_LOG2_MEM(...) - #define TU_LOG2_PTR(...) + #define TU_LOG2_BUF(...) #define TU_LOG2_INT(...) #define TU_LOG2_HEX(...) #endif @@ -167,7 +159,7 @@ static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint3 #ifndef TU_LOG3 #define TU_LOG3(...) #define TU_LOG3_MEM(...) - #define TU_LOG3_PTR(...) + #define TU_LOG3_BUF(...) #define TU_LOG3_INT(...) #define TU_LOG3_HEX(...) #endif diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index d6c3db4ce..8a0fd4417 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -62,7 +62,9 @@ TU_ATTR_ALWAYS_INLINE static inline void _ff_unlock(osal_mutex_t mutex) typedef enum { TU_FIFO_COPY_INC, ///< Copy from/to an increasing source/destination address - default mode +#ifdef TUP_MEM_CONST_ADDR TU_FIFO_COPY_CST_FULL_WORDS, ///< Copy from/to a constant source/destination address - required for e.g. STM32 to write into USB hardware FIFO +#endif } tu_fifo_copy_mode_t; bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable) @@ -92,6 +94,7 @@ bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_si // Pull & Push //--------------------------------------------------------------------+ +#ifdef TUP_MEM_CONST_ADDR // Intended to be used to read from hardware USB FIFO in e.g. STM32 where all data is read from a constant address // Code adapted from dcd_synopsys.c // TODO generalize with configurable 1 byte or 4 byte each read @@ -140,6 +143,7 @@ static void _ff_pull_const_addr(void * app_buf, const uint8_t * ff_buf, uint16_t *reg_tx = tmp32; } } +#endif // send one item to fifo WITHOUT updating write pointer static inline void _ff_push(tu_fifo_t* f, void const * app_buf, uint16_t rel) @@ -179,7 +183,7 @@ static void _ff_push_n(tu_fifo_t* f, void const * app_buf, uint16_t n, uint16_t memcpy(f->buffer, ((uint8_t const*) app_buf) + lin_bytes, wrap_bytes); } break; - +#ifdef TUP_MEM_CONST_ADDR case TU_FIFO_COPY_CST_FULL_WORDS: // Intended for hardware buffers from which it can be read word by word only if(n <= lin_count) @@ -224,6 +228,8 @@ static void _ff_push_n(tu_fifo_t* f, void const * app_buf, uint16_t n, uint16_t if (wrap_bytes > 0) _ff_push_const_addr(ff_buf, app_buf, wrap_bytes); } break; +#endif + default: break; } } @@ -264,7 +270,7 @@ static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rd_ptr, memcpy((uint8_t*) app_buf + lin_bytes, f->buffer, wrap_bytes); } break; - +#ifdef TUP_MEM_CONST_ADDR case TU_FIFO_COPY_CST_FULL_WORDS: if ( n <= lin_count ) { @@ -309,6 +315,7 @@ static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rd_ptr, // Read data wrapped part if (wrap_bytes > 0) _ff_pull_const_addr(app_buf, ff_buf, wrap_bytes); } +#endif break; default: break; @@ -726,10 +733,29 @@ uint16_t tu_fifo_read_n(tu_fifo_t* f, void * buffer, uint16_t n) return _tu_fifo_read_n(f, buffer, n, TU_FIFO_COPY_INC); } +#ifdef TUP_MEM_CONST_ADDR +/******************************************************************************/ +/*! + @brief This function will read n elements from the array index specified by + the read pointer and increment the read index. + This function checks for an overflow and corrects read pointer if required. + The dest address will not be incremented which is useful for writing to registers. + + @param[in] f + Pointer to the FIFO buffer to manipulate + @param[in] buffer + The pointer to data location + @param[in] n + Number of element that buffer can afford + + @returns number of items read from the FIFO + */ +/******************************************************************************/ uint16_t tu_fifo_read_n_const_addr_full_words(tu_fifo_t* f, void * buffer, uint16_t n) { return _tu_fifo_read_n(f, buffer, n, TU_FIFO_COPY_CST_FULL_WORDS); } +#endif /******************************************************************************/ /*! @@ -838,6 +864,7 @@ uint16_t tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n) return _tu_fifo_write_n(f, data, n, TU_FIFO_COPY_INC); } +#ifdef TUP_MEM_CONST_ADDR /******************************************************************************/ /*! @brief This function will write n elements into the array index specified by @@ -857,6 +884,7 @@ uint16_t tu_fifo_write_n_const_addr_full_words(tu_fifo_t* f, const void * data, { return _tu_fifo_write_n(f, data, n, TU_FIFO_COPY_CST_FULL_WORDS); } +#endif /******************************************************************************/ /*! diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h index 2f60ec2f4..6c0efb509 100644 --- a/src/common/tusb_fifo.h +++ b/src/common/tusb_fifo.h @@ -102,10 +102,8 @@ extern "C" { * | * ------------------------- * | R | 1 | 2 | W | 4 | 5 | - */ -typedef struct -{ +typedef struct { uint8_t* buffer ; // buffer pointer uint16_t depth ; // max items @@ -124,16 +122,14 @@ typedef struct } tu_fifo_t; -typedef struct -{ +typedef struct { uint16_t len_lin ; ///< linear length in item size uint16_t len_wrap ; ///< wrapped length in item size void * ptr_lin ; ///< linear part start pointer void * ptr_wrap ; ///< wrapped part start pointer } tu_fifo_buffer_info_t; -#define TU_FIFO_INIT(_buffer, _depth, _type, _overwritable) \ -{ \ +#define TU_FIFO_INIT(_buffer, _depth, _type, _overwritable){\ .buffer = _buffer, \ .depth = _depth, \ .item_size = sizeof(_type), \ @@ -144,32 +140,31 @@ typedef struct uint8_t _name##_buf[_depth*sizeof(_type)]; \ tu_fifo_t _name = TU_FIFO_INIT(_name##_buf, _depth, _type, _overwritable) - bool tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable); bool tu_fifo_clear(tu_fifo_t *f); bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable); #if OSAL_MUTEX_REQUIRED TU_ATTR_ALWAYS_INLINE static inline -void tu_fifo_config_mutex(tu_fifo_t *f, osal_mutex_t wr_mutex, osal_mutex_t rd_mutex) -{ +void tu_fifo_config_mutex(tu_fifo_t *f, osal_mutex_t wr_mutex, osal_mutex_t rd_mutex) { f->mutex_wr = wr_mutex; f->mutex_rd = rd_mutex; } - #else - #define tu_fifo_config_mutex(_f, _wr_mutex, _rd_mutex) - #endif bool tu_fifo_write (tu_fifo_t* f, void const * p_data); uint16_t tu_fifo_write_n (tu_fifo_t* f, void const * p_data, uint16_t n); +#ifdef TUP_MEM_CONST_ADDR uint16_t tu_fifo_write_n_const_addr_full_words (tu_fifo_t* f, const void * data, uint16_t n); +#endif bool tu_fifo_read (tu_fifo_t* f, void * p_buffer); uint16_t tu_fifo_read_n (tu_fifo_t* f, void * p_buffer, uint16_t n); +#ifdef TUP_MEM_CONST_ADDR uint16_t tu_fifo_read_n_const_addr_full_words (tu_fifo_t* f, void * buffer, uint16_t n); +#endif bool tu_fifo_peek (tu_fifo_t* f, void * p_buffer); uint16_t tu_fifo_peek_n (tu_fifo_t* f, void * p_buffer, uint16_t n); @@ -182,8 +177,7 @@ bool tu_fifo_overflowed (tu_fifo_t* f); void tu_fifo_correct_read_pointer (tu_fifo_t* f); TU_ATTR_ALWAYS_INLINE static inline -uint16_t tu_fifo_depth(tu_fifo_t* f) -{ +uint16_t tu_fifo_depth(tu_fifo_t* f) { return f->depth; } @@ -198,7 +192,6 @@ void tu_fifo_advance_read_pointer (tu_fifo_t *f, uint16_t n); void tu_fifo_get_read_info (tu_fifo_t *f, tu_fifo_buffer_info_t *info); void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info); - #ifdef __cplusplus } #endif diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 89f89182e..4e3b89262 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -58,6 +58,7 @@ // NXP //--------------------------------------------------------------------+ #if TU_CHECK_MCU(OPT_MCU_LPC11UXX, OPT_MCU_LPC13XX, OPT_MCU_LPC15XX) + #define TUP_USBIP_IP3511 #define TUP_DCD_ENDPOINT_MAX 5 #elif TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX) @@ -66,14 +67,17 @@ #define TUP_OHCI_RHPORTS 2 #elif TU_CHECK_MCU(OPT_MCU_LPC51UXX) + #define TUP_USBIP_IP3511 #define TUP_DCD_ENDPOINT_MAX 5 -#elif TU_CHECK_MCU(OPT_MCU_LPC54XXX) +#elif TU_CHECK_MCU(OPT_MCU_LPC54) // TODO USB0 has 5, USB1 has 6 + #define TUP_USBIP_IP3511 #define TUP_DCD_ENDPOINT_MAX 6 -#elif TU_CHECK_MCU(OPT_MCU_LPC55XX) +#elif TU_CHECK_MCU(OPT_MCU_LPC55) // TODO USB0 has 5, USB1 has 6 + #define TUP_USBIP_IP3511 #define TUP_DCD_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX) @@ -96,6 +100,13 @@ #define TUP_DCD_ENDPOINT_MAX 8 #define TUP_RHPORT_HIGHSPEED 1 +#elif TU_CHECK_MCU(OPT_MCU_MCXA15) + // USB0 is chipidea FS + #define TUP_USBIP_CHIPIDEA_FS + #define TUP_USBIP_CHIPIDEA_FS_MCX + + #define TUP_DCD_ENDPOINT_MAX 16 + #elif TU_CHECK_MCU(OPT_MCU_MIMXRT1XXX) #define TUP_USBIP_CHIPIDEA_HS #define TUP_USBIP_EHCI @@ -103,7 +114,7 @@ #define TUP_DCD_ENDPOINT_MAX 8 #define TUP_RHPORT_HIGHSPEED 1 -#elif TU_CHECK_MCU(OPT_MCU_KINETIS_KL, OPT_MCU_KINETIS_K32L) +#elif TU_CHECK_MCU(OPT_MCU_KINETIS_KL, OPT_MCU_KINETIS_K32L, OPT_MCU_KINETIS_K) #define TUP_USBIP_CHIPIDEA_FS #define TUP_USBIP_CHIPIDEA_FS_KINETIS #define TUP_DCD_ENDPOINT_MAX 16 @@ -206,6 +217,11 @@ #define TUP_DCD_ENDPOINT_MAX 9 +#elif TU_CHECK_MCU(OPT_MCU_STM32H5) + #define TUP_USBIP_FSDEV + #define TUP_USBIP_FSDEV_STM32 + #define TUP_DCD_ENDPOINT_MAX 8 + #elif TU_CHECK_MCU(OPT_MCU_STM32G4) // Device controller #define TUP_USBIP_FSDEV @@ -213,9 +229,7 @@ // TypeC controller #define TUP_USBIP_TYPEC_STM32 - #define TUP_DCD_ENDPOINT_MAX 8 - #define TUP_TYPEC_RHPORTS_NUM 1 #elif TU_CHECK_MCU(OPT_MCU_STM32G0) @@ -257,14 +271,21 @@ #elif TU_CHECK_MCU(OPT_MCU_STM32U5) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 - #define TUP_DCD_ENDPOINT_MAX 6 + + // U59x/5Ax/5Fx/5Gx are highspeed with built-in HS PHY + #if defined(STM32U595xx) || defined(STM32U599xx) || defined(STM32U5A5xx) || defined(STM32U5A9xx) || \ + defined(STM32U5F7xx) || defined(STM32U5F9xx) || defined(STM32U5G7xx) || defined(STM32U5G9xx) + #define TUP_DCD_ENDPOINT_MAX 9 + #define TUP_RHPORT_HIGHSPEED 1 + #else + #define TUP_DCD_ENDPOINT_MAX 6 + #endif #elif TU_CHECK_MCU(OPT_MCU_STM32L5) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 #define TUP_DCD_ENDPOINT_MAX 8 - //--------------------------------------------------------------------+ // Sony //--------------------------------------------------------------------+ @@ -308,6 +329,9 @@ #define TUP_USBIP_DWC2 #define TUP_DCD_ENDPOINT_MAX 6 +#elif TU_CHECK_MCU(OPT_MCU_ESP32) && (CFG_TUD_ENABLED || !(defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421)) + #error "MCUs are only supported with CFG_TUH_MAX3421 enabled" + //--------------------------------------------------------------------+ // Dialog //--------------------------------------------------------------------+ @@ -379,8 +403,24 @@ #elif TU_CHECK_MCU(OPT_MCU_CH32V307) #define TUP_DCD_ENDPOINT_MAX 16 #define TUP_RHPORT_HIGHSPEED 1 + +#elif TU_CHECK_MCU(OPT_MCU_CH32F20X) + #define TUP_DCD_ENDPOINT_MAX 16 + #define TUP_RHPORT_HIGHSPEED 1 #endif + +//--------------------------------------------------------------------+ +// External USB controller +//--------------------------------------------------------------------+ + +#if defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 + #ifndef CFG_TUH_MAX3421_ENDPOINT_TOTAL + #define CFG_TUH_MAX3421_ENDPOINT_TOTAL (8 + 4*(CFG_TUH_DEVICE_MAX-1)) + #endif +#endif + + //--------------------------------------------------------------------+ // Default Values //--------------------------------------------------------------------+ @@ -389,7 +429,7 @@ #define TUP_MCU_MULTIPLE_CORE 0 #endif -#ifndef TUP_DCD_ENDPOINT_MAX +#if !defined(TUP_DCD_ENDPOINT_MAX) && defined(CFG_TUD_ENABLED) && CFG_TUD_ENABLED #warning "TUP_DCD_ENDPOINT_MAX is not defined for this MCU, default to 8" #define TUP_DCD_ENDPOINT_MAX 8 #endif @@ -404,4 +444,12 @@ #define TU_ATTR_FAST_FUNC #endif +#if defined(TUP_USBIP_DWC2) || defined(TUP_USBIP_FSDEV) + #define TUP_DCD_EDPT_ISO_ALLOC +#endif + +#if defined(TUP_USBIP_DWC2) + #define TUP_MEM_CONST_ADDR +#endif + #endif diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index db1ba974d..373a50256 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -60,7 +60,7 @@ typedef struct { tu_fifo_t ff; // mutex: read if ep rx, write if e tx - OSAL_MUTEX_DEF(ff_mutex); + OSAL_MUTEX_DEF(ff_mutexdef); }tu_edpt_stream_t; @@ -87,15 +87,17 @@ bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex); // Endpoint Stream //--------------------------------------------------------------------+ -// Init an stream, should only be called once +// Init an endpoint stream bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool overwritable, void* ff_buf, uint16_t ff_bufsize, uint8_t* ep_buf, uint16_t ep_bufsize); +// Deinit an endpoint stream +bool tu_edpt_stream_deinit(tu_edpt_stream_t* s); + // Open an stream for an endpoint // hwid is either device address (host mode) or rhport (device mode) TU_ATTR_ALWAYS_INLINE static inline -void tu_edpt_stream_open(tu_edpt_stream_t* s, uint8_t hwid, tusb_desc_endpoint_t const *desc_ep) -{ +void tu_edpt_stream_open(tu_edpt_stream_t* s, uint8_t hwid, tusb_desc_endpoint_t const *desc_ep) { tu_fifo_clear(&s->ff); s->hwid = hwid; s->ep_addr = desc_ep->bEndpointAddress; @@ -103,16 +105,14 @@ void tu_edpt_stream_open(tu_edpt_stream_t* s, uint8_t hwid, tusb_desc_endpoint_t } TU_ATTR_ALWAYS_INLINE static inline -void tu_edpt_stream_close(tu_edpt_stream_t* s) -{ +void tu_edpt_stream_close(tu_edpt_stream_t* s) { s->hwid = 0; s->ep_addr = 0; } // Clear fifo TU_ATTR_ALWAYS_INLINE static inline -bool tu_edpt_stream_clear(tu_edpt_stream_t* s) -{ +bool tu_edpt_stream_clear(tu_edpt_stream_t* s) { return tu_fifo_clear(&s->ff); } @@ -131,8 +131,7 @@ bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t* s, uint32_t last_xferr // Get the number of bytes available for writing TU_ATTR_ALWAYS_INLINE static inline -uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t* s) -{ +uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t* s) { return (uint32_t) tu_fifo_remaining(&s->ff); } diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index fab680989..b571f9b72 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -24,12 +24,8 @@ * This file is part of the TinyUSB stack. */ -/** \ingroup group_usb_definitions - * \defgroup USBDef_Type USB Types - * @{ */ - -#ifndef _TUSB_TYPES_H_ -#define _TUSB_TYPES_H_ +#ifndef TUSB_TYPES_H_ +#define TUSB_TYPES_H_ #include #include @@ -44,43 +40,38 @@ *------------------------------------------------------------------*/ /// defined base on EHCI specs value for Endpoint Speed -typedef enum -{ +typedef enum { TUSB_SPEED_FULL = 0, TUSB_SPEED_LOW = 1, TUSB_SPEED_HIGH = 2, TUSB_SPEED_INVALID = 0xff, -}tusb_speed_t; +} tusb_speed_t; /// defined base on USB Specs Endpoint's bmAttributes -typedef enum -{ +typedef enum { TUSB_XFER_CONTROL = 0 , TUSB_XFER_ISOCHRONOUS , TUSB_XFER_BULK , TUSB_XFER_INTERRUPT -}tusb_xfer_type_t; +} tusb_xfer_type_t; -typedef enum -{ +typedef enum { TUSB_DIR_OUT = 0, TUSB_DIR_IN = 1, TUSB_DIR_IN_MASK = 0x80 -}tusb_dir_t; +} tusb_dir_t; -enum -{ +enum { TUSB_EPSIZE_BULK_FS = 64, - TUSB_EPSIZE_BULK_HS= 512, + TUSB_EPSIZE_BULK_HS = 512, TUSB_EPSIZE_ISO_FS_MAX = 1023, TUSB_EPSIZE_ISO_HS_MAX = 1024, }; -/// Isochronous End Point Attributes -typedef enum -{ +/// Isochronous Endpoint Attributes +typedef enum { TUSB_ISO_EP_ATT_NO_SYNC = 0x00, TUSB_ISO_EP_ATT_ASYNCHRONOUS = 0x04, TUSB_ISO_EP_ATT_ADAPTIVE = 0x08, @@ -88,11 +79,10 @@ typedef enum TUSB_ISO_EP_ATT_DATA = 0x00, ///< Data End Point TUSB_ISO_EP_ATT_EXPLICIT_FB = 0x10, ///< Feedback End Point TUSB_ISO_EP_ATT_IMPLICIT_FB = 0x20, ///< Data endpoint that also serves as an implicit feedback -}tusb_iso_ep_attribute_t; +} tusb_iso_ep_attribute_t; /// USB Descriptor Types -typedef enum -{ +typedef enum { TUSB_DESC_DEVICE = 0x01, TUSB_DESC_CONFIGURATION = 0x02, TUSB_DESC_STRING = 0x03, @@ -119,10 +109,9 @@ typedef enum TUSB_DESC_SUPERSPEED_ENDPOINT_COMPANION = 0x30, TUSB_DESC_SUPERSPEED_ISO_ENDPOINT_COMPANION = 0x31 -}tusb_desc_type_t; +} tusb_desc_type_t; -typedef enum -{ +typedef enum { TUSB_REQ_GET_STATUS = 0 , TUSB_REQ_CLEAR_FEATURE = 1 , TUSB_REQ_RESERVED = 2 , @@ -136,25 +125,22 @@ typedef enum TUSB_REQ_GET_INTERFACE = 10 , TUSB_REQ_SET_INTERFACE = 11 , TUSB_REQ_SYNCH_FRAME = 12 -}tusb_request_code_t; +} tusb_request_code_t; -typedef enum -{ +typedef enum { TUSB_REQ_FEATURE_EDPT_HALT = 0, TUSB_REQ_FEATURE_REMOTE_WAKEUP = 1, TUSB_REQ_FEATURE_TEST_MODE = 2 -}tusb_request_feature_selector_t; +} tusb_request_feature_selector_t; -typedef enum -{ +typedef enum { TUSB_REQ_TYPE_STANDARD = 0, TUSB_REQ_TYPE_CLASS, TUSB_REQ_TYPE_VENDOR, TUSB_REQ_TYPE_INVALID } tusb_request_type_t; -typedef enum -{ +typedef enum { TUSB_REQ_RCPT_DEVICE =0, TUSB_REQ_RCPT_INTERFACE, TUSB_REQ_RCPT_ENDPOINT, @@ -162,8 +148,7 @@ typedef enum } tusb_request_recipient_t; // https://www.usb.org/defined-class-codes -typedef enum -{ +typedef enum { TUSB_CLASS_UNSPECIFIED = 0 , TUSB_CLASS_AUDIO = 1 , TUSB_CLASS_CDC = 2 , @@ -187,26 +172,23 @@ typedef enum TUSB_CLASS_MISC = 0xEF , TUSB_CLASS_APPLICATION_SPECIFIC = 0xFE , TUSB_CLASS_VENDOR_SPECIFIC = 0xFF -}tusb_class_code_t; +} tusb_class_code_t; typedef enum { MISC_SUBCLASS_COMMON = 2 }misc_subclass_type_t; -typedef enum -{ +typedef enum { MISC_PROTOCOL_IAD = 1 -}misc_protocol_type_t; +} misc_protocol_type_t; -typedef enum -{ +typedef enum { APP_SUBCLASS_USBTMC = 0x03, APP_SUBCLASS_DFU_RUNTIME = 0x01 } app_subclass_type_t; -typedef enum -{ +typedef enum { DEVICE_CAPABILITY_WIRELESS_USB = 0x01, DEVICE_CAPABILITY_USB20_EXTENSION = 0x02, DEVICE_CAPABILITY_SUPERSPEED_USB = 0x03, @@ -223,11 +205,11 @@ typedef enum DEVICE_CAPABILITY_AUTHENTICATION = 0x0E, DEVICE_CAPABILITY_BILLBOARD_EX = 0x0F, DEVICE_CAPABILITY_CONFIGURATION_SUMMARY = 0x10 -}device_capability_type_t; +} device_capability_type_t; enum { - TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP = TU_BIT(5), - TUSB_DESC_CONFIG_ATT_SELF_POWERED = TU_BIT(6), + TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP = 1u << 5, + TUSB_DESC_CONFIG_ATT_SELF_POWERED = 1u << 6, }; #define TUSB_DESC_CONFIG_POWER_MA(x) ((x)/2) @@ -235,28 +217,25 @@ enum { //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ -typedef enum -{ +typedef enum { XFER_RESULT_SUCCESS = 0, XFER_RESULT_FAILED, XFER_RESULT_STALLED, XFER_RESULT_TIMEOUT, XFER_RESULT_INVALID -}xfer_result_t; +} xfer_result_t; -enum // TODO remove -{ +// TODO remove +enum { DESC_OFFSET_LEN = 0, DESC_OFFSET_TYPE = 1 }; -enum -{ +enum { INTERFACE_INVALID_NUMBER = 0xff }; -typedef enum -{ +typedef enum { MS_OS_20_SET_HEADER_DESCRIPTOR = 0x00, MS_OS_20_SUBSET_HEADER_CONFIGURATION = 0x01, MS_OS_20_SUBSET_HEADER_FUNCTION = 0x02, @@ -268,16 +247,14 @@ typedef enum MS_OS_20_FEATURE_VENDOR_REVISION = 0x08 } microsoft_os_20_type_t; -enum -{ +enum { CONTROL_STAGE_IDLE, CONTROL_STAGE_SETUP, CONTROL_STAGE_DATA, CONTROL_STAGE_ACK }; -enum -{ +enum { TUSB_INDEX_INVALID_8 = 0xFFu }; @@ -290,15 +267,14 @@ TU_ATTR_PACKED_BEGIN TU_ATTR_BIT_FIELD_ORDER_BEGIN /// USB Device Descriptor -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. uint8_t bDescriptorType ; ///< DEVICE Descriptor Type. - uint16_t bcdUSB ; ///< BUSB Specification Release Number in Binary-Coded Decimal (i.e., 2.10 is 210H). This field identifies the release of the USB Specification with which the device and its descriptors are compliant. + uint16_t bcdUSB ; ///< BUSB Specification Release Number in Binary-Coded Decimal (i.e., 2.10 is 210H). - uint8_t bDeviceClass ; ///< Class code (assigned by the USB-IF). \li If this field is reset to zero, each interface within a configuration specifies its own class information and the various interfaces operate independently. \li If this field is set to a value between 1 and FEH, the device supports different class specifications on different interfaces and the interfaces may not operate independently. This value identifies the class definition used for the aggregate interfaces. \li If this field is set to FFH, the device class is vendor-specific. - uint8_t bDeviceSubClass ; ///< Subclass code (assigned by the USB-IF). These codes are qualified by the value of the bDeviceClass field. \li If the bDeviceClass field is reset to zero, this field must also be reset to zero. \li If the bDeviceClass field is not set to FFH, all values are reserved for assignment by the USB-IF. - uint8_t bDeviceProtocol ; ///< Protocol code (assigned by the USB-IF). These codes are qualified by the value of the bDeviceClass and the bDeviceSubClass fields. If a device supports class-specific protocols on a device basis as opposed to an interface basis, this code identifies the protocols that the device uses as defined by the specification of the device class. \li If this field is reset to zero, the device does not use class-specific protocols on a device basis. However, it may use classspecific protocols on an interface basis. \li If this field is set to FFH, the device uses a vendor-specific protocol on a device basis. + uint8_t bDeviceClass ; ///< Class code (assigned by the USB-IF). + uint8_t bDeviceSubClass ; ///< Subclass code (assigned by the USB-IF). + uint8_t bDeviceProtocol ; ///< Protocol code (assigned by the USB-IF). uint8_t bMaxPacketSize0 ; ///< Maximum packet size for endpoint zero (only 8, 16, 32, or 64 are valid). For HS devices is fixed to 64. uint16_t idVendor ; ///< Vendor ID (assigned by the USB-IF). @@ -314,8 +290,7 @@ typedef struct TU_ATTR_PACKED TU_VERIFY_STATIC( sizeof(tusb_desc_device_t) == 18, "size is not correct"); // USB Binary Device Object Store (BOS) Descriptor -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes uint8_t bDescriptorType ; ///< CONFIGURATION Descriptor Type uint16_t wTotalLength ; ///< Total length of data returned for this descriptor @@ -325,8 +300,7 @@ typedef struct TU_ATTR_PACKED TU_VERIFY_STATIC( sizeof(tusb_desc_bos_t) == 5, "size is not correct"); /// USB Configuration Descriptor -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes uint8_t bDescriptorType ; ///< CONFIGURATION Descriptor Type uint16_t wTotalLength ; ///< Total length of data returned for this configuration. Includes the combined length of all descriptors (configuration, interface, endpoint, and class- or vendor-specific) returned for this configuration. @@ -341,8 +315,7 @@ typedef struct TU_ATTR_PACKED TU_VERIFY_STATIC( sizeof(tusb_desc_configuration_t) == 9, "size is not correct"); /// USB Interface Descriptor -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes uint8_t bDescriptorType ; ///< INTERFACE Descriptor Type @@ -358,8 +331,7 @@ typedef struct TU_ATTR_PACKED TU_VERIFY_STATIC( sizeof(tusb_desc_interface_t) == 9, "size is not correct"); /// USB Endpoint Descriptor -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength ; // Size of this descriptor in bytes uint8_t bDescriptorType ; // ENDPOINT Descriptor Type @@ -379,8 +351,7 @@ typedef struct TU_ATTR_PACKED TU_VERIFY_STATIC( sizeof(tusb_desc_endpoint_t) == 7, "size is not correct"); /// USB Other Speed Configuration Descriptor -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of descriptor uint8_t bDescriptorType ; ///< Other_speed_Configuration Type uint16_t wTotalLength ; ///< Total length of data returned @@ -393,8 +364,7 @@ typedef struct TU_ATTR_PACKED } tusb_desc_other_speed_t; /// USB Device Qualifier Descriptor -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of descriptor uint8_t bDescriptorType ; ///< Device Qualifier Type uint16_t bcdUSB ; ///< USB specification version number (e.g., 0200H for V2.00) @@ -411,8 +381,7 @@ typedef struct TU_ATTR_PACKED TU_VERIFY_STATIC( sizeof(tusb_desc_device_qualifier_t) == 10, "size is not correct"); /// USB Interface Association Descriptor (IAD ECN) -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of descriptor uint8_t bDescriptorType ; ///< Other_speed_Configuration Type @@ -426,17 +395,17 @@ typedef struct TU_ATTR_PACKED uint8_t iFunction ; ///< Index of the string descriptor describing the interface association. } tusb_desc_interface_assoc_t; +TU_VERIFY_STATIC( sizeof(tusb_desc_interface_assoc_t) == 8, "size is not correct"); + // USB String Descriptor -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes uint8_t bDescriptorType ; ///< Descriptor Type uint16_t unicode_string[]; } tusb_desc_string_t; // USB Binary Device Object Store (BOS) -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType ; uint8_t bDevCapabilityType; @@ -445,9 +414,8 @@ typedef struct TU_ATTR_PACKED uint8_t CapabilityData[]; } tusb_desc_bos_platform_t; -// USB WebuSB URL Descriptor -typedef struct TU_ATTR_PACKED -{ +// USB WebUSB URL Descriptor +typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; uint8_t bScheme; @@ -455,8 +423,7 @@ typedef struct TU_ATTR_PACKED } tusb_desc_webusb_url_t; // DFU Functional Descriptor -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; @@ -481,7 +448,7 @@ typedef struct TU_ATTR_PACKED // //--------------------------------------------------------------------+ -typedef struct TU_ATTR_PACKED{ +typedef struct TU_ATTR_PACKED { union { struct TU_ATTR_PACKED { uint8_t recipient : 5; ///< Recipient type tusb_request_recipient_t. @@ -500,7 +467,6 @@ typedef struct TU_ATTR_PACKED{ TU_VERIFY_STATIC( sizeof(tusb_control_request_t) == 8, "size is not correct"); - TU_ATTR_PACKED_END // End of all packed definitions TU_ATTR_BIT_FIELD_ORDER_END @@ -509,36 +475,25 @@ TU_ATTR_BIT_FIELD_ORDER_END //--------------------------------------------------------------------+ // Get direction from Endpoint address -TU_ATTR_ALWAYS_INLINE static inline tusb_dir_t tu_edpt_dir(uint8_t addr) -{ +TU_ATTR_ALWAYS_INLINE static inline tusb_dir_t tu_edpt_dir(uint8_t addr) { return (addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT; } // Get Endpoint number from address -TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_edpt_number(uint8_t addr) -{ +TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_edpt_number(uint8_t addr) { return (uint8_t)(addr & (~TUSB_DIR_IN_MASK)); } -TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_edpt_addr(uint8_t num, uint8_t dir) -{ +TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_edpt_addr(uint8_t num, uint8_t dir) { return (uint8_t)(num | (dir ? TUSB_DIR_IN_MASK : 0)); } -TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_edpt_packet_size(tusb_desc_endpoint_t const* desc_ep) -{ - return tu_le16toh(desc_ep->wMaxPacketSize) & TU_GENMASK(10, 0); +TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_edpt_packet_size(tusb_desc_endpoint_t const* desc_ep) { + return tu_le16toh(desc_ep->wMaxPacketSize) & 0x7FF; } #if CFG_TUSB_DEBUG -TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_dir_str(tusb_dir_t dir) -{ - tu_static const char *str[] = {"out", "in"}; - return str[dir]; -} - -TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_type_str(tusb_xfer_type_t t) -{ +TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_type_str(tusb_xfer_type_t t) { tu_static const char *str[] = {"control", "isochronous", "bulk", "interrupt"}; return str[t]; } @@ -549,21 +504,18 @@ TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_type_str(tusb_xfer_type_ //--------------------------------------------------------------------+ // return next descriptor -TU_ATTR_ALWAYS_INLINE static inline uint8_t const * tu_desc_next(void const* desc) -{ +TU_ATTR_ALWAYS_INLINE static inline uint8_t const * tu_desc_next(void const* desc) { uint8_t const* desc8 = (uint8_t const*) desc; return desc8 + desc8[DESC_OFFSET_LEN]; } // get descriptor type -TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_type(void const* desc) -{ +TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_type(void const* desc) { return ((uint8_t const*) desc)[DESC_OFFSET_TYPE]; } // get descriptor length -TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_len(void const* desc) -{ +TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_len(void const* desc) { return ((uint8_t const*) desc)[DESC_OFFSET_LEN]; } @@ -580,6 +532,4 @@ uint8_t const * tu_desc_find3(uint8_t const* desc, uint8_t const* end, uint8_t b } #endif -#endif /* _TUSB_TYPES_H_ */ - -/** @} */ +#endif // TUSB_TYPES_H_ diff --git a/src/common/tusb_verify.h b/src/common/tusb_verify.h index 12355e8be..dde0550d3 100644 --- a/src/common/tusb_verify.h +++ b/src/common/tusb_verify.h @@ -56,12 +56,8 @@ * #define TU_VERIFY(cond) if(cond) return false; * #define TU_VERIFY(cond,ret) if(cond) return ret; * - * #define TU_VERIFY_HDLR(cond,handler) if(cond) {handler; return false;} - * #define TU_VERIFY_HDLR(cond,ret,handler) if(cond) {handler; return ret;} - * * #define TU_ASSERT(cond) if(cond) {_MESS_FAILED(); TU_BREAKPOINT(), return false;} * #define TU_ASSERT(cond,ret) if(cond) {_MESS_FAILED(); TU_BREAKPOINT(), return ret;} - * *------------------------------------------------------------------*/ #ifdef __cplusplus @@ -79,15 +75,15 @@ #define _MESS_FAILED() do {} while (0) #endif -// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7, M33 -#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__) - #define TU_BREAKPOINT() do \ - { \ +// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7, M33. M55 +#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8_1M_MAIN__) || \ + defined(__ARM7M__) || defined (__ARM7EM__) || defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__) + #define TU_BREAKPOINT() do { \ volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ if ( (*ARM_CM_DHCSR) & 1UL ) __asm("BKPT #0\n"); /* Only halt mcu if debugger is attached */ \ } while(0) -#elif defined(__riscv) +#elif defined(__riscv) && !TUP_MCU_ESPRESSIF #define TU_BREAKPOINT() do { __asm("ebreak\n"); } while(0) #elif defined(_mips) @@ -97,40 +93,23 @@ #define TU_BREAKPOINT() do {} while (0) #endif -/*------------------------------------------------------------------*/ -/* Macro Generator - *------------------------------------------------------------------*/ - // Helper to implement optional parameter for TU_VERIFY Macro family #define _GET_3RD_ARG(arg1, arg2, arg3, ...) arg3 -#define _GET_4TH_ARG(arg1, arg2, arg3, arg4, ...) arg4 - -/*------------- Generator for TU_VERIFY and TU_VERIFY_HDLR -------------*/ -#define TU_VERIFY_DEFINE(_cond, _handler, _ret) do \ -{ \ - if ( !(_cond) ) { _handler; return _ret; } \ -} while(0) /*------------------------------------------------------------------*/ /* TU_VERIFY * - TU_VERIFY_1ARGS : return false if failed * - TU_VERIFY_2ARGS : return provided value if failed *------------------------------------------------------------------*/ -#define TU_VERIFY_1ARGS(_cond) TU_VERIFY_DEFINE(_cond, , false) -#define TU_VERIFY_2ARGS(_cond, _ret) TU_VERIFY_DEFINE(_cond, , _ret) +#define TU_VERIFY_DEFINE(_cond, _ret) \ + do { \ + if ( !(_cond) ) { return _ret; } \ + } while(0) -#define TU_VERIFY(...) _GET_3RD_ARG(__VA_ARGS__, TU_VERIFY_2ARGS, TU_VERIFY_1ARGS, UNUSED)(__VA_ARGS__) +#define TU_VERIFY_1ARGS(_cond) TU_VERIFY_DEFINE(_cond, false) +#define TU_VERIFY_2ARGS(_cond, _ret) TU_VERIFY_DEFINE(_cond, _ret) - -/*------------------------------------------------------------------*/ -/* TU_VERIFY WITH HANDLER - * - TU_VERIFY_HDLR_2ARGS : execute handler, return false if failed - * - TU_VERIFY_HDLR_3ARGS : execute handler, return provided error if failed - *------------------------------------------------------------------*/ -#define TU_VERIFY_HDLR_2ARGS(_cond, _handler) TU_VERIFY_DEFINE(_cond, _handler, false) -#define TU_VERIFY_HDLR_3ARGS(_cond, _handler, _ret) TU_VERIFY_DEFINE(_cond, _handler, _ret) - -#define TU_VERIFY_HDLR(...) _GET_4TH_ARG(__VA_ARGS__, TU_VERIFY_HDLR_3ARGS, TU_VERIFY_HDLR_2ARGS,UNUSED)(__VA_ARGS__) +#define TU_VERIFY(...) _GET_3RD_ARG(__VA_ARGS__, TU_VERIFY_2ARGS, TU_VERIFY_1ARGS, _dummy)(__VA_ARGS__) /*------------------------------------------------------------------*/ /* ASSERT @@ -138,19 +117,20 @@ * - 1 arg : return false if failed * - 2 arg : return error if failed *------------------------------------------------------------------*/ -#define ASSERT_1ARGS(_cond) TU_VERIFY_DEFINE(_cond, _MESS_FAILED(); TU_BREAKPOINT(), false) -#define ASSERT_2ARGS(_cond, _ret) TU_VERIFY_DEFINE(_cond, _MESS_FAILED(); TU_BREAKPOINT(), _ret) +#define TU_ASSERT_DEFINE(_cond, _ret) \ + do { \ + if ( !(_cond) ) { _MESS_FAILED(); TU_BREAKPOINT(); return _ret; } \ + } while(0) + +#define TU_ASSERT_1ARGS(_cond) TU_ASSERT_DEFINE(_cond, false) +#define TU_ASSERT_2ARGS(_cond, _ret) TU_ASSERT_DEFINE(_cond, _ret) #ifndef TU_ASSERT -#define TU_ASSERT(...) _GET_3RD_ARG(__VA_ARGS__, ASSERT_2ARGS, ASSERT_1ARGS,UNUSED)(__VA_ARGS__) +#define TU_ASSERT(...) _GET_3RD_ARG(__VA_ARGS__, TU_ASSERT_2ARGS, TU_ASSERT_1ARGS, _dummy)(__VA_ARGS__) #endif -/*------------------------------------------------------------------*/ -/* ASSERT HDLR - *------------------------------------------------------------------*/ - #ifdef __cplusplus } #endif -#endif /* TUSB_VERIFY_H_ */ +#endif diff --git a/src/device/dcd.h b/src/device/dcd.h index 18a708347..d4f105aa3 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -47,8 +47,7 @@ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ -typedef enum -{ +typedef enum { DCD_EVENT_INVALID = 0, DCD_EVENT_BUS_RESET, DCD_EVENT_UNPLUGGED, @@ -65,13 +64,11 @@ typedef enum DCD_EVENT_COUNT } dcd_eventid_t; -typedef struct TU_ATTR_ALIGNED(4) -{ +typedef struct TU_ATTR_ALIGNED(4) { uint8_t rhport; uint8_t event_id; - union - { + union { // BUS RESET struct { tusb_speed_t speed; @@ -123,7 +120,10 @@ void dcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) TU_ATTR_W //--------------------------------------------------------------------+ // Initialize controller to device mode -void dcd_init (uint8_t rhport); +void dcd_init(uint8_t rhport); + +// Deinitialize controller, unset device mode. +bool dcd_deinit(uint8_t rhport); // Interrupt Handler void dcd_int_handler(uint8_t rhport); @@ -155,7 +155,7 @@ void dcd_sof_enable(uint8_t rhport, bool en); // Invoked when a control transfer's status stage is complete. // May help DCD to prepare for next control transfer, this API is optional. -void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) TU_ATTR_WEAK; +void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request); // Configure endpoint's registers according to descriptor bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_ep); @@ -184,11 +184,11 @@ void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr); void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr); // Allocate packet buffer used by ISO endpoints -// Some MCU need manual packet buffer allocation, we allocation largest size to avoid clustering +// Some MCU need manual packet buffer allocation, we allocate the largest size to avoid clustering TU_ATTR_WEAK bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size); // Configure and enable an ISO endpoint according to descriptor -TU_ATTR_WEAK bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc); +TU_ATTR_WEAK bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc); //--------------------------------------------------------------------+ // Event API (implemented by stack) @@ -198,23 +198,20 @@ TU_ATTR_WEAK bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t co extern void dcd_event_handler(dcd_event_t const * event, bool in_isr); // helper to send bus signal event -TU_ATTR_ALWAYS_INLINE static inline void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr) -{ +TU_ATTR_ALWAYS_INLINE static inline void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr) { dcd_event_t event = { .rhport = rhport, .event_id = eid }; dcd_event_handler(&event, in_isr); } // helper to send bus reset event -TU_ATTR_ALWAYS_INLINE static inline void dcd_event_bus_reset (uint8_t rhport, tusb_speed_t speed, bool in_isr) -{ +TU_ATTR_ALWAYS_INLINE static inline void dcd_event_bus_reset (uint8_t rhport, tusb_speed_t speed, bool in_isr) { dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_BUS_RESET }; event.bus_reset.speed = speed; dcd_event_handler(&event, in_isr); } // helper to send setup received -TU_ATTR_ALWAYS_INLINE static inline void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr) -{ +TU_ATTR_ALWAYS_INLINE static inline void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr) { dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SETUP_RECEIVED }; memcpy(&event.setup_received, setup, sizeof(tusb_control_request_t)); @@ -222,8 +219,7 @@ TU_ATTR_ALWAYS_INLINE static inline void dcd_event_setup_received(uint8_t rhport } // helper to send transfer complete event -TU_ATTR_ALWAYS_INLINE static inline void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr) -{ +TU_ATTR_ALWAYS_INLINE static inline void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr) { dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_XFER_COMPLETE }; event.xfer_complete.ep_addr = ep_addr; @@ -233,8 +229,7 @@ TU_ATTR_ALWAYS_INLINE static inline void dcd_event_xfer_complete (uint8_t rhport dcd_event_handler(&event, in_isr); } -static inline void dcd_event_sof(uint8_t rhport, uint32_t frame_count, bool in_isr) -{ +TU_ATTR_ALWAYS_INLINE static inline void dcd_event_sof(uint8_t rhport, uint32_t frame_count, bool in_isr) { dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SOF }; event.sof.frame_count = frame_count; dcd_event_handler(&event, in_isr); diff --git a/src/device/usbd.c b/src/device/usbd.c index ff57f5cad..a3f9126de 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -38,11 +38,24 @@ //--------------------------------------------------------------------+ // USBD Configuration //--------------------------------------------------------------------+ - #ifndef CFG_TUD_TASK_QUEUE_SZ #define CFG_TUD_TASK_QUEUE_SZ 16 #endif +//--------------------------------------------------------------------+ +// Weak stubs: invoked if no strong implementation is available +//--------------------------------------------------------------------+ +TU_ATTR_WEAK bool dcd_deinit(uint8_t rhport) { + (void) rhport; + return false; +} + +TU_ATTR_WEAK void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) { + (void)rhport; + (void)eventid; + (void)in_isr; +} + //--------------------------------------------------------------------+ // Device Data //--------------------------------------------------------------------+ @@ -50,10 +63,8 @@ // Invalid driver ID in itf2drv[] ep2drv[][] mapping enum { DRVID_INVALID = 0xFFu }; -typedef struct -{ - struct TU_ATTR_PACKED - { +typedef struct { + struct TU_ATTR_PACKED { volatile uint8_t connected : 1; volatile uint8_t addressed : 1; volatile uint8_t suspended : 1; @@ -62,9 +73,9 @@ typedef struct uint8_t remote_wakeup_support : 1; // configuration descriptor's attribute uint8_t self_powered : 1; // configuration descriptor's attribute }; - volatile uint8_t cfg_num; // current active configuration (0x00 is not configured) uint8_t speed; + volatile uint8_t setup_count; uint8_t itf2drv[CFG_TUD_INTERFACE_MAX]; // map interface number to driver (0xff is invalid) uint8_t ep2drv[CFG_TUD_ENDPPOINT_MAX][2]; // map endpoint to driver ( 0xff is invalid ), can use only 4-bit each @@ -79,157 +90,168 @@ tu_static usbd_device_t _usbd_dev; // Class Driver //--------------------------------------------------------------------+ #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL - #define DRIVER_NAME(_name) .name = _name, + #define DRIVER_NAME(_name) _name #else - #define DRIVER_NAME(_name) + #define DRIVER_NAME(_name) NULL #endif // Built-in class drivers -tu_static usbd_class_driver_t const _usbd_driver[] = -{ - #if CFG_TUD_CDC - { - DRIVER_NAME("CDC") - .init = cdcd_init, - .reset = cdcd_reset, - .open = cdcd_open, - .control_xfer_cb = cdcd_control_xfer_cb, - .xfer_cb = cdcd_xfer_cb, - .sof = NULL - }, - #endif +tu_static usbd_class_driver_t const _usbd_driver[] = { + #if CFG_TUD_CDC + { + .name = DRIVER_NAME("CDC"), + .init = cdcd_init, + .deinit = cdcd_deinit, + .reset = cdcd_reset, + .open = cdcd_open, + .control_xfer_cb = cdcd_control_xfer_cb, + .xfer_cb = cdcd_xfer_cb, + .sof = NULL + }, + #endif - #if CFG_TUD_MSC - { - DRIVER_NAME("MSC") - .init = mscd_init, - .reset = mscd_reset, - .open = mscd_open, - .control_xfer_cb = mscd_control_xfer_cb, - .xfer_cb = mscd_xfer_cb, - .sof = NULL - }, - #endif + #if CFG_TUD_MSC + { + .name = DRIVER_NAME("MSC"), + .init = mscd_init, + .deinit = NULL, + .reset = mscd_reset, + .open = mscd_open, + .control_xfer_cb = mscd_control_xfer_cb, + .xfer_cb = mscd_xfer_cb, + .sof = NULL + }, + #endif - #if CFG_TUD_HID - { - DRIVER_NAME("HID") - .init = hidd_init, - .reset = hidd_reset, - .open = hidd_open, - .control_xfer_cb = hidd_control_xfer_cb, - .xfer_cb = hidd_xfer_cb, - .sof = NULL - }, - #endif + #if CFG_TUD_HID + { + .name = DRIVER_NAME("HID"), + .init = hidd_init, + .deinit = hidd_deinit, + .reset = hidd_reset, + .open = hidd_open, + .control_xfer_cb = hidd_control_xfer_cb, + .xfer_cb = hidd_xfer_cb, + .sof = NULL + }, + #endif - #if CFG_TUD_AUDIO - { - DRIVER_NAME("AUDIO") - .init = audiod_init, - .reset = audiod_reset, - .open = audiod_open, - .control_xfer_cb = audiod_control_xfer_cb, - .xfer_cb = audiod_xfer_cb, - .sof = audiod_sof_isr - }, - #endif + #if CFG_TUD_AUDIO + { + .name = DRIVER_NAME("AUDIO"), + .init = audiod_init, + .deinit = audiod_deinit, + .reset = audiod_reset, + .open = audiod_open, + .control_xfer_cb = audiod_control_xfer_cb, + .xfer_cb = audiod_xfer_cb, + .sof = audiod_sof_isr + }, + #endif - #if CFG_TUD_VIDEO - { - DRIVER_NAME("VIDEO") - .init = videod_init, - .reset = videod_reset, - .open = videod_open, - .control_xfer_cb = videod_control_xfer_cb, - .xfer_cb = videod_xfer_cb, - .sof = NULL - }, - #endif + #if CFG_TUD_VIDEO + { + .name = DRIVER_NAME("VIDEO"), + .init = videod_init, + .deinit = videod_deinit, + .reset = videod_reset, + .open = videod_open, + .control_xfer_cb = videod_control_xfer_cb, + .xfer_cb = videod_xfer_cb, + .sof = NULL + }, + #endif - #if CFG_TUD_MIDI - { - DRIVER_NAME("MIDI") - .init = midid_init, - .open = midid_open, - .reset = midid_reset, - .control_xfer_cb = midid_control_xfer_cb, - .xfer_cb = midid_xfer_cb, - .sof = NULL - }, - #endif + #if CFG_TUD_MIDI + { + .name = DRIVER_NAME("MIDI"), + .init = midid_init, + .deinit = midid_deinit, + .open = midid_open, + .reset = midid_reset, + .control_xfer_cb = midid_control_xfer_cb, + .xfer_cb = midid_xfer_cb, + .sof = NULL + }, + #endif - #if CFG_TUD_VENDOR - { - DRIVER_NAME("VENDOR") - .init = vendord_init, - .reset = vendord_reset, - .open = vendord_open, - .control_xfer_cb = tud_vendor_control_xfer_cb, - .xfer_cb = vendord_xfer_cb, - .sof = NULL - }, - #endif + #if CFG_TUD_VENDOR + { + .name = DRIVER_NAME("VENDOR"), + .init = vendord_init, + .deinit = vendord_deinit, + .reset = vendord_reset, + .open = vendord_open, + .control_xfer_cb = tud_vendor_control_xfer_cb, + .xfer_cb = vendord_xfer_cb, + .sof = NULL + }, + #endif - #if CFG_TUD_USBTMC - { - DRIVER_NAME("TMC") - .init = usbtmcd_init_cb, - .reset = usbtmcd_reset_cb, - .open = usbtmcd_open_cb, - .control_xfer_cb = usbtmcd_control_xfer_cb, - .xfer_cb = usbtmcd_xfer_cb, - .sof = NULL - }, - #endif + #if CFG_TUD_USBTMC + { + .name = DRIVER_NAME("TMC"), + .init = usbtmcd_init_cb, + .deinit = usbtmcd_deinit, + .reset = usbtmcd_reset_cb, + .open = usbtmcd_open_cb, + .control_xfer_cb = usbtmcd_control_xfer_cb, + .xfer_cb = usbtmcd_xfer_cb, + .sof = NULL + }, + #endif - #if CFG_TUD_DFU_RUNTIME - { - DRIVER_NAME("DFU-RUNTIME") - .init = dfu_rtd_init, - .reset = dfu_rtd_reset, - .open = dfu_rtd_open, - .control_xfer_cb = dfu_rtd_control_xfer_cb, - .xfer_cb = NULL, - .sof = NULL - }, - #endif + #if CFG_TUD_DFU_RUNTIME + { + .name = DRIVER_NAME("DFU-RUNTIME"), + .init = dfu_rtd_init, + .deinit = dfu_rtd_deinit, + .reset = dfu_rtd_reset, + .open = dfu_rtd_open, + .control_xfer_cb = dfu_rtd_control_xfer_cb, + .xfer_cb = NULL, + .sof = NULL + }, + #endif - #if CFG_TUD_DFU - { - DRIVER_NAME("DFU") - .init = dfu_moded_init, - .reset = dfu_moded_reset, - .open = dfu_moded_open, - .control_xfer_cb = dfu_moded_control_xfer_cb, - .xfer_cb = NULL, - .sof = NULL - }, - #endif + #if CFG_TUD_DFU + { + .name = DRIVER_NAME("DFU"), + .init = dfu_moded_init, + .deinit = dfu_moded_deinit, + .reset = dfu_moded_reset, + .open = dfu_moded_open, + .control_xfer_cb = dfu_moded_control_xfer_cb, + .xfer_cb = NULL, + .sof = NULL + }, + #endif - #if CFG_TUD_ECM_RNDIS || CFG_TUD_NCM - { - DRIVER_NAME("NET") - .init = netd_init, - .reset = netd_reset, - .open = netd_open, - .control_xfer_cb = netd_control_xfer_cb, - .xfer_cb = netd_xfer_cb, - .sof = NULL, - }, - #endif + #if CFG_TUD_ECM_RNDIS || CFG_TUD_NCM + { + .name = DRIVER_NAME("NET"), + .init = netd_init, + .deinit = netd_deinit, + .reset = netd_reset, + .open = netd_open, + .control_xfer_cb = netd_control_xfer_cb, + .xfer_cb = netd_xfer_cb, + .sof = NULL, + }, + #endif - #if CFG_TUD_BTH - { - DRIVER_NAME("BTH") - .init = btd_init, - .reset = btd_reset, - .open = btd_open, - .control_xfer_cb = btd_control_xfer_cb, - .xfer_cb = btd_xfer_cb, - .sof = NULL - }, - #endif + #if CFG_TUD_BTH + { + .name = DRIVER_NAME("BTH"), + .init = btd_init, + .deinit = btd_deinit, + .reset = btd_reset, + .open = btd_open, + .control_xfer_cb = btd_control_xfer_cb, + .xfer_cb = btd_xfer_cb, + .sof = NULL + }, + #endif }; enum { BUILTIN_DRIVER_COUNT = TU_ARRAY_SIZE(_usbd_driver) }; @@ -238,35 +260,21 @@ enum { BUILTIN_DRIVER_COUNT = TU_ARRAY_SIZE(_usbd_driver) }; tu_static usbd_class_driver_t const * _app_driver = NULL; tu_static uint8_t _app_driver_count = 0; +#define TOTAL_DRIVER_COUNT (_app_driver_count + BUILTIN_DRIVER_COUNT) + // virtually joins built-in and application drivers together. // Application is positioned first to allow overwriting built-in ones. -static inline usbd_class_driver_t const * get_driver(uint8_t drvid) -{ - // Application drivers - if ( usbd_app_driver_get_cb ) - { - if ( drvid < _app_driver_count ) return &_app_driver[drvid]; - drvid -= _app_driver_count; +TU_ATTR_ALWAYS_INLINE static inline usbd_class_driver_t const * get_driver(uint8_t drvid) { + usbd_class_driver_t const * driver = NULL; + if ( drvid < _app_driver_count ) { + // Application drivers + driver = &_app_driver[drvid]; + } else if ( drvid < TOTAL_DRIVER_COUNT && BUILTIN_DRIVER_COUNT > 0 ){ + driver = &_usbd_driver[drvid - _app_driver_count]; } - - // when there is no built-in drivers BUILTIN_DRIVER_COUNT = 0 will cause -Wtype-limits warning -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wtype-limits" -#endif - - // Built-in drivers - if (drvid < BUILTIN_DRIVER_COUNT) return &_usbd_driver[drvid]; - -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif - - return NULL; + return driver; } -#define TOTAL_DRIVER_COUNT (_app_driver_count + BUILTIN_DRIVER_COUNT) - typedef struct { union @@ -302,6 +310,11 @@ tu_static osal_queue_t _usbd_q; #define _usbd_mutex NULL #endif +TU_ATTR_ALWAYS_INLINE static inline bool queue_event(dcd_event_t const * event, bool in_isr) { + TU_ASSERT(osal_queue_send(_usbd_q, event, in_isr)); + tud_event_hook_cb(event->rhport, event->event_id, in_isr); + return true; +} //--------------------------------------------------------------------+ // Prototypes @@ -321,28 +334,24 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, // Debug //--------------------------------------------------------------------+ #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL -tu_static char const* const _usbd_event_str[DCD_EVENT_COUNT] = -{ - "Invalid" , - "Bus Reset" , - "Unplugged" , - "SOF" , - "Suspend" , - "Resume" , - "Setup Received" , - "Xfer Complete" , - "Func Call" +tu_static char const* const _usbd_event_str[DCD_EVENT_COUNT] = { + "Invalid", + "Bus Reset", + "Unplugged", + "SOF", + "Suspend", + "Resume", + "Setup Received", + "Xfer Complete", + "Func Call" }; // for usbd_control to print the name of control complete driver -void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback) -{ - for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) - { - usbd_class_driver_t const * driver = get_driver(i); - if ( driver && driver->control_xfer_cb == callback ) - { - TU_LOG_USBD(" %s control complete\r\n", driver->name); +void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback) { + for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { + usbd_class_driver_t const* driver = get_driver(i); + if (driver && driver->control_xfer_cb == callback) { + TU_LOG_USBD("%s control complete\r\n", driver->name); return; } } @@ -353,43 +362,36 @@ void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback) //--------------------------------------------------------------------+ // Application API //--------------------------------------------------------------------+ -tusb_speed_t tud_speed_get(void) -{ +tusb_speed_t tud_speed_get(void) { return (tusb_speed_t) _usbd_dev.speed; } -bool tud_connected(void) -{ +bool tud_connected(void) { return _usbd_dev.connected; } -bool tud_mounted(void) -{ +bool tud_mounted(void) { return _usbd_dev.cfg_num ? true : false; } -bool tud_suspended(void) -{ +bool tud_suspended(void) { return _usbd_dev.suspended; } -bool tud_remote_wakeup(void) -{ +bool tud_remote_wakeup(void) { // only wake up host if this feature is supported and enabled and we are suspended - TU_VERIFY (_usbd_dev.suspended && _usbd_dev.remote_wakeup_support && _usbd_dev.remote_wakeup_en ); + TU_VERIFY (_usbd_dev.suspended && _usbd_dev.remote_wakeup_support && _usbd_dev.remote_wakeup_en); dcd_remote_wakeup(_usbd_rhport); return true; } -bool tud_disconnect(void) -{ +bool tud_disconnect(void) { TU_VERIFY(dcd_disconnect); dcd_disconnect(_usbd_rhport); return true; } -bool tud_connect(void) -{ +bool tud_connect(void) { TU_VERIFY(dcd_connect); dcd_connect(_usbd_rhport); return true; @@ -405,18 +407,17 @@ bool tud_sof_cb_enable(bool en) //--------------------------------------------------------------------+ // USBD Task //--------------------------------------------------------------------+ -bool tud_inited(void) -{ +bool tud_inited(void) { return _usbd_rhport != RHPORT_INVALID; } -bool tud_init (uint8_t rhport) -{ +bool tud_init(uint8_t rhport) { // skip if already initialized - if ( tud_inited() ) return true; + if (tud_inited()) return true; 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(dcd_event_t)); TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(tu_fifo_t)); TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(tu_edpt_stream_t)); @@ -433,16 +434,14 @@ bool tud_init (uint8_t rhport) TU_ASSERT(_usbd_q); // Get application driver if available - if ( usbd_app_driver_get_cb ) - { + if (usbd_app_driver_get_cb) { _app_driver = usbd_app_driver_get_cb(&_app_driver_count); } // Init class drivers - for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) - { - usbd_class_driver_t const * driver = get_driver(i); - TU_ASSERT(driver); + for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { + usbd_class_driver_t const* driver = get_driver(i); + TU_ASSERT(driver && driver->init); TU_LOG_USBD("%s init\r\n", driver->name); driver->init(); } @@ -456,31 +455,61 @@ bool tud_init (uint8_t rhport) return true; } -static void configuration_reset(uint8_t rhport) -{ - for ( uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++ ) - { - usbd_class_driver_t const * driver = get_driver(i); - TU_ASSERT(driver, ); +bool tud_deinit(uint8_t rhport) { + // skip if not initialized + if (!tud_inited()) return true; + + TU_LOG_USBD("USBD deinit on controller %u\r\n", rhport); + + // Deinit device controller driver + dcd_int_disable(rhport); + dcd_disconnect(rhport); + dcd_deinit(rhport); + + // Deinit class drivers + for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { + usbd_class_driver_t const* driver = get_driver(i); + if(driver && driver->deinit) { + TU_LOG_USBD("%s deinit\r\n", driver->name); + driver->deinit(); + } + } + + // Deinit device queue & task + osal_queue_delete(_usbd_q); + _usbd_q = NULL; + +#if OSAL_MUTEX_REQUIRED + // TODO make sure there is no task waiting on this mutex + osal_mutex_delete(_usbd_mutex); + _usbd_mutex = NULL; +#endif + + _usbd_rhport = RHPORT_INVALID; + + return true; +} + +static void configuration_reset(uint8_t rhport) { + for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { + usbd_class_driver_t const* driver = get_driver(i); + TU_ASSERT(driver,); driver->reset(rhport); } tu_varclr(&_usbd_dev); memset(_usbd_dev.itf2drv, DRVID_INVALID, sizeof(_usbd_dev.itf2drv)); // invalid mapping - memset(_usbd_dev.ep2drv , DRVID_INVALID, sizeof(_usbd_dev.ep2drv )); // invalid mapping + memset(_usbd_dev.ep2drv, DRVID_INVALID, sizeof(_usbd_dev.ep2drv)); // invalid mapping } -static void usbd_reset(uint8_t rhport) -{ +static void usbd_reset(uint8_t rhport) { configuration_reset(rhport); usbd_control_reset(); } -bool tud_task_event_ready(void) -{ +bool tud_task_event_ready(void) { // Skip if stack is not initialized - if ( !tud_inited() ) return false; - + if (!tud_inited()) return false; return !osal_queue_empty(_usbd_q); } @@ -488,57 +517,52 @@ bool tud_task_event_ready(void) * This top level thread manages all device controller event and delegates events to class-specific drivers. * This should be called periodically within the mainloop or rtos thread. * - @code - int main(void) - { + int main(void) { application_init(); tusb_init(); - while(1) // the mainloop - { + while(1) { // the mainloop application_code(); tud_task(); // tinyusb device task } } - @endcode */ -void tud_task_ext(uint32_t timeout_ms, bool in_isr) -{ +void tud_task_ext(uint32_t timeout_ms, bool in_isr) { (void) in_isr; // not implemented yet // Skip if stack is not initialized - if ( !tud_inited() ) return; + if (!tud_inited()) return; // Loop until there is no more events in the queue - while (1) - { + while (1) { dcd_event_t event; - if ( !osal_queue_receive(_usbd_q, &event, timeout_ms) ) return; + if (!osal_queue_receive(_usbd_q, &event, timeout_ms)) return; #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 ) - { + switch (event.event_id) { case DCD_EVENT_BUS_RESET: 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; + break; case DCD_EVENT_UNPLUGGED: TU_LOG_USBD("\r\n"); usbd_reset(event.rhport); - - // invoke callback if (tud_umount_cb) tud_umount_cb(); - break; + break; case DCD_EVENT_SETUP_RECEIVED: - TU_LOG_PTR(CFG_TUD_LOG_LEVEL, &event.setup_received); - TU_LOG_USBD("\r\n"); + _usbd_dev.setup_count--; + TU_LOG_BUF(CFG_TUD_LOG_LEVEL, &event.setup_received, 8); + if (_usbd_dev.setup_count) { + TU_LOG_USBD(" Skipped since there is other SETUP in queue\r\n"); + break; + } // 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 @@ -547,76 +571,67 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) // mark both in & out control as free _usbd_dev.ep_status[0][TUSB_DIR_OUT].busy = 0; _usbd_dev.ep_status[0][TUSB_DIR_OUT].claimed = 0; - _usbd_dev.ep_status[0][TUSB_DIR_IN ].busy = 0; - _usbd_dev.ep_status[0][TUSB_DIR_IN ].claimed = 0; + _usbd_dev.ep_status[0][TUSB_DIR_IN].busy = 0; + _usbd_dev.ep_status[0][TUSB_DIR_IN].claimed = 0; // Process control request - if ( !process_control_request(event.rhport, &event.setup_received) ) - { + if (!process_control_request(event.rhport, &event.setup_received)) { 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); } - break; + break; - case DCD_EVENT_XFER_COMPLETE: - { + case DCD_EVENT_XFER_COMPLETE: { // Invoke the class callback associated with the endpoint address uint8_t const ep_addr = event.xfer_complete.ep_addr; - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const ep_dir = tu_edpt_dir(ep_addr); + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const ep_dir = tu_edpt_dir(ep_addr); 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; - if ( 0 == epnum ) - { - usbd_control_xfer_cb(event.rhport, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete - .len); - } - else - { - usbd_class_driver_t const * driver = get_driver( _usbd_dev.ep2drv[epnum][ep_dir] ); - TU_ASSERT(driver, ); + if (0 == epnum) { + usbd_control_xfer_cb(event.rhport, ep_addr, (xfer_result_t) event.xfer_complete.result, + event.xfer_complete.len); + } else { + usbd_class_driver_t const* driver = get_driver(_usbd_dev.ep2drv[epnum][ep_dir]); + TU_ASSERT(driver,); 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); } + break; } - break; case DCD_EVENT_SUSPEND: // NOTE: When plugging/unplugging device, the D+/D- state are unstable and // can accidentally meet the SUSPEND condition ( Bus Idle for 3ms ), which result in a series of event // e.g suspend -> resume -> unplug/plug. Skip suspend/resume if not connected - if ( _usbd_dev.connected ) - { + if (_usbd_dev.connected) { TU_LOG_USBD(": Remote Wakeup = %u\r\n", _usbd_dev.remote_wakeup_en); if (tud_suspend_cb) tud_suspend_cb(_usbd_dev.remote_wakeup_en); - }else - { + } else { TU_LOG_USBD(" Skipped\r\n"); } - break; + break; case DCD_EVENT_RESUME: - if ( _usbd_dev.connected ) - { + if (_usbd_dev.connected) { TU_LOG_USBD("\r\n"); if (tud_resume_cb) tud_resume_cb(); - }else - { + } else { TU_LOG_USBD(" Skipped\r\n"); } - break; + break; case USBD_EVENT_FUNC_CALL: TU_LOG_USBD("\r\n"); - if ( event.func_call.func ) event.func_call.func(event.func_call.param); - break; + if (event.func_call.func) event.func_call.func(event.func_call.param); + break; case DCD_EVENT_SOF: if ( _usbd_sof.cb_en) @@ -628,7 +643,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) default: TU_BREAKPOINT(); - break; + break; } #if CFG_TUSB_OS != OPT_OS_NONE && CFG_TUSB_OS != OPT_OS_PICO @@ -643,24 +658,20 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) //--------------------------------------------------------------------+ // Helper to invoke class driver control request handler -static bool invoke_class_control(uint8_t rhport, usbd_class_driver_t const * driver, tusb_control_request_t const * request) -{ +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(" %s control request\r\n", driver->name); return driver->control_xfer_cb(rhport, CONTROL_STAGE_SETUP, request); } // This handles the actual request and its response. -// return false will cause its caller to stall control endpoint -static bool process_control_request(uint8_t rhport, tusb_control_request_t const * p_request) -{ +// Returns false if unable to complete the request, causing caller to stall control endpoints. +static bool process_control_request(uint8_t rhport, tusb_control_request_t const * p_request) { usbd_control_set_complete_callback(NULL); - TU_ASSERT(p_request->bmRequestType_bit.type < TUSB_REQ_TYPE_INVALID); // Vendor request - if ( p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_VENDOR ) - { + if ( p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_VENDOR ) { TU_VERIFY(tud_vendor_control_xfer_cb); usbd_control_set_complete_callback(tud_vendor_control_xfer_cb); @@ -668,19 +679,16 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const } #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) - { + if (TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type && p_request->bRequest <= TUSB_REQ_SYNCH_FRAME) { 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 - switch ( p_request->bmRequestType_bit.recipient ) - { + switch ( p_request->bmRequestType_bit.recipient ) { //------------- Device Requests e.g in enumeration -------------// case TUSB_REQ_RCPT_DEVICE: - if ( TUSB_REQ_TYPE_CLASS == p_request->bmRequestType_bit.type ) - { + if ( TUSB_REQ_TYPE_CLASS == p_request->bmRequestType_bit.type ) { uint8_t const itf = tu_u16_low(p_request->wIndex); TU_VERIFY(itf < TU_ARRAY_SIZE(_usbd_dev.itf2drv)); @@ -691,15 +699,13 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const return invoke_class_control(rhport, driver, p_request); } - if ( TUSB_REQ_TYPE_STANDARD != p_request->bmRequestType_bit.type ) - { + if ( TUSB_REQ_TYPE_STANDARD != p_request->bmRequestType_bit.type ) { // Non standard request is not supported TU_BREAKPOINT(); return false; } - switch ( p_request->bRequest ) - { + switch ( p_request->bRequest ) { case TUSB_REQ_SET_ADDRESS: // Depending on mcu, status phase could be sent either before or after changing device address, // or even require stack to not response with status at all @@ -710,22 +716,18 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const _usbd_dev.addressed = 1; break; - case TUSB_REQ_GET_CONFIGURATION: - { + case TUSB_REQ_GET_CONFIGURATION: { uint8_t cfg_num = _usbd_dev.cfg_num; tud_control_xfer(rhport, p_request, &cfg_num, 1); } break; - case TUSB_REQ_SET_CONFIGURATION: - { + case TUSB_REQ_SET_CONFIGURATION: { uint8_t const cfg_num = (uint8_t) p_request->wValue; // Only process if new configure is different - if (_usbd_dev.cfg_num != cfg_num) - { - if ( _usbd_dev.cfg_num ) - { + if (_usbd_dev.cfg_num != cfg_num) { + if ( _usbd_dev.cfg_num ) { // already configured: need to clear all endpoints and driver first TU_LOG_USBD(" Clear current Configuration (%u) before switching\r\n", _usbd_dev.cfg_num); @@ -739,8 +741,14 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const _usbd_dev.speed = speed; // restore speed } - // switch to new configuration if not zero - if ( cfg_num ) TU_ASSERT( process_set_config(rhport, cfg_num) ); + // Handle the new configuration and execute the corresponding callback + if ( cfg_num ) { + // switch to new configuration if not zero + TU_ASSERT( process_set_config(rhport, cfg_num) ); + if ( tud_mount_cb ) tud_mount_cb(); + } else { + if ( tud_umount_cb ) tud_umount_cb(); + } } _usbd_dev.cfg_num = cfg_num; @@ -774,15 +782,14 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const tud_control_status(rhport, p_request); break; - case TUSB_REQ_GET_STATUS: - { + case TUSB_REQ_GET_STATUS: { // Device status bit mask // - Bit 0: Self Powered // - Bit 1: Remote Wakeup enabled uint16_t status = (uint16_t) ((_usbd_dev.self_powered ? 1u : 0u) | (_usbd_dev.remote_wakeup_en ? 2u : 0u)); tud_control_xfer(rhport, p_request, &status, 2); + break; } - break; // Unknown/Unsupported request default: TU_BREAKPOINT(); return false; @@ -790,8 +797,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const break; //------------- Class/Interface Specific Request -------------// - case TUSB_REQ_RCPT_INTERFACE: - { + case TUSB_REQ_RCPT_INTERFACE: { uint8_t const itf = tu_u16_low(p_request->wIndex); TU_VERIFY(itf < TU_ARRAY_SIZE(_usbd_dev.itf2drv)); @@ -800,25 +806,21 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const // all requests to Interface (STD or Class) is forwarded to class driver. // notable requests are: GET HID REPORT DESCRIPTOR, SET_INTERFACE, GET_INTERFACE - if ( !invoke_class_control(rhport, driver, p_request) ) - { + if ( !invoke_class_control(rhport, driver, p_request) ) { // For GET_INTERFACE and SET_INTERFACE, it is mandatory to respond even if the class // driver doesn't use alternate settings or implement this TU_VERIFY(TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type); - switch(p_request->bRequest) - { + switch(p_request->bRequest) { case TUSB_REQ_GET_INTERFACE: case TUSB_REQ_SET_INTERFACE: // Clear complete callback if driver set since it can also stall the request. usbd_control_set_complete_callback(NULL); - if (TUSB_REQ_GET_INTERFACE == p_request->bRequest) - { + if (TUSB_REQ_GET_INTERFACE == p_request->bRequest) { uint8_t alternate = 0; tud_control_xfer(rhport, p_request, &alternate, 1); - }else - { + }else { tud_control_status(rhport, p_request); } break; @@ -826,54 +828,42 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const default: return false; } } + break; } - break; //------------- Endpoint Request -------------// - case TUSB_REQ_RCPT_ENDPOINT: - { + case TUSB_REQ_RCPT_ENDPOINT: { uint8_t const ep_addr = tu_u16_low(p_request->wIndex); uint8_t const ep_num = tu_edpt_number(ep_addr); uint8_t const ep_dir = tu_edpt_dir(ep_addr); TU_ASSERT(ep_num < TU_ARRAY_SIZE(_usbd_dev.ep2drv) ); - usbd_class_driver_t const * driver = get_driver(_usbd_dev.ep2drv[ep_num][ep_dir]); - if ( TUSB_REQ_TYPE_STANDARD != p_request->bmRequestType_bit.type ) - { + if ( TUSB_REQ_TYPE_STANDARD != p_request->bmRequestType_bit.type ) { // Forward class request to its driver TU_VERIFY(driver); return invoke_class_control(rhport, driver, p_request); - } - else - { + } else { // Handle STD request to endpoint - switch ( p_request->bRequest ) - { - case TUSB_REQ_GET_STATUS: - { + switch ( p_request->bRequest ) { + case TUSB_REQ_GET_STATUS: { uint16_t status = usbd_edpt_stalled(rhport, ep_addr) ? 0x0001 : 0x0000; tud_control_xfer(rhport, p_request, &status, 2); } break; case TUSB_REQ_CLEAR_FEATURE: - case TUSB_REQ_SET_FEATURE: - { - if ( TUSB_REQ_FEATURE_EDPT_HALT == p_request->wValue ) - { - if ( TUSB_REQ_CLEAR_FEATURE == p_request->bRequest ) - { + case TUSB_REQ_SET_FEATURE: { + if ( TUSB_REQ_FEATURE_EDPT_HALT == p_request->wValue ) { + if ( TUSB_REQ_CLEAR_FEATURE == p_request->bRequest ) { usbd_edpt_clear_stall(rhport, ep_addr); - }else - { + }else { usbd_edpt_stall(rhport, ep_addr); } } - if (driver) - { + if (driver) { // Some classes such as USBTMC needs to clear/re-init its buffer when receiving CLEAR_FEATURE request // We will also forward std request targeted endpoint to class drivers as well @@ -889,14 +879,18 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const break; // Unknown/Unsupported request - default: TU_BREAKPOINT(); return false; + default: + TU_BREAKPOINT(); + return false; } } } break; // Unknown recipient - default: TU_BREAKPOINT(); return false; + default: + TU_BREAKPOINT(); + return false; } return true; @@ -993,9 +987,6 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num) TU_ASSERT(drv_id < TOTAL_DRIVER_COUNT); } - // invoke callback - if (tud_mount_cb) tud_mount_cb(); - return true; } @@ -1108,66 +1099,69 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const //--------------------------------------------------------------------+ // DCD Event Handler //--------------------------------------------------------------------+ -TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const * event, bool in_isr) -{ - switch (event->event_id) - { +TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const* event, bool in_isr) { + bool send = false; + switch (event->event_id) { case DCD_EVENT_UNPLUGGED: - _usbd_dev.connected = 0; - _usbd_dev.addressed = 0; - _usbd_dev.cfg_num = 0; - _usbd_dev.suspended = 0; - osal_queue_send(_usbd_q, event, in_isr); - break; + _usbd_dev.connected = 0; + _usbd_dev.addressed = 0; + _usbd_dev.cfg_num = 0; + _usbd_dev.suspended = 0; + send = true; + break; case DCD_EVENT_SUSPEND: // NOTE: When plugging/unplugging device, the D+/D- state are unstable and // can accidentally meet the SUSPEND condition ( Bus Idle for 3ms ). // In addition, some MCUs such as SAMD or boards that haven no VBUS detection cannot distinguish // suspended vs disconnected. We will skip handling SUSPEND/RESUME event if not currently connected - if ( _usbd_dev.connected ) - { + if (_usbd_dev.connected) { _usbd_dev.suspended = 1; - osal_queue_send(_usbd_q, event, in_isr); + send = true; } - break; + break; case DCD_EVENT_RESUME: // skip event if not connected (especially required for SAMD) - if ( _usbd_dev.connected ) - { + if (_usbd_dev.connected) { _usbd_dev.suspended = 0; - osal_queue_send(_usbd_q, event, in_isr); + send = true; } - break; + break; case DCD_EVENT_SOF: + // Some MCUs after running dcd_remote_wakeup() does not have way to detect the end of remote wakeup + // which last 1-15 ms. DCD can use SOF as a clear indicator that bus is back to operational + if (_usbd_dev.suspended) { + _usbd_dev.suspended = 0; + + dcd_event_t const event_resume = {.rhport = event->rhport, .event_id = DCD_EVENT_RESUME}; + queue_event(&event_resume, in_isr); + } + // SOF driver handler in ISR context - for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) - { - usbd_class_driver_t const * driver = get_driver(i); - if (driver && driver->sof) - { + for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { + usbd_class_driver_t const* driver = get_driver(i); + if (driver && driver->sof) { driver->sof(event->rhport, event->sof.frame_count); } } - // Some MCUs after running dcd_remote_wakeup() does not have way to detect the end of remote wakeup - // which last 1-15 ms. DCD can use SOF as a clear indicator that bus is back to operational - if ( _usbd_dev.suspended ) - { - _usbd_dev.suspended = 0; - - dcd_event_t const event_resume = { .rhport = event->rhport, .event_id = DCD_EVENT_RESUME }; - osal_queue_send(_usbd_q, &event_resume, in_isr); - } - // skip osal queue for SOF in usbd task - break; + break; + + case DCD_EVENT_SETUP_RECEIVED: + _usbd_dev.setup_count++; + send = true; + break; default: - osal_queue_send(_usbd_q, event, in_isr); - break; + send = true; + break; + } + + if (send) { + queue_event(event, in_isr); } } @@ -1211,26 +1205,22 @@ bool usbd_open_edpt_pair(uint8_t rhport, uint8_t const* p_desc, uint8_t ep_count } // Helper to defer an isr function -void usbd_defer_func(osal_task_func_t func, void* param, bool in_isr) -{ - dcd_event_t event = - { +void usbd_defer_func(osal_task_func_t func, void* param, bool in_isr) { + dcd_event_t event = { .rhport = 0, .event_id = USBD_EVENT_FUNC_CALL, }; - event.func_call.func = func; event.func_call.param = param; - dcd_event_handler(&event, in_isr); + queue_event(&event, in_isr); } //--------------------------------------------------------------------+ // USBD Endpoint API //--------------------------------------------------------------------+ -bool usbd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) -{ +bool usbd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const* desc_ep) { rhport = _usbd_rhport; TU_ASSERT(tu_edpt_number(desc_ep->bEndpointAddress) < CFG_TUD_ENDPPOINT_MAX); @@ -1239,42 +1229,44 @@ bool usbd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) return dcd_edpt_open(rhport, desc_ep); } -bool usbd_edpt_claim(uint8_t rhport, uint8_t ep_addr) -{ +bool usbd_edpt_claim(uint8_t rhport, uint8_t ep_addr) { (void) rhport; // TODO add this check later, also make sure we don't starve an out endpoint while suspending // TU_VERIFY(tud_ready()); - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); tu_edpt_state_t* ep_state = &_usbd_dev.ep_status[epnum][dir]; return tu_edpt_claim(ep_state, _usbd_mutex); } -bool usbd_edpt_release(uint8_t rhport, uint8_t ep_addr) -{ +bool usbd_edpt_release(uint8_t rhport, uint8_t ep_addr) { (void) rhport; - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); tu_edpt_state_t* ep_state = &_usbd_dev.ep_status[epnum][dir]; return tu_edpt_release(ep_state, _usbd_mutex); } -bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) -{ +bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) { rhport = _usbd_rhport; uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); // TODO skip ready() check for now since enumeration also use this API // TU_VERIFY(tud_ready()); TU_LOG_USBD(" Queue EP %02X with %u bytes ...\r\n", ep_addr, total_bytes); +#if CFG_TUD_LOG_LEVEL >= 3 + if(dir == TUSB_DIR_IN) { + TU_LOG_MEM(CFG_TUD_LOG_LEVEL, buffer, total_bytes, 2); + } +#endif // Attempt to transfer on a busy endpoint, sound like an race condition ! TU_ASSERT(_usbd_dev.ep_status[epnum][dir].busy == 0); @@ -1283,11 +1275,9 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t // could return and USBD task can preempt and clear the busy _usbd_dev.ep_status[epnum][dir].busy = 1; - if ( dcd_edpt_xfer(rhport, ep_addr, buffer, total_bytes) ) - { + if (dcd_edpt_xfer(rhport, ep_addr, buffer, total_bytes)) { return true; - }else - { + } 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; @@ -1301,12 +1291,11 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t // bytes should be written and second to keep the return value free to give back a boolean // success message. If total_bytes is too big, the FIFO will copy only what is available // into the USB buffer! -bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) -{ +bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_t total_bytes) { rhport = _usbd_rhport; uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); TU_LOG_USBD(" Queue ISO EP %02X with %u bytes ... ", ep_addr, total_bytes); @@ -1317,12 +1306,10 @@ bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16 // and usbd task can preempt and clear the busy _usbd_dev.ep_status[epnum][dir].busy = 1; - if (dcd_edpt_xfer_fifo(rhport, ep_addr, ff, total_bytes)) - { + if (dcd_edpt_xfer_fifo(rhport, ep_addr, ff, total_bytes)) { TU_LOG_USBD("OK\r\n"); return true; - }else - { + } 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; @@ -1332,75 +1319,62 @@ bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16 } } -bool usbd_edpt_busy(uint8_t rhport, uint8_t ep_addr) -{ +bool usbd_edpt_busy(uint8_t rhport, uint8_t ep_addr) { (void) rhport; uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); return _usbd_dev.ep_status[epnum][dir].busy; } -void usbd_edpt_stall(uint8_t rhport, uint8_t ep_addr) -{ +void usbd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { rhport = _usbd_rhport; uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); // only stalled if currently cleared - if ( !_usbd_dev.ep_status[epnum][dir].stalled ) - { - 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; - } + 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; } -void usbd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) -{ +void usbd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { rhport = _usbd_rhport; uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); // only clear if currently stalled - if ( _usbd_dev.ep_status[epnum][dir].stalled ) - { - 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; - } + 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; } -bool usbd_edpt_stalled(uint8_t rhport, uint8_t ep_addr) -{ +bool usbd_edpt_stalled(uint8_t rhport, uint8_t ep_addr) { (void) rhport; uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); return _usbd_dev.ep_status[epnum][dir].stalled; } /** * usbd_edpt_close will disable an endpoint. - * * In progress transfers on this EP may be delivered after this call. - * */ -void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr) -{ +void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr) { rhport = _usbd_rhport; TU_ASSERT(dcd_edpt_close, /**/); 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); + uint8_t const dir = tu_edpt_dir(ep_addr); dcd_edpt_close(rhport, ep_addr); _usbd_dev.ep_status[epnum][dir].stalled = 0; @@ -1410,8 +1384,7 @@ void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr) return; } -void usbd_sof_enable(uint8_t rhport, bool en) -{ +void usbd_sof_enable(uint8_t rhport, bool en) { rhport = _usbd_rhport; // Keep track how many class instances need the SOF interrupt @@ -1428,8 +1401,7 @@ void usbd_sof_enable(uint8_t rhport, bool en) dcd_sof_enable(rhport, _usbd_sof.value ? true : false); } -bool usbd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) -{ +bool usbd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { rhport = _usbd_rhport; TU_ASSERT(dcd_edpt_iso_alloc); @@ -1438,12 +1410,11 @@ bool usbd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packe return dcd_edpt_iso_alloc(rhport, ep_addr, largest_packet_size); } -bool usbd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) -{ +bool usbd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const* desc_ep) { rhport = _usbd_rhport; uint8_t const epnum = tu_edpt_number(desc_ep->bEndpointAddress); - uint8_t const dir = tu_edpt_dir(desc_ep->bEndpointAddress); + uint8_t const dir = tu_edpt_dir(desc_ep->bEndpointAddress); TU_ASSERT(dcd_edpt_iso_activate); TU_ASSERT(epnum < CFG_TUD_ENDPPOINT_MAX); diff --git a/src/device/usbd.h b/src/device/usbd.h index 1de51af3e..ee83ddc32 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -37,9 +37,12 @@ extern "C" { // Application API //--------------------------------------------------------------------+ -// Init device stack +// Init device stack on roothub port bool tud_init (uint8_t rhport); +// Deinit device stack on roothub port +bool tud_deinit(uint8_t rhport); + // Check if device stack is already initialized bool tud_inited(void); @@ -50,8 +53,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr); // Task function should be called in main/rtos loop TU_ATTR_ALWAYS_INLINE static inline -void tud_task (void) -{ +void tud_task (void) { tud_task_ext(UINT32_MAX, false); } @@ -80,8 +82,7 @@ bool tud_suspended(void); // Check if device is ready to transfer TU_ATTR_ALWAYS_INLINE static inline -bool tud_ready(void) -{ +bool tud_ready(void) { return tud_mounted() && !tud_suspended(); } @@ -151,6 +152,9 @@ TU_ATTR_WEAK void tud_suspend_cb(bool remote_wakeup_en); // Invoked when usb bus is resumed TU_ATTR_WEAK void tud_resume_cb(void); +// Invoked when there is a new usb event, which need to be processed by tud_task()/tud_task_ext() +void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr); + // Invoked when a new (micro) frame started TU_ATTR_WEAK void tud_sof_cb(uint32_t frame_count); @@ -223,8 +227,8 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_HEADER, U16_TO_U8S_LE(0x0120),\ /* CDC Call */\ 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_CALL_MANAGEMENT, 0, (uint8_t)((_itfnum) + 1),\ - /* CDC ACM: support line request */\ - 4, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, 2,\ + /* CDC ACM: support line request + send break */\ + 4, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, 6,\ /* CDC Union */\ 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_UNION, _itfnum, (uint8_t)((_itfnum) + 1),\ /* Endpoint Notification */\ @@ -398,6 +402,11 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb // For more channels, add definitions here +/* Standard AC Interrupt Endpoint Descriptor(4.8.2.1) */ +#define TUD_AUDIO_DESC_STD_AC_INT_EP_LEN 7 +#define TUD_AUDIO_DESC_STD_AC_INT_EP(_ep, _interval) \ + TUD_AUDIO_DESC_STD_AC_INT_EP_LEN, TUSB_DESC_ENDPOINT, _ep, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(6), _interval + /* Standard AS Interface Descriptor(4.9.1) */ #define TUD_AUDIO_DESC_STD_AS_INT_LEN 9 #define TUD_AUDIO_DESC_STD_AS_INT(_itfnum, _altset, _nEPs, _stridx) \ @@ -426,7 +435,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* Standard AS Isochronous Feedback Endpoint Descriptor(4.10.2.1) */ #define TUD_AUDIO_DESC_STD_AS_ISO_FB_EP_LEN 7 #define TUD_AUDIO_DESC_STD_AS_ISO_FB_EP(_ep, _interval) \ - TUD_AUDIO_DESC_STD_AS_ISO_FB_EP_LEN, TUSB_DESC_ENDPOINT, _ep, (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_NO_SYNC | TUSB_ISO_EP_ATT_EXPLICIT_FB), U16_TO_U8S_LE(4), _interval + TUD_AUDIO_DESC_STD_AS_ISO_FB_EP_LEN, TUSB_DESC_ENDPOINT, _ep, (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_NO_SYNC | (uint8_t)TUSB_ISO_EP_ATT_EXPLICIT_FB), U16_TO_U8S_LE(4), _interval // AUDIO simple descriptor (UAC2) for 1 microphone input // - 1 Input Terminal, 1 Feature Unit (Mute and Volume Control), 1 Output Terminal, 1 Clock Source @@ -473,7 +482,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ TUD_OPT_HIGH_SPEED ? 0x04 : 0x01),\ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000) @@ -522,7 +531,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ TUD_OPT_HIGH_SPEED ? 0x04 : 0x01),\ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000) @@ -570,7 +579,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ TUD_OPT_HIGH_SPEED ? 0x04 : 0x01),\ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000),\ /* Standard AS Isochronous Feedback Endpoint Descriptor(4.10.2.1) */\ @@ -779,10 +788,6 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb #define TUD_BT_PROTOCOL_PRIMARY_CONTROLLER 0x01 #define TUD_BT_PROTOCOL_AMP_CONTROLLER 0x02 -#ifndef CFG_TUD_BTH_ISO_ALT_COUNT -#define CFG_TUD_BTH_ISO_ALT_COUNT 0 -#endif - // Length of template descriptor: 38 bytes + number of ISO alternatives * 23 #define TUD_BTH_DESC_LEN (8 + 9 + 7 + 7 + 7 + (CFG_TUD_BTH_ISO_ALT_COUNT) * (9 + 7 + 7)) diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index 76d062e40..35cce1f7e 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -32,24 +32,32 @@ #include "tusb.h" #include "device/usbd_pvt.h" +//--------------------------------------------------------------------+ +// Callback weak stubs (called if application does not provide) +//--------------------------------------------------------------------+ +TU_ATTR_WEAK void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const* request) { + (void) rhport; + (void) request; +} + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ + #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL extern void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback); #endif -enum -{ +enum { EDPT_CTRL_OUT = 0x00, - EDPT_CTRL_IN = 0x80 + EDPT_CTRL_IN = 0x80 }; -typedef struct -{ +typedef struct { tusb_control_request_t request; - uint8_t* buffer; uint16_t data_len; uint16_t total_xferred; - usbd_control_xfer_cb_t complete_cb; } usbd_control_xfer_t; @@ -63,20 +71,18 @@ tu_static uint8_t _usbd_ctrl_buf[CFG_TUD_ENDPOINT0_SIZE]; //--------------------------------------------------------------------+ // Queue ZLP status transaction -static inline bool _status_stage_xact(uint8_t rhport, tusb_control_request_t const * request) -{ +static inline bool _status_stage_xact(uint8_t rhport, tusb_control_request_t const* request) { // Opposite to endpoint in Data Phase uint8_t const ep_addr = request->bmRequestType_bit.direction ? EDPT_CTRL_OUT : EDPT_CTRL_IN; return usbd_edpt_xfer(rhport, ep_addr, NULL, 0); } // Status phase -bool tud_control_status(uint8_t rhport, tusb_control_request_t const * request) -{ - _ctrl_xfer.request = (*request); - _ctrl_xfer.buffer = NULL; +bool tud_control_status(uint8_t rhport, tusb_control_request_t const* request) { + _ctrl_xfer.request = (*request); + _ctrl_xfer.buffer = NULL; _ctrl_xfer.total_xferred = 0; - _ctrl_xfer.data_len = 0; + _ctrl_xfer.data_len = 0; return _status_stage_xact(rhport, request); } @@ -84,16 +90,15 @@ bool tud_control_status(uint8_t rhport, tusb_control_request_t const * request) // Queue a transaction in Data Stage // Each transaction has up to Endpoint0's max packet size. // This function can also transfer an zero-length packet -static bool _data_stage_xact(uint8_t rhport) -{ - uint16_t const xact_len = tu_min16(_ctrl_xfer.data_len - _ctrl_xfer.total_xferred, CFG_TUD_ENDPOINT0_SIZE); +static bool _data_stage_xact(uint8_t rhport) { + uint16_t const xact_len = tu_min16(_ctrl_xfer.data_len - _ctrl_xfer.total_xferred, + CFG_TUD_ENDPOINT0_SIZE); uint8_t ep_addr = EDPT_CTRL_OUT; - if ( _ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_IN ) - { + if (_ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_IN) { ep_addr = EDPT_CTRL_IN; - if ( xact_len ) { + if (xact_len) { TU_VERIFY(0 == tu_memcpy_s(_usbd_ctrl_buf, CFG_TUD_ENDPOINT0_SIZE, _ctrl_xfer.buffer, xact_len)); } } @@ -103,29 +108,24 @@ static bool _data_stage_xact(uint8_t rhport) // Transmit data to/from the control endpoint. // If the request's wLength is zero, a status packet is sent instead. -bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, void* buffer, uint16_t len) -{ - _ctrl_xfer.request = (*request); - _ctrl_xfer.buffer = (uint8_t*) buffer; +bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const* request, void* buffer, uint16_t len) { + _ctrl_xfer.request = (*request); + _ctrl_xfer.buffer = (uint8_t*) buffer; _ctrl_xfer.total_xferred = 0U; - _ctrl_xfer.data_len = tu_min16(len, request->wLength); + _ctrl_xfer.data_len = tu_min16(len, request->wLength); - if (request->wLength > 0U) - { - if(_ctrl_xfer.data_len > 0U) - { + if (request->wLength > 0U) { + if (_ctrl_xfer.data_len > 0U) { TU_ASSERT(buffer); } // TU_LOG2(" Control total data length is %u bytes\r\n", _ctrl_xfer.data_len); // Data stage - TU_ASSERT( _data_stage_xact(rhport) ); - } - else - { + TU_ASSERT(_data_stage_xact(rhport)); + } else { // Status stage - TU_ASSERT( _status_stage_xact(rhport, request) ); + TU_ASSERT(_status_stage_xact(rhport, request)); } return true; @@ -134,49 +134,42 @@ bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, vo //--------------------------------------------------------------------+ // USBD API //--------------------------------------------------------------------+ - void usbd_control_reset(void); -void usbd_control_set_request(tusb_control_request_t const *request); -void usbd_control_set_complete_callback( usbd_control_xfer_cb_t fp ); -bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); +void usbd_control_set_request(tusb_control_request_t const* request); +void usbd_control_set_complete_callback(usbd_control_xfer_cb_t fp); +bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); -void usbd_control_reset(void) -{ +void usbd_control_reset(void) { tu_varclr(&_ctrl_xfer); } // Set complete callback -void usbd_control_set_complete_callback( usbd_control_xfer_cb_t fp ) -{ +void usbd_control_set_complete_callback(usbd_control_xfer_cb_t fp) { _ctrl_xfer.complete_cb = fp; } // for dcd_set_address where DCD is responsible for status response -void usbd_control_set_request(tusb_control_request_t const *request) -{ - _ctrl_xfer.request = (*request); - _ctrl_xfer.buffer = NULL; +void usbd_control_set_request(tusb_control_request_t const* request) { + _ctrl_xfer.request = (*request); + _ctrl_xfer.buffer = NULL; _ctrl_xfer.total_xferred = 0; - _ctrl_xfer.data_len = 0; + _ctrl_xfer.data_len = 0; } // callback when a transaction complete on // - DATA stage of control endpoint or // - Status stage -bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) -{ +bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) result; // Endpoint Address is opposite to direction bit, this is Status Stage complete event - if ( tu_edpt_dir(ep_addr) != _ctrl_xfer.request.bmRequestType_bit.direction ) - { + if (tu_edpt_dir(ep_addr) != _ctrl_xfer.request.bmRequestType_bit.direction) { TU_ASSERT(0 == xferred_bytes); // invoke optional dcd hook if available - if (dcd_edpt0_status_complete) dcd_edpt0_status_complete(rhport, &_ctrl_xfer.request); + dcd_edpt0_status_complete(rhport, &_ctrl_xfer.request); - if (_ctrl_xfer.complete_cb) - { + if (_ctrl_xfer.complete_cb) { // TODO refactor with usbd_driver_print_control_complete_name _ctrl_xfer.complete_cb(rhport, CONTROL_STAGE_ACK, &_ctrl_xfer.request); } @@ -184,8 +177,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result return true; } - if ( _ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_OUT ) - { + if (_ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_OUT) { TU_VERIFY(_ctrl_xfer.buffer); memcpy(_ctrl_xfer.buffer, _usbd_ctrl_buf, xferred_bytes); TU_LOG_MEM(CFG_TUD_LOG_LEVEL, _usbd_ctrl_buf, xferred_bytes, 2); @@ -196,15 +188,14 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result // Data Stage is complete when all request's length are transferred or // a short packet is sent including zero-length packet. - if ( (_ctrl_xfer.request.wLength == _ctrl_xfer.total_xferred) || (xferred_bytes < CFG_TUD_ENDPOINT0_SIZE) ) - { + if ((_ctrl_xfer.request.wLength == _ctrl_xfer.total_xferred) || + (xferred_bytes < CFG_TUD_ENDPOINT0_SIZE)) { // DATA stage is complete bool is_ok = true; // invoke complete callback if set // callback can still stall control in status phase e.g out data does not make sense - if ( _ctrl_xfer.complete_cb ) - { + if (_ctrl_xfer.complete_cb) { #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL usbd_driver_print_control_complete_name(_ctrl_xfer.complete_cb); #endif @@ -212,21 +203,17 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result is_ok = _ctrl_xfer.complete_cb(rhport, CONTROL_STAGE_DATA, &_ctrl_xfer.request); } - if ( is_ok ) - { + if (is_ok) { // Send status - TU_ASSERT( _status_stage_xact(rhport, &_ctrl_xfer.request) ); - }else - { + TU_ASSERT(_status_stage_xact(rhport, &_ctrl_xfer.request)); + } else { // Stall both IN and OUT control endpoint dcd_edpt_stall(rhport, EDPT_CTRL_OUT); dcd_edpt_stall(rhport, EDPT_CTRL_IN); } - } - else - { + } else { // More data to transfer - TU_ASSERT( _data_stage_xact(rhport) ); + TU_ASSERT(_data_stage_xact(rhport)); } return true; diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index 940b2858b..7eb504246 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -23,8 +23,8 @@ * * This file is part of the TinyUSB stack. */ -#ifndef USBD_PVT_H_ -#define USBD_PVT_H_ +#ifndef TUSB_USBD_PVT_H_ +#define TUSB_USBD_PVT_H_ #include "osal/osal.h" #include "common/tusb_fifo.h" @@ -33,24 +33,16 @@ 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 >= CFG_TUD_LOG_LEVEL +typedef struct { char const* name; - #endif - void (* init ) (void); + bool (* deinit ) (void); void (* reset ) (uint8_t rhport); uint16_t (* open ) (uint8_t rhport, tusb_desc_interface_t const * desc_intf, uint16_t max_len); bool (* control_xfer_cb ) (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); @@ -59,7 +51,7 @@ typedef struct } usbd_class_driver_t; // Invoked when initializing device stack to get additional class drivers. -// Can optionally implemented by application to extend/overwrite class driver support. +// Can be implemented by application to extend/overwrite class driver support. // Note: The drivers array must be accessible at all time when stack is active usbd_class_driver_t const* usbd_app_driver_get_cb(uint8_t* driver_count) TU_ATTR_WEAK; @@ -111,8 +103,7 @@ bool usbd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endp // Check if endpoint is ready (not busy and not stalled) TU_ATTR_ALWAYS_INLINE static inline -bool usbd_edpt_ready(uint8_t rhport, uint8_t ep_addr) -{ +bool usbd_edpt_ready(uint8_t rhport, uint8_t ep_addr) { return !usbd_edpt_busy(rhport, ep_addr) && !usbd_edpt_stalled(rhport, ep_addr); } @@ -124,11 +115,10 @@ void usbd_sof_enable(uint8_t rhport, bool en); *------------------------------------------------------------------*/ bool usbd_open_edpt_pair(uint8_t rhport, uint8_t const* p_desc, uint8_t ep_count, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in); -void usbd_defer_func( osal_task_func_t func, void* param, bool in_isr ); - +void usbd_defer_func(osal_task_func_t func, void *param, bool in_isr); #ifdef __cplusplus } #endif -#endif /* USBD_PVT_H_ */ +#endif diff --git a/src/host/hcd.h b/src/host/hcd.h index 9bcc1c6df..5547c7cc5 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -39,7 +39,7 @@ // Configuration //--------------------------------------------------------------------+ -// Max number of endpoints per device +// Max number of endpoints pair per device // TODO optimize memory usage #ifndef CFG_TUH_ENDPOINT_MAX #define CFG_TUH_ENDPOINT_MAX 16 @@ -125,13 +125,16 @@ bool hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) TU_ATTR_W //--------------------------------------------------------------------+ // optional hcd configuration, called by tuh_configure() -bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) TU_ATTR_WEAK; +bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param); // Initialize controller to host mode bool hcd_init(uint8_t rhport); +// De-initialize controller +bool hcd_deinit(uint8_t rhport); + // Interrupt Handler -void hcd_int_handler(uint8_t rhport); +void hcd_int_handler(uint8_t rhport, bool in_isr); // Enable USB interrupt void hcd_int_enable (uint8_t rhport); @@ -167,17 +170,17 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr); //--------------------------------------------------------------------+ // Open an endpoint -bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc); +bool hcd_edpt_open(uint8_t rhport, uint8_t daddr, tusb_desc_endpoint_t const * ep_desc); // 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); +bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, 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]); +bool hcd_setup_send(uint8_t rhport, uint8_t daddr, uint8_t const setup_packet[8]); // clear stall, data toggle is also reset to DATA0 bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr); @@ -198,8 +201,7 @@ extern void hcd_event_handler(hcd_event_t const* event, bool in_isr); // Helper to send device attach event TU_ATTR_ALWAYS_INLINE static inline -void hcd_event_device_attach(uint8_t rhport, bool in_isr) -{ +void hcd_event_device_attach(uint8_t rhport, bool in_isr) { hcd_event_t event; event.rhport = rhport; event.event_id = HCD_EVENT_DEVICE_ATTACH; @@ -211,8 +213,7 @@ void hcd_event_device_attach(uint8_t rhport, bool in_isr) // Helper to send device removal event TU_ATTR_ALWAYS_INLINE static inline -void hcd_event_device_remove(uint8_t rhport, bool in_isr) -{ +void hcd_event_device_remove(uint8_t rhport, bool in_isr) { hcd_event_t event; event.rhport = rhport; event.event_id = HCD_EVENT_DEVICE_REMOVE; @@ -224,10 +225,8 @@ void hcd_event_device_remove(uint8_t rhport, bool in_isr) // Helper to send USB transfer event TU_ATTR_ALWAYS_INLINE static inline -void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, uint32_t xferred_bytes, xfer_result_t result, bool in_isr) -{ - hcd_event_t event = - { +void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, uint32_t xferred_bytes, xfer_result_t result, bool in_isr) { + hcd_event_t event = { .rhport = 0, // TODO correct rhport .event_id = HCD_EVENT_XFER_COMPLETE, .dev_addr = dev_addr, diff --git a/src/host/hub.c b/src/host/hub.c index ec30eb96a..e97014443 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -30,7 +30,7 @@ #include "hcd.h" #include "usbh.h" -#include "usbh_classdriver.h" +#include "usbh_pvt.h" #include "hub.h" // Debug level, TUSB_CFG_DEBUG must be at least this level for debug message @@ -182,9 +182,13 @@ bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, //--------------------------------------------------------------------+ // CLASS-USBH API (don't require to verify parameters) //--------------------------------------------------------------------+ -void hub_init(void) -{ +bool hub_init(void) { tu_memclr(hub_data, sizeof(hub_data)); + return true; +} + +bool hub_deinit(void) { + return true; } bool hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) @@ -435,9 +439,12 @@ static void hub_port_get_status_complete (tuh_xfer_t* xfer) // Other changes are: L1 state // TODO clear change - // prepare for next hub status - // TODO continue with status_change, or maybe we can do it again with status - hub_edpt_status_xfer(daddr); + else + { + // prepare for next hub status + // TODO continue with status_change, or maybe we can do it again with status + hub_edpt_status_xfer(daddr); + } } } diff --git a/src/host/hub.h b/src/host/hub.h index 390740e1f..385efe6b2 100644 --- a/src/host/hub.h +++ b/src/host/hub.h @@ -187,16 +187,14 @@ bool hub_port_get_status (uint8_t hub_addr, uint8_t hub_port, void* resp, bool hub_edpt_status_xfer(uint8_t dev_addr); // Reset a port -static inline bool hub_port_reset(uint8_t hub_addr, uint8_t hub_port, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +TU_ATTR_ALWAYS_INLINE static inline +bool hub_port_reset(uint8_t hub_addr, uint8_t hub_port, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return hub_port_set_feature(hub_addr, hub_port, HUB_FEATURE_PORT_RESET, complete_cb, user_data); } // Clear Reset Change -static inline bool hub_port_clear_reset_change(uint8_t hub_addr, uint8_t hub_port, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +TU_ATTR_ALWAYS_INLINE static inline +bool hub_port_clear_reset_change(uint8_t hub_addr, uint8_t hub_port, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return hub_port_clear_feature(hub_addr, hub_port, HUB_FEATURE_PORT_RESET_CHANGE, complete_cb, user_data); } @@ -204,7 +202,8 @@ static inline bool hub_port_clear_reset_change(uint8_t hub_addr, uint8_t hub_por //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ -void hub_init (void); +bool hub_init (void); +bool hub_deinit (void); bool hub_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); bool hub_set_config (uint8_t dev_addr, uint8_t itf_num); bool hub_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); diff --git a/src/host/usbh.c b/src/host/usbh.c index cc7e38b45..7a47f5056 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -30,13 +30,12 @@ #include "host/hcd.h" #include "tusb.h" -#include "host/usbh_classdriver.h" +#include "host/usbh_pvt.h" #include "hub.h" //--------------------------------------------------------------------+ // USBH Configuration //--------------------------------------------------------------------+ - #ifndef CFG_TUH_TASK_QUEUE_SZ #define CFG_TUH_TASK_QUEUE_SZ 16 #endif @@ -45,26 +44,41 @@ #define CFG_TUH_INTERFACE_MAX 8 #endif +//--------------------------------------------------------------------+ +// Weak stubs: invoked if no strong implementation is available +//--------------------------------------------------------------------+ +TU_ATTR_WEAK bool hcd_deinit(uint8_t rhport) { + (void) rhport; + return false; +} + +TU_ATTR_WEAK bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { + (void) rhport; + (void) cfg_id; + (void) cfg_param; + return false; +} + +TU_ATTR_WEAK void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) { + (void) rhport; + (void) eventid; + (void) in_isr; +} + //--------------------------------------------------------------------+ // USBH-HCD common data structure //--------------------------------------------------------------------+ - -typedef struct -{ +typedef struct { // port uint8_t rhport; uint8_t hub_addr; uint8_t hub_port; - uint8_t speed; - // enumeration is in progress, done when all interfaces are configured - volatile uint8_t enumerating; - -// struct TU_ATTR_PACKED { -// uint8_t speed : 4; // packed speed to save footprint -// volatile uint8_t enumerating : 1; -// uint8_t TU_RESERVED : 3; -// }; + struct TU_ATTR_PACKED { + uint8_t speed : 4; // packed speed to save footprint + volatile uint8_t enumerating : 1; // enumeration is in progress, false if not connected or all interfaces are configured + uint8_t TU_RESERVED : 3; + }; } usbh_dev0_t; typedef struct { @@ -116,73 +130,94 @@ typedef struct { //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ - -#if CFG_TUSB_DEBUG >= 2 - #define DRIVER_NAME(_name) .name = _name, +#if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL + #define DRIVER_NAME(_name) _name #else - #define DRIVER_NAME(_name) + #define DRIVER_NAME(_name) NULL #endif -static usbh_class_driver_t const usbh_class_drivers[] = -{ - #if CFG_TUH_CDC +static usbh_class_driver_t const usbh_class_drivers[] = { + #if CFG_TUH_CDC { - DRIVER_NAME("CDC") - .init = cdch_init, - .open = cdch_open, - .set_config = cdch_set_config, - .xfer_cb = cdch_xfer_cb, - .close = cdch_close + .name = DRIVER_NAME("CDC"), + .init = cdch_init, + .deinit = cdch_deinit, + .open = cdch_open, + .set_config = cdch_set_config, + .xfer_cb = cdch_xfer_cb, + .close = cdch_close }, - #endif + #endif - #if CFG_TUH_MSC + #if CFG_TUH_MSC { - DRIVER_NAME("MSC") - .init = msch_init, - .open = msch_open, - .set_config = msch_set_config, - .xfer_cb = msch_xfer_cb, - .close = msch_close + .name = DRIVER_NAME("MSC"), + .init = msch_init, + .deinit = msch_deinit, + .open = msch_open, + .set_config = msch_set_config, + .xfer_cb = msch_xfer_cb, + .close = msch_close }, - #endif + #endif - #if CFG_TUH_HID + #if CFG_TUH_HID { - DRIVER_NAME("HID") - .init = hidh_init, - .open = hidh_open, - .set_config = hidh_set_config, - .xfer_cb = hidh_xfer_cb, - .close = hidh_close + .name = DRIVER_NAME("HID"), + .init = hidh_init, + .deinit = hidh_deinit, + .open = hidh_open, + .set_config = hidh_set_config, + .xfer_cb = hidh_xfer_cb, + .close = hidh_close }, - #endif + #endif - #if CFG_TUH_HUB + #if CFG_TUH_HUB { - DRIVER_NAME("HUB") - .init = hub_init, - .open = hub_open, - .set_config = hub_set_config, - .xfer_cb = hub_xfer_cb, - .close = hub_close + .name = DRIVER_NAME("HUB"), + .init = hub_init, + .deinit = hub_deinit, + .open = hub_open, + .set_config = hub_set_config, + .xfer_cb = hub_xfer_cb, + .close = hub_close }, - #endif + #endif - #if CFG_TUH_VENDOR + #if CFG_TUH_VENDOR { - DRIVER_NAME("VENDOR") + .name = DRIVER_NAME("VENDOR"), .init = cush_init, - .open = cush_open_subtask, + .deinit = cush_deinit, + .open = cush_open, + .set_config = cush_set_config, .xfer_cb = cush_isr, .close = cush_close } - #endif + #endif }; -enum { USBH_CLASS_DRIVER_COUNT = TU_ARRAY_SIZE(usbh_class_drivers) }; +enum { BUILTIN_DRIVER_COUNT = TU_ARRAY_SIZE(usbh_class_drivers) }; enum { CONFIG_NUM = 1 }; // default to use configuration 1 +// Additional class drivers implemented by application +tu_static usbh_class_driver_t const * _app_driver = NULL; +tu_static uint8_t _app_driver_count = 0; + +#define TOTAL_DRIVER_COUNT (_app_driver_count + BUILTIN_DRIVER_COUNT) + +static inline usbh_class_driver_t const *get_driver(uint8_t drv_id) { + usbh_class_driver_t const *driver = NULL; + + if ( drv_id < _app_driver_count ) { + driver = &_app_driver[drv_id]; + } else if ( drv_id < TOTAL_DRIVER_COUNT && BUILTIN_DRIVER_COUNT > 0) { + driver = &usbh_class_drivers[drv_id - _app_driver_count]; + } + + return driver; +} //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION @@ -220,8 +255,7 @@ static uint8_t _usbh_ctrl_buf[CFG_TUH_ENUMERATION_BUFSIZE]; // Control transfers: since most controllers do not support multiple control transfers // on multiple devices concurrently and control transfers are not used much except for // enumeration, we will only execute control transfers one at a time. -CFG_TUH_MEM_SECTION struct -{ +CFG_TUH_MEM_SECTION struct { CFG_TUH_MEM_ALIGN tusb_control_request_t request; uint8_t* buffer; tuh_xfer_cb_t complete_cb; @@ -234,9 +268,7 @@ CFG_TUH_MEM_SECTION struct //------------- Helper Function -------------// -TU_ATTR_ALWAYS_INLINE -static inline usbh_device_t* get_device(uint8_t dev_addr) -{ +TU_ATTR_ALWAYS_INLINE static inline usbh_device_t* get_device(uint8_t dev_addr) { TU_VERIFY(dev_addr > 0 && dev_addr <= TOTAL_DEVICES, NULL); return &_usbh_devices[dev_addr-1]; } @@ -255,6 +287,12 @@ TU_ATTR_WEAK void osal_task_delay(uint32_t msec) { } #endif +TU_ATTR_ALWAYS_INLINE static inline bool queue_event(hcd_event_t const * event, bool in_isr) { + TU_ASSERT(osal_queue_send(_usbh_q, event, in_isr)); + tuh_event_hook_cb(event->rhport, event->event_id, in_isr); + return true; +} + //--------------------------------------------------------------------+ // Device API //--------------------------------------------------------------------+ @@ -301,11 +339,7 @@ bool tuh_rhport_reset_bus(uint8_t rhport, bool active) { //--------------------------------------------------------------------+ bool tuh_configure(uint8_t rhport, uint32_t cfg_id, const void *cfg_param) { - if ( hcd_configure ) { - return hcd_configure(rhport, cfg_id, cfg_param); - } else { - return false; - } + return hcd_configure(rhport, cfg_id, cfg_param); } static void clear_device(usbh_device_t* dev) { @@ -318,50 +352,95 @@ bool tuh_inited(void) { return _usbh_controller != TUSB_INDEX_INVALID_8; } -bool tuh_init(uint8_t controller_id) { +bool tuh_init(uint8_t rhport) { // skip if already initialized - if ( tuh_inited() ) return true; + if (tuh_rhport_is_active(rhport)) return true; - TU_LOG_USBH("USBH init on controller %u\r\n", controller_id); - 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)); + TU_LOG_USBH("USBH init on controller %u\r\n", rhport); - // Event queue - _usbh_q = osal_queue_create( &_usbh_qdef ); - TU_ASSERT(_usbh_q != NULL); + // Init host stack if not already + if (!tuh_inited()) { + TU_LOG_INT_USBH(sizeof(usbh_device_t)); + TU_LOG_INT_USBH(sizeof(hcd_event_t)); + TU_LOG_INT_USBH(sizeof(_ctrl_xfer)); + TU_LOG_INT_USBH(sizeof(tuh_xfer_t)); + TU_LOG_INT_USBH(sizeof(tu_fifo_t)); + TU_LOG_INT_USBH(sizeof(tu_edpt_stream_t)); + + // Event queue + _usbh_q = osal_queue_create(&_usbh_qdef); + TU_ASSERT(_usbh_q != NULL); #if OSAL_MUTEX_REQUIRED - // Init mutex - _usbh_mutex = osal_mutex_create(&_usbh_mutexdef); - TU_ASSERT(_usbh_mutex); + // Init mutex + _usbh_mutex = osal_mutex_create(&_usbh_mutexdef); + TU_ASSERT(_usbh_mutex); #endif - // Device - tu_memclr(&_dev0, sizeof(_dev0)); - tu_memclr(_usbh_devices, sizeof(_usbh_devices)); - tu_memclr(&_ctrl_xfer, sizeof(_ctrl_xfer)); + // Get application driver if available + if (usbh_app_driver_get_cb) { + _app_driver = usbh_app_driver_get_cb(&_app_driver_count); + } - for(uint8_t i=0; iname); + driver->init(); + } + } } - // Class drivers - for (uint8_t drv_id = 0; drv_id < USBH_CLASS_DRIVER_COUNT; drv_id++) - { - TU_LOG_USBH("%s init\r\n", usbh_class_drivers[drv_id].name); - usbh_class_drivers[drv_id].init(); + // Init host controller + _usbh_controller = rhport;; + TU_ASSERT(hcd_init(rhport)); + hcd_int_enable(rhport); + + return true; +} + +bool tuh_deinit(uint8_t rhport) { + if (!tuh_rhport_is_active(rhport)) return true; + + // deinit host controller + hcd_int_disable(rhport); + hcd_deinit(rhport); + _usbh_controller = TUSB_INDEX_INVALID_8; + + // "unplug" all devices on this rhport (hub_addr = 0, hub_port = 0) + process_removing_device(rhport, 0, 0); + + // deinit host stack if no controller is active + if (!tuh_inited()) { + // Class drivers + for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) { + usbh_class_driver_t const* driver = get_driver(drv_id); + if (driver && driver->deinit) { + TU_LOG_USBH("%s deinit\r\n", driver->name); + driver->deinit(); + } + } + + osal_queue_delete(_usbh_q); + _usbh_q = NULL; + + #if OSAL_MUTEX_REQUIRED + // TODO make sure there is no task waiting on this mutex + osal_mutex_delete(_usbh_mutex); + _usbh_mutex = NULL; + #endif } - _usbh_controller = controller_id;; - - TU_ASSERT(hcd_init(controller_id)); - hcd_int_enable(controller_id); - return true; } @@ -394,35 +473,33 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { (void) in_isr; // not implemented yet // Skip if stack is not initialized - if ( !tuh_inited() ) return; + if (!tuh_inited()) return; // Loop until there is no more events in the queue - while (1) - { + while (1) { hcd_event_t event; - if ( !osal_queue_receive(_usbh_q, &event, timeout_ms) ) return; + if (!osal_queue_receive(_usbh_q, &event, timeout_ms)) return; - switch (event.event_id) - { + switch (event.event_id) { case HCD_EVENT_DEVICE_ATTACH: - // due to the shared _usbh_ctrl_buf, we must complete enumerating - // one device before enumerating another one. - if ( _dev0.enumerating ) { + // due to the shared _usbh_ctrl_buf, we must complete enumerating one device before enumerating another one. + // TODO better to have an separated queue for newly attached devices + if (_dev0.enumerating) { TU_LOG_USBH("[%u:] USBH Defer Attach until current enumeration complete\r\n", event.rhport); bool is_empty = osal_queue_empty(_usbh_q); - osal_queue_send(_usbh_q, &event, in_isr); + queue_event(&event, in_isr); if (is_empty) { // Exit if this is the only event in the queue, otherwise we may loop forever return; } - }else { + } else { TU_LOG_USBH("[%u:] USBH DEVICE ATTACH\r\n", event.rhport); _dev0.enumerating = 1; enum_new_device(&event); } - break; + break; case HCD_EVENT_DEVICE_REMOVE: TU_LOG_USBH("[%u:%u:%u] USBH DEVICE REMOVED\r\n", event.rhport, event.connection.hub_addr, event.connection.hub_port); @@ -430,37 +507,34 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { #if CFG_TUH_HUB // TODO remove - if ( event.connection.hub_addr != 0) { + if (event.connection.hub_addr != 0 && event.connection.hub_port != 0) { // done with hub, waiting for next data on status pipe - (void) hub_edpt_status_xfer( event.connection.hub_addr ); + (void) hub_edpt_status_xfer(event.connection.hub_addr); } #endif - break; + break; - case HCD_EVENT_XFER_COMPLETE: - { + case HCD_EVENT_XFER_COMPLETE: { uint8_t const ep_addr = event.xfer_complete.ep_addr; - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const ep_dir = tu_edpt_dir(ep_addr); + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const ep_dir = (uint8_t) tu_edpt_dir(ep_addr); - 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]); + 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) { // device 0 only has control endpoint - TU_ASSERT(epnum == 0, ); + 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 { usbh_device_t* dev = get_device(event.dev_addr); - TU_VERIFY(dev && dev->connected, ); + TU_VERIFY(dev && dev->connected,); - dev->ep_status[epnum][ep_dir].busy = 0; + 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 { + 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 @@ -477,16 +551,16 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { .complete_cb = complete_cb, .user_data = dev->ep_callback[epnum][ep_dir].user_data }; - 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); + uint8_t drv_id = dev->ep2drv[epnum][ep_dir]; + usbh_class_driver_t const* driver = get_driver(drv_id); + if (driver) { + TU_LOG_USBH("%s xfer callback\r\n", driver->name); + driver->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,); @@ -494,14 +568,15 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { } } } + break; } - break; case USBH_EVENT_FUNC_CALL: - if ( event.func_call.func ) event.func_call.func(event.func_call.param); - break; + if (event.func_call.func) event.func_call.func(event.func_call.param); + break; - default: break; + default: + break; } #if CFG_TUSB_OS != OPT_OS_NONE && CFG_TUSB_OS != OPT_OS_PICO @@ -515,28 +590,31 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { // Control transfer //--------------------------------------------------------------------+ -static void _control_blocking_complete_cb(tuh_xfer_t* xfer) -{ +static void _control_blocking_complete_cb(tuh_xfer_t* xfer) { // update result *((xfer_result_t*) xfer->user_data) = xfer->result; } // TODO timeout_ms is not supported yet -bool tuh_control_xfer (tuh_xfer_t* xfer) -{ +bool tuh_control_xfer (tuh_xfer_t* xfer) { // EP0 with setup packet TU_VERIFY(xfer->ep_addr == 0 && xfer->setup); + // Check if device is still connected (enumerating for dev0) + uint8_t const daddr = xfer->daddr; + if ( daddr == 0 ) { + if (!_dev0.enumerating) return false; + } else { + usbh_device_t const* dev = get_device(daddr); + if (dev && dev->connected == 0) return false; + } + // pre-check to help reducing mutex lock TU_VERIFY(_ctrl_xfer.stage == CONTROL_STAGE_IDLE); - - uint8_t const daddr = xfer->daddr; - (void) osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER); bool const is_idle = (_ctrl_xfer.stage == CONTROL_STAGE_IDLE); - if (is_idle) - { + if (is_idle) { _ctrl_xfer.stage = CONTROL_STAGE_SETUP; _ctrl_xfer.daddr = daddr; _ctrl_xfer.actual_len = 0; @@ -555,14 +633,11 @@ 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(CFG_TUH_LOG_LEVEL, xfer->setup); - TU_LOG_USBH("\r\n"); + TU_LOG_BUF_USBH(xfer->setup, 8); - if (xfer->complete_cb) - { + if (xfer->complete_cb) { TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t const*) &_ctrl_xfer.request) ); - }else - { + }else { // blocking if complete callback is not provided // change callback to internal blocking, and result as user argument volatile xfer_result_t result = XFER_RESULT_INVALID; @@ -593,21 +668,18 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) return true; } -TU_ATTR_ALWAYS_INLINE static inline void _set_control_xfer_stage(uint8_t stage) -{ +TU_ATTR_ALWAYS_INLINE static inline void _set_control_xfer_stage(uint8_t stage) { (void) osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER); _ctrl_xfer.stage = stage; (void) osal_mutex_unlock(_usbh_mutex); } -static void _xfer_complete(uint8_t daddr, xfer_result_t result) -{ +static void _control_xfer_complete(uint8_t daddr, xfer_result_t result) { TU_LOG_USBH("\r\n"); // duplicate xfer since user can execute control transfer within callback tusb_control_request_t const request = _ctrl_xfer.request; - tuh_xfer_t xfer_temp = - { + tuh_xfer_t xfer_temp = { .daddr = daddr, .ep_addr = 0, .result = result, @@ -620,60 +692,61 @@ static void _xfer_complete(uint8_t daddr, xfer_result_t result) _set_control_xfer_stage(CONTROL_STAGE_IDLE); - if (xfer_temp.complete_cb) - { + if (xfer_temp.complete_cb) { xfer_temp.complete_cb(&xfer_temp); } } -static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) -{ +static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) ep_addr; - const uint8_t rhport = usbh_get_rhport(dev_addr); + const uint8_t rhport = usbh_get_rhport(daddr); tusb_control_request_t const * request = &_ctrl_xfer.request; - if (XFER_RESULT_SUCCESS != result) - { - TU_LOG1("[%u:%u] Control %s, xferred_bytes = %lu\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes); - #if CFG_TUSB_DEBUG == 1 - TU_LOG1_PTR(request); - TU_LOG1("\r\n"); - #endif + if (XFER_RESULT_SUCCESS != result) { + TU_LOG_USBH("[%u:%u] Control %s, xferred_bytes = %" PRIu32 "\r\n", rhport, daddr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes); + TU_LOG_BUF_USBH(request, 8); // terminate transfer if any stage failed - _xfer_complete(dev_addr, result); - }else - { - switch(_ctrl_xfer.stage) - { + _control_xfer_complete(daddr, result); + }else { + switch(_ctrl_xfer.stage) { case CONTROL_STAGE_SETUP: - if (request->wLength) - { + if (request->wLength) { // DATA stage: initial data toggle is always 1 _set_control_xfer_stage(CONTROL_STAGE_DATA); - TU_ASSERT( hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.buffer, request->wLength) ); + TU_ASSERT( hcd_edpt_xfer(rhport, daddr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.buffer, request->wLength) ); return true; } TU_ATTR_FALLTHROUGH; case CONTROL_STAGE_DATA: - if (request->wLength) - { - TU_LOG_USBH("[%u:%u] Control data:\r\n", rhport, dev_addr); - TU_LOG_MEM(CFG_TUH_LOG_LEVEL, _ctrl_xfer.buffer, xferred_bytes, 2); + if (request->wLength) { + TU_LOG_USBH("[%u:%u] Control data:\r\n", rhport, daddr); + TU_LOG_MEM_USBH(_ctrl_xfer.buffer, xferred_bytes, 2); } _ctrl_xfer.actual_len = (uint16_t) xferred_bytes; // ACK stage: toggle is always 1 _set_control_xfer_stage(CONTROL_STAGE_ACK); - TU_ASSERT( hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, 1-request->bmRequestType_bit.direction), NULL, 0) ); - break; + TU_ASSERT( hcd_edpt_xfer(rhport, daddr, tu_edpt_addr(0, 1 - request->bmRequestType_bit.direction), NULL, 0) ); + break; - case CONTROL_STAGE_ACK: - _xfer_complete(dev_addr, result); - break; + case CONTROL_STAGE_ACK: { + // Abort all pending transfers if SET_CONFIGURATION request + // NOTE: should we force closing all non-control endpoints in the future? + if (request->bRequest == TUSB_REQ_SET_CONFIGURATION && request->bmRequestType == 0x00) { + for(uint8_t epnum=1; epnumdaddr; +bool tuh_edpt_xfer(tuh_xfer_t* xfer) { + uint8_t const daddr = xfer->daddr; uint8_t const ep_addr = xfer->ep_addr; TU_VERIFY(daddr && ep_addr); - TU_VERIFY(usbh_edpt_claim(daddr, ep_addr)); - if ( !usbh_edpt_xfer_with_callback(daddr, ep_addr, xfer->buffer, (uint16_t) xfer->buflen, xfer->complete_cb, xfer->user_data) ) - { + if (!usbh_edpt_xfer_with_callback(daddr, ep_addr, xfer->buffer, (uint16_t) xfer->buflen, + xfer->complete_cb, xfer->user_data)) { usbh_edpt_release(daddr, ep_addr); return false; } @@ -708,61 +779,72 @@ bool tuh_edpt_abort_xfer(uint8_t daddr, uint8_t ep_addr) { usbh_device_t* dev = get_device(daddr); TU_VERIFY(dev); + TU_LOG_USBH("[%u] Aborted transfer on EP %02X\r\n", daddr, ep_addr); + 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 + if ( epnum == 0 ) { + // control transfer: only 1 control at a time, check if we are aborting the current one + TU_VERIFY(daddr == _ctrl_xfer.daddr && _ctrl_xfer.stage != CONTROL_STAGE_IDLE); + TU_VERIFY(hcd_edpt_abort_xfer(dev->rhport, daddr, ep_addr)); + // reset control transfer state to idle + _set_control_xfer_stage(CONTROL_STAGE_IDLE); + } else { + // non-control skip if not busy + TU_VERIFY(dev->ep_status[epnum][dir].busy); + TU_VERIFY(hcd_edpt_abort_xfer(dev->rhport, daddr, ep_addr)); + // mark as ready and release endpoint if transfer is aborted dev->ep_status[epnum][dir].busy = false; + tu_edpt_release(&dev->ep_status[epnum][dir], _usbh_mutex); } - return ret; + return true; } //--------------------------------------------------------------------+ // USBH API For Class Driver //--------------------------------------------------------------------+ -uint8_t usbh_get_rhport(uint8_t dev_addr) -{ - usbh_device_t* dev = get_device(dev_addr); +uint8_t usbh_get_rhport(uint8_t dev_addr) { + usbh_device_t *dev = get_device(dev_addr); return dev ? dev->rhport : _dev0.rhport; } -uint8_t* usbh_get_enum_buf(void) -{ +uint8_t *usbh_get_enum_buf(void) { return _usbh_ctrl_buf; } -void usbh_int_set(bool enabled) -{ +void usbh_int_set(bool enabled) { // TODO all host controller if multiple are used since they shared the same event queue - if (enabled) - { + if (enabled) { hcd_int_enable(_usbh_controller); - }else - { + } else { hcd_int_disable(_usbh_controller); } } +void usbh_defer_func(osal_task_func_t func, void *param, bool in_isr) { + hcd_event_t event = { 0 }; + event.event_id = USBH_EVENT_FUNC_CALL; + event.func_call.func = func; + event.func_call.param = param; + + queue_event(&event, in_isr); +} + //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ // Claim an endpoint for transfer -bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr) -{ +bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr) { // Note: addr0 only use tuh_control_xfer usbh_device_t* dev = get_device(dev_addr); TU_ASSERT(dev && dev->connected); uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); TU_VERIFY(tu_edpt_claim(&dev->ep_status[epnum][dir], _usbh_mutex)); TU_LOG_USBH("[%u] Claimed EP 0x%02x\r\n", dev_addr, ep_addr); @@ -771,14 +853,13 @@ bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr) } // Release an claimed endpoint due to failed transfer attempt -bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr) -{ +bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr) { // Note: addr0 only use tuh_control_xfer usbh_device_t* dev = get_device(dev_addr); TU_VERIFY(dev && dev->connected); uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); TU_VERIFY(tu_edpt_release(&dev->ep_status[epnum][dir], _usbh_mutex)); TU_LOG_USBH("[%u] Released EP 0x%02x\r\n", dev_addr, ep_addr); @@ -787,9 +868,9 @@ bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr) } // 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) -{ +// TODO call usbh_edpt_release if failed +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) { (void) complete_cb; (void) user_data; @@ -797,7 +878,7 @@ bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * b TU_VERIFY(dev); uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); tu_edpt_state_t* ep_state = &dev->ep_status[epnum][dir]; TU_LOG_USBH(" Queue EP %02X with %u bytes ... \r\n", ep_addr, total_bytes); @@ -814,27 +895,22 @@ bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * b dev->ep_callback[epnum][dir].user_data = user_data; #endif - if ( hcd_edpt_xfer(dev->rhport, dev_addr, ep_addr, buffer, total_bytes) ) - { + if (hcd_edpt_xfer(dev->rhport, dev_addr, ep_addr, buffer, total_bytes)) { TU_LOG_USBH("OK\r\n"); return true; - }else - { + } else { // HCD error, mark endpoint as ready to allow next transfer - ep_state->busy = 0; + ep_state->busy = 0; ep_state->claimed = 0; TU_LOG1("Failed\r\n"); - TU_BREAKPOINT(); +// TU_BREAKPOINT(); return false; } } -static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size) -{ +static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size) { TU_LOG_USBH("[%u:%u] Open EP0 with Size = %u\r\n", usbh_get_rhport(dev_addr), dev_addr, max_packet_size); - - tusb_desc_endpoint_t ep0_desc = - { + tusb_desc_endpoint_t ep0_desc = { .bLength = sizeof(tusb_desc_endpoint_t), .bDescriptorType = TUSB_DESC_ENDPOINT, .bEndpointAddress = 0, @@ -846,10 +922,8 @@ static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size) return hcd_edpt_open(usbh_get_rhport(dev_addr), dev_addr, &ep0_desc); } -bool tuh_edpt_open(uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep) -{ - TU_ASSERT( tu_edpt_validate(desc_ep, tuh_speed_get(dev_addr)) ); - +bool tuh_edpt_open(uint8_t dev_addr, tusb_desc_endpoint_t const* desc_ep) { + TU_ASSERT(tu_edpt_validate(desc_ep, tuh_speed_get(dev_addr))); return hcd_edpt_open(usbh_get_rhport(dev_addr), dev_addr, desc_ep); } @@ -858,7 +932,7 @@ bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) { TU_VERIFY(dev); uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); return dev->ep_status[epnum][dir].busy; } @@ -867,37 +941,38 @@ bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) { // HCD Event Handler //--------------------------------------------------------------------+ -void hcd_devtree_get_info(uint8_t dev_addr, hcd_devtree_info_t* devtree_info) -{ +void hcd_devtree_get_info(uint8_t dev_addr, hcd_devtree_info_t* devtree_info) { usbh_device_t const* dev = get_device(dev_addr); - - if (dev) - { - devtree_info->rhport = dev->rhport; + if (dev) { + devtree_info->rhport = dev->rhport; devtree_info->hub_addr = dev->hub_addr; devtree_info->hub_port = dev->hub_port; - devtree_info->speed = dev->speed; - }else - { - devtree_info->rhport = _dev0.rhport; + devtree_info->speed = dev->speed; + } else { + devtree_info->rhport = _dev0.rhport; devtree_info->hub_addr = _dev0.hub_addr; devtree_info->hub_port = _dev0.hub_port; - devtree_info->speed = _dev0.speed; + devtree_info->speed = _dev0.speed; } } -TU_ATTR_FAST_FUNC void hcd_event_handler(hcd_event_t const* event, bool in_isr) -{ - switch (event->event_id) - { -// case HCD_EVENT_DEVICE_REMOVE: -// // mark device as removing to prevent further xfer before the event is processed in usbh task -// break; +TU_ATTR_FAST_FUNC void hcd_event_handler(hcd_event_t const* event, bool in_isr) { + switch (event->event_id) { + case HCD_EVENT_DEVICE_REMOVE: + // FIXME device remove from a hub need an HCD API for hcd to free up endpoint + // mark device as removing to prevent further xfer before the event is processed in usbh task - default: - osal_queue_send(_usbh_q, event, in_isr); - break; + // Check if dev0 is removed + if ((event->rhport == _dev0.rhport) && (event->connection.hub_addr == _dev0.hub_addr) && + (event->connection.hub_port == _dev0.hub_port)) { + _dev0.enumerating = 0; + } + break; + + default: break; } + + queue_event(event, in_isr); } //--------------------------------------------------------------------+ @@ -907,12 +982,9 @@ TU_ATTR_FAST_FUNC void hcd_event_handler(hcd_event_t const* event, bool in_isr) // generic helper to get a descriptor // if blocking, user_data is pointed to xfer_result static bool _get_descriptor(uint8_t daddr, uint8_t type, uint8_t index, uint16_t language_id, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ - tusb_control_request_t const request = - { - .bmRequestType_bit = - { + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + tusb_control_request_t const request = { + .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_DEVICE, .type = TUSB_REQ_TYPE_STANDARD, .direction = TUSB_DIR_IN @@ -922,9 +994,7 @@ static bool _get_descriptor(uint8_t daddr, uint8_t type, uint8_t index, uint16_t .wIndex = tu_htole16(language_id), .wLength = tu_htole16(len) }; - - tuh_xfer_t xfer = - { + tuh_xfer_t xfer = { .daddr = daddr, .ep_addr = 0, .setup = &request, @@ -937,29 +1007,25 @@ static bool _get_descriptor(uint8_t daddr, uint8_t type, uint8_t index, uint16_t } bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return _get_descriptor(daddr, type, index, 0x0000, buffer, len, complete_cb, user_data); } bool tuh_descriptor_get_device(uint8_t daddr, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { len = tu_min16(len, sizeof(tusb_desc_device_t)); return tuh_descriptor_get(daddr, TUSB_DESC_DEVICE, 0, buffer, len, complete_cb, user_data); } bool tuh_descriptor_get_configuration(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return tuh_descriptor_get(daddr, TUSB_DESC_CONFIGURATION, index, buffer, len, complete_cb, user_data); } //------------- String Descriptor -------------// bool tuh_descriptor_get_string(uint8_t daddr, uint8_t index, uint16_t language_id, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return _get_descriptor(daddr, TUSB_DESC_STRING, index, language_id, buffer, len, complete_cb, user_data); } @@ -974,8 +1040,7 @@ bool tuh_descriptor_get_manufacturer_string(uint8_t daddr, uint16_t language_id, // Get product string descriptor bool tuh_descriptor_get_product_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { usbh_device_t const* dev = get_device(daddr); TU_VERIFY(dev && dev->i_product); return tuh_descriptor_get_string(daddr, dev->i_product, language_id, buffer, len, complete_cb, user_data); @@ -983,8 +1048,7 @@ bool tuh_descriptor_get_product_string(uint8_t daddr, uint16_t language_id, void // Get serial string descriptor bool tuh_descriptor_get_serial_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { usbh_device_t const* dev = get_device(daddr); TU_VERIFY(dev && dev->i_serial); return tuh_descriptor_get_string(daddr, dev->i_serial, language_id, buffer, len, complete_cb, user_data); @@ -993,95 +1057,78 @@ bool tuh_descriptor_get_serial_string(uint8_t daddr, uint16_t language_id, void* // Get HID report descriptor // if blocking, user_data is pointed to xfer_result bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG_USBH("HID Get Report Descriptor\r\n"); - tusb_control_request_t const request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_IN - }, - .bRequest = TUSB_REQ_GET_DESCRIPTOR, - .wValue = tu_htole16(TU_U16(desc_type, index)), - .wIndex = tu_htole16((uint16_t) itf_num), - .wLength = len + tusb_control_request_t const request = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_IN + }, + .bRequest = TUSB_REQ_GET_DESCRIPTOR, + .wValue = tu_htole16(TU_U16(desc_type, index)), + .wIndex = tu_htole16((uint16_t) itf_num), + .wLength = len }; - - tuh_xfer_t xfer = - { - .daddr = daddr, - .ep_addr = 0, - .setup = &request, - .buffer = buffer, - .complete_cb = complete_cb, - .user_data = user_data + tuh_xfer_t xfer = { + .daddr = daddr, + .ep_addr = 0, + .setup = &request, + .buffer = buffer, + .complete_cb = complete_cb, + .user_data = user_data }; return tuh_control_xfer(&xfer); } bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG_USBH("Set Configuration = %d\r\n", config_num); - - tusb_control_request_t const request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_DEVICE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_OUT - }, - .bRequest = TUSB_REQ_SET_CONFIGURATION, - .wValue = tu_htole16(config_num), - .wIndex = 0, - .wLength = 0 + tusb_control_request_t const request = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_OUT + }, + .bRequest = TUSB_REQ_SET_CONFIGURATION, + .wValue = tu_htole16(config_num), + .wIndex = 0, + .wLength = 0 }; - - tuh_xfer_t xfer = - { - .daddr = daddr, - .ep_addr = 0, - .setup = &request, - .buffer = NULL, - .complete_cb = complete_cb, - .user_data = user_data + tuh_xfer_t xfer = { + .daddr = daddr, + .ep_addr = 0, + .setup = &request, + .buffer = NULL, + .complete_cb = complete_cb, + .user_data = user_data }; return tuh_control_xfer(&xfer); } bool tuh_interface_set(uint8_t daddr, uint8_t itf_num, uint8_t itf_alt, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG_USBH("Set Interface %u Alternate %u\r\n", itf_num, itf_alt); - - tusb_control_request_t const request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_DEVICE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_OUT - }, - .bRequest = TUSB_REQ_SET_INTERFACE, - .wValue = tu_htole16(itf_alt), - .wIndex = tu_htole16(itf_num), - .wLength = 0 + tusb_control_request_t const request = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_OUT + }, + .bRequest = TUSB_REQ_SET_INTERFACE, + .wValue = tu_htole16(itf_alt), + .wIndex = tu_htole16(itf_num), + .wLength = 0 }; - - tuh_xfer_t xfer = - { - .daddr = daddr, - .ep_addr = 0, - .setup = &request, - .buffer = NULL, - .complete_cb = complete_cb, - .user_data = user_data + tuh_xfer_t xfer = { + .daddr = daddr, + .ep_addr = 0, + .setup = &request, + .buffer = NULL, + .complete_cb = complete_cb, + .user_data = user_data }; return tuh_control_xfer(&xfer); @@ -1096,43 +1143,42 @@ bool tuh_interface_set(uint8_t daddr, uint8_t itf_num, uint8_t itf_alt, TU_VERIFY(_async_func(__VA_ARGS__, NULL, (uintptr_t) &result), XFER_RESULT_TIMEOUT); \ return (uint8_t) result -uint8_t tuh_descriptor_get_sync(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len) -{ +uint8_t tuh_descriptor_get_sync(uint8_t daddr, uint8_t type, uint8_t index, + void* buffer, uint16_t len) { _CONTROL_SYNC_API(tuh_descriptor_get, daddr, type, index, buffer, len); } -uint8_t tuh_descriptor_get_device_sync(uint8_t daddr, void* buffer, uint16_t len) -{ +uint8_t tuh_descriptor_get_device_sync(uint8_t daddr, void* buffer, uint16_t len) { _CONTROL_SYNC_API(tuh_descriptor_get_device, daddr, buffer, len); } -uint8_t tuh_descriptor_get_configuration_sync(uint8_t daddr, uint8_t index, void* buffer, uint16_t len) -{ +uint8_t tuh_descriptor_get_configuration_sync(uint8_t daddr, uint8_t index, + void* buffer, uint16_t len) { _CONTROL_SYNC_API(tuh_descriptor_get_configuration, daddr, index, buffer, len); } -uint8_t tuh_descriptor_get_hid_report_sync(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, void* buffer, uint16_t len) -{ +uint8_t tuh_descriptor_get_hid_report_sync(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, + void* buffer, uint16_t len) { _CONTROL_SYNC_API(tuh_descriptor_get_hid_report, daddr, itf_num, desc_type, index, buffer, len); } -uint8_t tuh_descriptor_get_string_sync(uint8_t daddr, uint8_t index, uint16_t language_id, void* buffer, uint16_t len) -{ +uint8_t tuh_descriptor_get_string_sync(uint8_t daddr, uint8_t index, uint16_t language_id, + void* buffer, uint16_t len) { _CONTROL_SYNC_API(tuh_descriptor_get_string, daddr, index, language_id, buffer, len); } -uint8_t tuh_descriptor_get_manufacturer_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len) -{ +uint8_t tuh_descriptor_get_manufacturer_string_sync(uint8_t daddr, uint16_t language_id, + void* buffer, uint16_t len) { _CONTROL_SYNC_API(tuh_descriptor_get_manufacturer_string, daddr, language_id, buffer, len); } -uint8_t tuh_descriptor_get_product_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len) -{ +uint8_t tuh_descriptor_get_product_string_sync(uint8_t daddr, uint16_t language_id, + void* buffer, uint16_t len) { _CONTROL_SYNC_API(tuh_descriptor_get_product_string, daddr, language_id, buffer, len); } -uint8_t tuh_descriptor_get_serial_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len) -{ +uint8_t tuh_descriptor_get_serial_string_sync(uint8_t daddr, uint16_t language_id, + void* buffer, uint16_t len) { _CONTROL_SYNC_API(tuh_descriptor_get_serial_string, daddr, language_id, buffer, len); } @@ -1140,9 +1186,7 @@ uint8_t tuh_descriptor_get_serial_string_sync(uint8_t daddr, uint16_t language_i // Detaching //--------------------------------------------------------------------+ -TU_ATTR_ALWAYS_INLINE -static inline bool is_hub_addr(uint8_t daddr) -{ +TU_ATTR_ALWAYS_INLINE static inline bool is_hub_addr(uint8_t daddr) { return (CFG_TUH_HUB > 0) && (daddr > CFG_TUH_DEVICE_MAX); } @@ -1167,60 +1211,63 @@ static inline bool is_hub_addr(uint8_t daddr) //} // a device unplugged from rhport:hub_addr:hub_port -static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port) -{ +static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port) { //------------- find the all devices (star-network) under port that is unplugged -------------// // TODO mark as disconnected in ISR, also handle dev0 + uint32_t removing_hubs = 0; + do { + for (uint8_t dev_id = 0; dev_id < TOTAL_DEVICES; dev_id++) { + usbh_device_t* dev = &_usbh_devices[dev_id]; + uint8_t const daddr = dev_id + 1; -#if 0 - // index as hub addr, value is hub port (0xFF for invalid) - uint8_t removing_hubs[CFG_TUH_HUB]; - memset(removing_hubs, TUSB_INDEX_INVALID_8, sizeof(removing_hubs)); + // hub_addr = 0 means roothub, hub_port = 0 means all devices of downstream hub + if (dev->rhport == rhport && dev->connected && + (hub_addr == 0 || dev->hub_addr == hub_addr) && + (hub_port == 0 || dev->hub_port == hub_port)) { + TU_LOG_USBH("[%u:%u:%u] unplugged address = %u\r\n", rhport, hub_addr, hub_port, daddr); - removing_hubs[hub_addr-CFG_TUH_DEVICE_MAX] = hub_port; + if (is_hub_addr(daddr)) { + TU_LOG_USBH(" is a HUB device %u\r\n", daddr); + removing_hubs |= TU_BIT(dev_id - CFG_TUH_DEVICE_MAX); + } else { + // Invoke callback before closing driver (maybe call it later ?) + if (tuh_umount_cb) tuh_umount_cb(daddr); + } - // consecutive non-removing hub - uint8_t nop_count = 0; -#endif + // Close class driver + for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) { + usbh_class_driver_t const* driver = get_driver(drv_id); + if (driver) driver->close(daddr); + } - for (uint8_t dev_id = 0; dev_id < TOTAL_DEVICES; dev_id++) { - usbh_device_t *dev = &_usbh_devices[dev_id]; - uint8_t const daddr = dev_id + 1; + hcd_device_close(rhport, daddr); + clear_device(dev); - // hub_addr = 0 means roothub, hub_port = 0 means all devices of downstream hub - if (dev->rhport == rhport && dev->connected && - (hub_addr == 0 || dev->hub_addr == hub_addr) && - (hub_port == 0 || dev->hub_port == hub_port)) { - TU_LOG_USBH("Device unplugged address = %u\r\n", daddr); - - if (is_hub_addr(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 - hcd_event_t event; - event.rhport = rhport; - event.event_id = HCD_EVENT_DEVICE_REMOVE; - event.connection.hub_addr = daddr; - event.connection.hub_port = 0; - - hcd_event_handler(&event, false); - } else { - // Invoke callback before closing driver (maybe call it later ?) - if (tuh_umount_cb) tuh_umount_cb(daddr); + // abort on-going control xfer on this device if any + if (_ctrl_xfer.daddr == daddr) _set_control_xfer_stage(CONTROL_STAGE_IDLE); } - - // Close class driver - for (uint8_t drv_id = 0; drv_id < USBH_CLASS_DRIVER_COUNT; drv_id++) { - usbh_class_drivers[drv_id].close(daddr); - } - - hcd_device_close(rhport, daddr); - clear_device(dev); - // abort on-going control xfer if any - if (_ctrl_xfer.daddr == daddr) _set_control_xfer_stage(CONTROL_STAGE_IDLE); } - } + + // if removing a hub, we need to remove its downstream devices + #if CFG_TUH_HUB + if (removing_hubs == 0) break; + + // find a marked hub to process + for (uint8_t h_id = 0; h_id < CFG_TUH_HUB; h_id++) { + if (tu_bit_test(removing_hubs, h_id)) { + removing_hubs &= ~TU_BIT(h_id); + + // update hub_addr and hub_port for next loop + hub_addr = h_id + 1 + CFG_TUH_DEVICE_MAX; + hub_port = 0; + break; + } + } + #else + (void) removing_hubs; + break; + #endif + } while(1); } //--------------------------------------------------------------------+ @@ -1260,8 +1307,7 @@ static bool _parse_configuration_descriptor (uint8_t dev_addr, tusb_desc_configu static void enum_full_complete(void); // process device enumeration -static void process_enumeration(tuh_xfer_t* xfer) -{ +static void process_enumeration(tuh_xfer_t* xfer) { // Retry a few times with transfers in enumeration since device can be unstable when starting up enum { ATTEMPT_COUNT_MAX = 3, @@ -1269,19 +1315,20 @@ static void process_enumeration(tuh_xfer_t* xfer) }; static uint8_t failed_count = 0; - if (XFER_RESULT_SUCCESS != xfer->result) - { + if (XFER_RESULT_SUCCESS != xfer->result) { // retry if not reaching max attempt - if ( failed_count < ATTEMPT_COUNT_MAX ) - { + bool retry = _dev0.enumerating && (failed_count < ATTEMPT_COUNT_MAX); + if ( retry ) { failed_count++; osal_task_delay(ATTEMPT_DELAY_MS); // delay a bit TU_LOG1("Enumeration attempt %u\r\n", failed_count); - TU_ASSERT(tuh_control_xfer(xfer), ); - }else - { + retry = tuh_control_xfer(xfer); + } + + if (!retry) { enum_full_complete(); } + return; } failed_count = 0; @@ -1289,229 +1336,221 @@ static void process_enumeration(tuh_xfer_t* xfer) uint8_t const daddr = xfer->daddr; uintptr_t const state = xfer->user_data; - switch(state) - { -#if CFG_TUH_HUB + switch (state) { + #if CFG_TUH_HUB //case ENUM_HUB_GET_STATUS_1: break; - case ENUM_HUB_CLEAR_RESET_1: - { + case ENUM_HUB_CLEAR_RESET_1: { hub_port_status_response_t port_status; memcpy(&port_status, _usbh_ctrl_buf, sizeof(hub_port_status_response_t)); - if ( !port_status.status.connection ) - { + if (!port_status.status.connection) { // device unplugged while delaying, nothing else to do enum_full_complete(); return; } _dev0.speed = (port_status.status.high_speed) ? TUSB_SPEED_HIGH : - (port_status.status.low_speed ) ? TUSB_SPEED_LOW : TUSB_SPEED_FULL; + (port_status.status.low_speed) ? TUSB_SPEED_LOW : TUSB_SPEED_FULL; // Acknowledge Port Reset Change - if (port_status.change.reset) - { - hub_port_clear_reset_change(_dev0.hub_addr, _dev0.hub_port, process_enumeration, ENUM_ADDR0_DEVICE_DESC); + if (port_status.change.reset) { + hub_port_clear_reset_change(_dev0.hub_addr, _dev0.hub_port, + process_enumeration, ENUM_ADDR0_DEVICE_DESC); } + break; } - break; case ENUM_HUB_GET_STATUS_2: osal_task_delay(ENUM_RESET_DELAY); - TU_ASSERT( hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, process_enumeration, ENUM_HUB_CLEAR_RESET_2), ); - break; + TU_ASSERT(hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, + process_enumeration, ENUM_HUB_CLEAR_RESET_2),); + break; - case ENUM_HUB_CLEAR_RESET_2: - { + case ENUM_HUB_CLEAR_RESET_2: { hub_port_status_response_t port_status; memcpy(&port_status, _usbh_ctrl_buf, sizeof(hub_port_status_response_t)); // Acknowledge Port Reset Change if Reset Successful - if (port_status.change.reset) - { - TU_ASSERT( hub_port_clear_reset_change(_dev0.hub_addr, _dev0.hub_port, process_enumeration, ENUM_SET_ADDR), ); + if (port_status.change.reset) { + TU_ASSERT(hub_port_clear_reset_change(_dev0.hub_addr, _dev0.hub_port, + process_enumeration, ENUM_SET_ADDR),); } + break; } - break; -#endif + #endif - case ENUM_ADDR0_DEVICE_DESC: - { + case ENUM_ADDR0_DEVICE_DESC: { // TODO probably doesn't need to open/close each enumeration uint8_t const addr0 = 0; - TU_ASSERT( usbh_edpt_control_open(addr0, 8), ); + TU_ASSERT(usbh_edpt_control_open(addr0, 8),); // Get first 8 bytes of device descriptor for Control Endpoint size TU_LOG_USBH("Get 8 byte of Device Descriptor\r\n"); - TU_ASSERT(tuh_descriptor_get_device(addr0, _usbh_ctrl_buf, 8, process_enumeration, ENUM_SET_ADDR), ); + TU_ASSERT(tuh_descriptor_get_device(addr0, _usbh_ctrl_buf, 8, + process_enumeration, ENUM_SET_ADDR),); + break; } - break; #if 0 - case ENUM_RESET_2: - // TODO not used by now, but may be needed for some devices !? - // Reset device again before Set Address - TU_LOG_USBH("Port reset2 \r\n"); - if (_dev0.hub_addr == 0) - { - // connected directly to roothub - hcd_port_reset( _dev0.rhport ); - osal_task_delay(RESET_DELAY); // TODO may not work for no-OS on MCU that require reset_end() since - // sof of controller may not running while resetting - hcd_port_reset_end(_dev0.rhport); - // TODO: fall through to SET ADDRESS, refactor later - } - #if CFG_TUH_HUB - else - { - // after RESET_DELAY the hub_port_reset() already complete - TU_ASSERT( hub_port_reset(_dev0.hub_addr, _dev0.hub_port, process_enumeration, ENUM_HUB_GET_STATUS_2), ); - break; - } - #endif - TU_ATTR_FALLTHROUGH; + case ENUM_RESET_2: + // TODO not used by now, but may be needed for some devices !? + // Reset device again before Set Address + TU_LOG_USBH("Port reset2 \r\n"); + if (_dev0.hub_addr == 0) { + // connected directly to roothub + hcd_port_reset( _dev0.rhport ); + osal_task_delay(RESET_DELAY); // TODO may not work for no-OS on MCU that require reset_end() since + // sof of controller may not running while resetting + hcd_port_reset_end(_dev0.rhport); + // TODO: fall through to SET ADDRESS, refactor later + } +#if CFG_TUH_HUB + else { + // after RESET_DELAY the hub_port_reset() already complete + TU_ASSERT( hub_port_reset(_dev0.hub_addr, _dev0.hub_port, + process_enumeration, ENUM_HUB_GET_STATUS_2), ); + break; + } +#endif + TU_ATTR_FALLTHROUGH; #endif case ENUM_SET_ADDR: enum_request_set_addr(); - break; + break; - case ENUM_GET_DEVICE_DESC: - { + case ENUM_GET_DEVICE_DESC: { uint8_t const new_addr = (uint8_t) tu_le16toh(xfer->setup->wValue); usbh_device_t* new_dev = get_device(new_addr); - TU_ASSERT(new_dev, ); + TU_ASSERT(new_dev,); new_dev->addressed = 1; // Close device 0 hcd_device_close(_dev0.rhport, 0); // open control pipe for new address - TU_ASSERT( usbh_edpt_control_open(new_addr, new_dev->ep0_size), ); + TU_ASSERT(usbh_edpt_control_open(new_addr, new_dev->ep0_size),); // Get full device descriptor TU_LOG_USBH("Get Device Descriptor\r\n"); - TU_ASSERT(tuh_descriptor_get_device(new_addr, _usbh_ctrl_buf, sizeof(tusb_desc_device_t), process_enumeration, ENUM_GET_9BYTE_CONFIG_DESC), ); + TU_ASSERT(tuh_descriptor_get_device(new_addr, _usbh_ctrl_buf, sizeof(tusb_desc_device_t), + process_enumeration, ENUM_GET_9BYTE_CONFIG_DESC),); + break; } - break; - case ENUM_GET_9BYTE_CONFIG_DESC: - { - tusb_desc_device_t const * desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; + case ENUM_GET_9BYTE_CONFIG_DESC: { + tusb_desc_device_t const* desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; usbh_device_t* dev = get_device(daddr); - TU_ASSERT(dev, ); + TU_ASSERT(dev,); - dev->vid = desc_device->idVendor; - dev->pid = desc_device->idProduct; + dev->vid = desc_device->idVendor; + dev->pid = desc_device->idProduct; dev->i_manufacturer = desc_device->iManufacturer; - dev->i_product = desc_device->iProduct; - dev->i_serial = desc_device->iSerialNumber; + dev->i_product = desc_device->iProduct; + dev->i_serial = desc_device->iSerialNumber; - // if (tuh_attach_cb) tuh_attach_cb((tusb_desc_device_t*) _usbh_ctrl_buf); + // if (tuh_attach_cb) tuh_attach_cb((tusb_desc_device_t*) _usbh_ctrl_buf); // Get 9-byte for total length uint8_t const config_idx = CONFIG_NUM - 1; TU_LOG_USBH("Get Configuration[0] Descriptor (9 bytes)\r\n"); - TU_ASSERT( tuh_descriptor_get_configuration(daddr, config_idx, _usbh_ctrl_buf, 9, process_enumeration, ENUM_GET_FULL_CONFIG_DESC), ); + TU_ASSERT(tuh_descriptor_get_configuration(daddr, config_idx, _usbh_ctrl_buf, 9, + process_enumeration, ENUM_GET_FULL_CONFIG_DESC),); + break; } - break; - case ENUM_GET_FULL_CONFIG_DESC: - { - uint8_t const * desc_config = _usbh_ctrl_buf; + case ENUM_GET_FULL_CONFIG_DESC: { + uint8_t const* desc_config = _usbh_ctrl_buf; // Use offsetof to avoid pointer to the odd/misaligned address - uint16_t const total_len = tu_le16toh( tu_unaligned_read16(desc_config + offsetof(tusb_desc_configuration_t, wTotalLength)) ); + uint16_t const total_len = tu_le16toh( + tu_unaligned_read16(desc_config + offsetof(tusb_desc_configuration_t, wTotalLength))); // TODO not enough buffer to hold configuration descriptor - TU_ASSERT(total_len <= CFG_TUH_ENUMERATION_BUFSIZE, ); + TU_ASSERT(total_len <= CFG_TUH_ENUMERATION_BUFSIZE,); // Get full configuration descriptor uint8_t const config_idx = CONFIG_NUM - 1; TU_LOG_USBH("Get Configuration[0] Descriptor\r\n"); - TU_ASSERT( tuh_descriptor_get_configuration(daddr, config_idx, _usbh_ctrl_buf, total_len, process_enumeration, ENUM_SET_CONFIG), ); + TU_ASSERT(tuh_descriptor_get_configuration(daddr, config_idx, _usbh_ctrl_buf, total_len, + process_enumeration, ENUM_SET_CONFIG),); + break; } - break; case ENUM_SET_CONFIG: - // Parse configuration & set up drivers - // Driver open aren't allowed to make any usb transfer yet - TU_ASSERT( _parse_configuration_descriptor(daddr, (tusb_desc_configuration_t*) _usbh_ctrl_buf), ); + TU_ASSERT(tuh_configuration_set(daddr, CONFIG_NUM, process_enumeration, ENUM_CONFIG_DRIVER),); + break; - TU_ASSERT( tuh_configuration_set(daddr, CONFIG_NUM, process_enumeration, ENUM_CONFIG_DRIVER), ); - break; - - case ENUM_CONFIG_DRIVER: - { + case ENUM_CONFIG_DRIVER: { TU_LOG_USBH("Device configured\r\n"); usbh_device_t* dev = get_device(daddr); - TU_ASSERT(dev, ); + TU_ASSERT(dev,); dev->configured = 1; + // Parse configuration & set up drivers + // driver_open() must not make any usb transfer + TU_ASSERT(_parse_configuration_descriptor(daddr, (tusb_desc_configuration_t*) _usbh_ctrl_buf),); + // Start the Set Configuration process for interfaces (itf = TUSB_INDEX_INVALID_8) // Since driver can perform control transfer within its set_config, this is done asynchronously. // The process continue with next interface when class driver complete its sequence with usbh_driver_set_config_complete() // TODO use separated API instead of using TUSB_INDEX_INVALID_8 usbh_driver_set_config_complete(daddr, TUSB_INDEX_INVALID_8); + break; } - break; default: // stop enumeration if unknown state enum_full_complete(); - break; + break; } } -static bool enum_new_device(hcd_event_t* event) -{ - _dev0.rhport = event->rhport; +static bool enum_new_device(hcd_event_t* event) { + _dev0.rhport = event->rhport; _dev0.hub_addr = event->connection.hub_addr; _dev0.hub_port = event->connection.hub_port; - if (_dev0.hub_addr == 0) - { + if (_dev0.hub_addr == 0) { // connected/disconnected directly with roothub hcd_port_reset(_dev0.rhport); osal_task_delay(ENUM_RESET_DELAY); // TODO may not work for no-OS on MCU that require reset_end() since - // sof of controller may not running while resetting - hcd_port_reset_end( _dev0.rhport); + // sof of controller may not running while resetting + hcd_port_reset_end(_dev0.rhport); // wait until device connection is stable TODO non blocking osal_task_delay(ENUM_CONTACT_DEBOUNCING_DELAY); // device unplugged while delaying - if ( !hcd_port_connect_status(_dev0.rhport) ) { + if (!hcd_port_connect_status(_dev0.rhport)) { enum_full_complete(); return true; } - _dev0.speed = hcd_port_speed_get(_dev0.rhport ); + _dev0.speed = hcd_port_speed_get(_dev0.rhport); TU_LOG_USBH("%s Speed\r\n", tu_str_speed[_dev0.speed]); // fake transfer to kick-off the enumeration process tuh_xfer_t xfer; - xfer.daddr = 0; - xfer.result = XFER_RESULT_SUCCESS; + xfer.daddr = 0; + xfer.result = XFER_RESULT_SUCCESS; xfer.user_data = ENUM_ADDR0_DEVICE_DESC; - process_enumeration(&xfer); - } #if CFG_TUH_HUB - else - { + else { // connected/disconnected via external hub // wait until device connection is stable TODO non blocking osal_task_delay(ENUM_CONTACT_DEBOUNCING_DELAY); // ENUM_HUB_GET_STATUS //TU_ASSERT( hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, enum_hub_get_status0_complete, 0) ); - TU_ASSERT( hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, process_enumeration, ENUM_HUB_CLEAR_RESET_1) ); + TU_ASSERT(hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, + process_enumeration, ENUM_HUB_CLEAR_RESET_1)); } #endif // hub @@ -1537,58 +1576,48 @@ static uint8_t get_new_address(bool is_hub) { return 0; // invalid address } -static bool enum_request_set_addr(void) -{ - tusb_desc_device_t const * desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; +static bool enum_request_set_addr(void) { + tusb_desc_device_t const* desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; // Get new address uint8_t const new_addr = get_new_address(desc_device->bDeviceClass == TUSB_CLASS_HUB); TU_ASSERT(new_addr != 0); - TU_LOG_USBH("Set Address = %d\r\n", new_addr); usbh_device_t* new_dev = get_device(new_addr); - - new_dev->rhport = _dev0.rhport; - new_dev->hub_addr = _dev0.hub_addr; - new_dev->hub_port = _dev0.hub_port; - new_dev->speed = _dev0.speed; + new_dev->rhport = _dev0.rhport; + new_dev->hub_addr = _dev0.hub_addr; + new_dev->hub_port = _dev0.hub_port; + new_dev->speed = _dev0.speed; new_dev->connected = 1; - new_dev->ep0_size = desc_device->bMaxPacketSize0; + new_dev->ep0_size = desc_device->bMaxPacketSize0; - tusb_control_request_t const request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_DEVICE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_OUT - }, - .bRequest = TUSB_REQ_SET_ADDRESS, - .wValue = tu_htole16(new_addr), - .wIndex = 0, - .wLength = 0 + tusb_control_request_t const request = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_OUT + }, + .bRequest = TUSB_REQ_SET_ADDRESS, + .wValue = tu_htole16(new_addr), + .wIndex = 0, + .wLength = 0 + }; + tuh_xfer_t xfer = { + .daddr = 0, // dev0 + .ep_addr = 0, + .setup = &request, + .buffer = NULL, + .complete_cb = process_enumeration, + .user_data = ENUM_GET_DEVICE_DESC }; - tuh_xfer_t xfer = - { - .daddr = 0, // dev0 - .ep_addr = 0, - .setup = &request, - .buffer = NULL, - .complete_cb = process_enumeration, - .user_data = ENUM_GET_DEVICE_DESC - }; - - TU_ASSERT( tuh_control_xfer(&xfer) ); - + TU_ASSERT(tuh_control_xfer(&xfer)); return true; } -static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg) -{ +static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg) { usbh_device_t* dev = get_device(dev_addr); - uint16_t const total_len = tu_le16toh(desc_cfg->wTotalLength); uint8_t const* desc_end = ((uint8_t const*) desc_cfg) + total_len; uint8_t const* p_desc = tu_desc_next(desc_cfg); @@ -1596,13 +1625,11 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur TU_LOG_USBH("Parsing Configuration descriptor (wTotalLength = %u)\r\n", total_len); // parse each interfaces - while( p_desc < desc_end ) - { + while( p_desc < desc_end ) { uint8_t assoc_itf_count = 1; // Class will always starts with Interface Association (if any) and then Interface descriptor - if ( TUSB_DESC_INTERFACE_ASSOCIATION == tu_desc_type(p_desc) ) - { + if ( TUSB_DESC_INTERFACE_ASSOCIATION == tu_desc_type(p_desc) ) { tusb_desc_interface_assoc_t const * desc_iad = (tusb_desc_interface_assoc_t const *) p_desc; assoc_itf_count = desc_iad->bInterfaceCount; @@ -1622,8 +1649,7 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur if (1 == assoc_itf_count && TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass && AUDIO_SUBCLASS_CONTROL == desc_itf->bInterfaceSubClass && - AUDIO_FUNC_PROTOCOL_CODE_UNDEF == desc_itf->bInterfaceProtocol) - { + AUDIO_FUNC_PROTOCOL_CODE_UNDEF == desc_itf->bInterfaceProtocol) { assoc_itf_count = 2; } #endif @@ -1633,8 +1659,7 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur // manually force associated count = 2 if (1 == assoc_itf_count && TUSB_CLASS_CDC == desc_itf->bInterfaceClass && - CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == desc_itf->bInterfaceSubClass) - { + CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == desc_itf->bInterfaceSubClass) { assoc_itf_count = 2; } #endif @@ -1643,18 +1668,14 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur TU_ASSERT(drv_len >= sizeof(tusb_desc_interface_t)); // Find driver for this interface - for (uint8_t drv_id = 0; drv_id < USBH_CLASS_DRIVER_COUNT; drv_id++) - { - usbh_class_driver_t const * driver = &usbh_class_drivers[drv_id]; - - if ( driver->open(dev->rhport, dev_addr, desc_itf, drv_len) ) - { + for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) { + usbh_class_driver_t const * driver = get_driver(drv_id); + if (driver && driver->open(dev->rhport, dev_addr, desc_itf, drv_len) ) { // open successfully TU_LOG_USBH(" %s opened\r\n", driver->name); // bind (associated) interfaces to found driver - for(uint8_t i=0; ibInterfaceNumber+i; // Interface number must not be used already @@ -1668,10 +1689,9 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur break; // exit driver find loop } - if( drv_id >= USBH_CLASS_DRIVER_COUNT ) - { - 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); + if ( drv_id == TOTAL_DRIVER_COUNT - 1 ) { + TU_LOG_USBH("[%u:%u] Interface %u: class = %u subclass = %u protocol = %u is not supported\r\n", + dev->rhport, dev_addr, desc_itf->bInterfaceNumber, desc_itf->bInterfaceClass, desc_itf->bInterfaceSubClass, desc_itf->bInterfaceProtocol); } } @@ -1682,19 +1702,16 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur return true; } -void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) -{ +void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) { usbh_device_t* dev = get_device(dev_addr); - for(itf_num++; itf_num < CFG_TUH_INTERFACE_MAX; itf_num++) - { + for(itf_num++; itf_num < CFG_TUH_INTERFACE_MAX; itf_num++) { // continue with next valid interface // IAD binding interface such as CDCs should return itf_num + 1 when complete // with usbh_driver_set_config_complete() uint8_t const drv_id = dev->itf2drv[itf_num]; - if (drv_id != TUSB_INDEX_INVALID_8) - { - usbh_class_driver_t const * driver = &usbh_class_drivers[drv_id]; + usbh_class_driver_t const * driver = get_driver(drv_id); + if (driver) { TU_LOG_USBH("%s set config: itf = %u\r\n", driver->name, itf_num); driver->set_config(dev_addr, itf_num); break; @@ -1702,23 +1719,19 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) } // all interface are configured - if (itf_num == CFG_TUH_INTERFACE_MAX) - { + if (itf_num == CFG_TUH_INTERFACE_MAX) { enum_full_complete(); - if (is_hub_addr(dev_addr)) - { - TU_LOG(CFG_TUH_LOG_LEVEL, "HUB address = %u is mounted\r\n", dev_addr); - }else - { + if (is_hub_addr(dev_addr)) { + TU_LOG_USBH("HUB address = %u is mounted\r\n", dev_addr); + }else { // Invoke callback if available if (tuh_mount_cb) tuh_mount_cb(dev_addr); } } } -static void enum_full_complete(void) -{ +static void enum_full_complete(void) { // mark enumeration as complete _dev0.enumerating = 0; diff --git a/src/host/usbh.h b/src/host/usbh.h index 684e8240e..359684169 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -73,11 +73,25 @@ typedef struct { tusb_desc_interface_t desc; } tuh_itf_info_t; -// ConfigID for tuh_config() +// ConfigID for tuh_configure() enum { - TUH_CFGID_RPI_PIO_USB_CONFIGURATION = OPT_MCU_RP2040 << 8 // cfg_param: pio_usb_configuration_t + TUH_CFGID_INVALID = 0, + TUH_CFGID_RPI_PIO_USB_CONFIGURATION = 100, // cfg_param: pio_usb_configuration_t + TUH_CFGID_MAX3421 = 200, }; +typedef struct { + uint8_t max_nak; // max NAK per endpoint per frame + uint8_t cpuctl; // R16: CPU Control Register + uint8_t pinctl; // R17: Pin Control Register. FDUPSPI bit is ignored +} tuh_configure_max3421_t; + +typedef union { + // For TUH_CFGID_RPI_PIO_USB_CONFIGURATION use pio_usb_configuration_t + + tuh_configure_max3421_t max3421; +} tuh_configure_param_t; + //--------------------------------------------------------------------+ // APPLICATION CALLBACK //--------------------------------------------------------------------+ @@ -90,9 +104,12 @@ TU_ATTR_WEAK void tuh_mount_cb (uint8_t daddr); // Invoked when a device failed to mount during enumeration process // TU_ATTR_WEAK void tuh_mount_failed_cb (uint8_t daddr); -/// Invoked when a device is unmounted (detached) +// Invoked when a device is unmounted (detached) TU_ATTR_WEAK void tuh_umount_cb(uint8_t daddr); +// Invoked when there is a new usb event, which need to be processed by tuh_task()/tuh_task_ext() +void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr); + //--------------------------------------------------------------------+ // APPLICATION API //--------------------------------------------------------------------+ @@ -106,7 +123,11 @@ bool tuh_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param); // Init host stack bool tuh_init(uint8_t rhport); +// Deinit host stack on rhport +bool tuh_deinit(uint8_t rhport); + // Check if host stack is already initialized with any roothub ports +// To check if an rhport is initialized, use tuh_rhport_is_active() bool tuh_inited(void); // Task function should be called in main/rtos loop, extended version of tuh_task() @@ -124,11 +145,16 @@ void tuh_task(void) { bool tuh_task_event_ready(void); #ifndef _TUSB_HCD_H_ -extern void hcd_int_handler(uint8_t rhport); +extern void hcd_int_handler(uint8_t rhport, bool in_isr); #endif -// Interrupt handler, name alias to HCD -#define tuh_int_handler hcd_int_handler +// Interrupt handler alias to HCD with in_isr as optional parameter +// - tuh_int_handler(rhport) --> hcd_int_handler(rhport, true) +// - tuh_int_handler(rhport, in_isr) --> hcd_int_handler(rhport, in_isr) +// Note: this is similar to TU_VERIFY(), _GET_3RD_ARG() is defined in tusb_verify.h +#define _tuh_int_handler_1arg(_rhport) hcd_int_handler(_rhport, true) +#define _tuh_int_hanlder_2arg(_rhport, _in_isr) hcd_int_handler(_rhport, _in_isr) +#define tuh_int_handler(...) _GET_3RD_ARG(__VA_ARGS__, _tuh_int_hanlder_2arg, _tuh_int_handler_1arg, _dummy)(__VA_ARGS__) // Check if roothub port is initialized and active as a host bool tuh_rhport_is_active(uint8_t rhport); diff --git a/src/host/usbh_classdriver.h b/src/host/usbh_pvt.h similarity index 78% rename from src/host/usbh_classdriver.h rename to src/host/usbh_pvt.h index 308b4418a..95de915e9 100644 --- a/src/host/usbh_classdriver.h +++ b/src/host/usbh_pvt.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_USBH_CLASSDRIVER_H_ -#define _TUSB_USBH_CLASSDRIVER_H_ +#ifndef _TUSB_USBH_PVT_H_ +#define _TUSB_USBH_PVT_H_ #include "osal/osal.h" #include "common/tusb_fifo.h" @@ -35,12 +35,11 @@ extern "C" { #endif -// 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(CFG_TUH_LOG_LEVEL, __VA_ARGS__) +#define TU_LOG_USBH(...) TU_LOG(CFG_TUH_LOG_LEVEL, __VA_ARGS__) +#define TU_LOG_MEM_USBH(...) TU_LOG_MEM(CFG_TUH_LOG_LEVEL, __VA_ARGS__) +#define TU_LOG_BUF_USBH(...) TU_LOG_BUF(CFG_TUH_LOG_LEVEL, __VA_ARGS__) +#define TU_LOG_INT_USBH(...) TU_LOG_INT(CFG_TUH_LOG_LEVEL, __VA_ARGS__) +#define TU_LOG_HEX_USBH(...) TU_LOG_HEX(CFG_TUH_LOG_LEVEL, __VA_ARGS__) enum { USBH_EPSIZE_BULK_MAX = (TUH_OPT_HIGH_SPEED ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS) @@ -51,17 +50,20 @@ enum { //--------------------------------------------------------------------+ typedef struct { - #if CFG_TUSB_DEBUG >= 2 char const* name; - #endif - - void (* const init )(void); + bool (* const init )(void); + bool (* const deinit )(void); bool (* const open )(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool (* const set_config )(uint8_t dev_addr, uint8_t itf_num); bool (* const xfer_cb )(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); void (* const close )(uint8_t dev_addr); } usbh_class_driver_t; +// Invoked when initializing host stack to get additional class drivers. +// Can be implemented by application to extend/overwrite class driver support. +// Note: The drivers array must be accessible at all time when stack is active +usbh_class_driver_t const* usbh_app_driver_get_cb(uint8_t* driver_count) TU_ATTR_WEAK; + // Call by class driver to tell USBH that it has complete the enumeration void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num); @@ -71,6 +73,8 @@ uint8_t* usbh_get_enum_buf(void); void usbh_int_set(bool enabled); +void usbh_defer_func(osal_task_func_t func, void *param, bool in_isr); + //--------------------------------------------------------------------+ // USBH Endpoint API //--------------------------------------------------------------------+ @@ -80,12 +84,10 @@ bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * b tuh_xfer_cb_t complete_cb, uintptr_t user_data); TU_ATTR_ALWAYS_INLINE -static inline bool usbh_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) -{ +static inline bool usbh_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) { return usbh_edpt_xfer_with_callback(dev_addr, ep_addr, buffer, total_bytes, NULL, 0); } - // Claim an endpoint before submitting a transfer. // If caller does not make any transfer, it must release endpoint for others. bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr); diff --git a/src/osal/osal.h b/src/osal/osal.h index f092e8ffb..8f45ea5c1 100644 --- a/src/osal/osal.h +++ b/src/osal/osal.h @@ -74,15 +74,18 @@ typedef void (*osal_task_func_t)( void * ); // Should be implemented as static inline function in osal_port.h header /* osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef); + bool osal_semaphore_delete(osal_semaphore_t semd_hdl); bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr); bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec); void osal_semaphore_reset(osal_semaphore_t sem_hdl); // TODO removed osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef); + bool osal_mutex_delete(osal_mutex_t mutex_hdl) bool osal_mutex_lock (osal_mutex_t sem_hdl, uint32_t msec); bool osal_mutex_unlock(osal_mutex_t mutex_hdl); osal_queue_t osal_queue_create(osal_queue_def_t* qdef); + bool osal_queue_delete(osal_queue_t qhdl); bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec); bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr); bool osal_queue_empty(osal_queue_t qhdl); diff --git a/src/osal/osal_freertos.h b/src/osal/osal_freertos.h index 501e0bddd..f1f05f353 100644 --- a/src/osal/osal_freertos.h +++ b/src/osal/osal_freertos.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_OSAL_FREERTOS_H_ -#define _TUSB_OSAL_FREERTOS_H_ +#ifndef TUSB_OSAL_FREERTOS_H_ +#define TUSB_OSAL_FREERTOS_H_ // FreeRTOS Headers #include TU_INCLUDE_PATH(CFG_TUSB_OS_INC_PATH,FreeRTOS.h) @@ -114,6 +114,11 @@ TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_ #endif } +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) { + vSemaphoreDelete(semd_hdl); + return true; +} + TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { if ( !in_isr ) { return xSemaphoreGive(sem_hdl) != 0; @@ -153,6 +158,11 @@ TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_de #endif } +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) { + vSemaphoreDelete(mutex_hdl); + return true; +} + TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) { return osal_semaphore_wait(mutex_hdl, msec); } @@ -181,6 +191,11 @@ TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_de return q; } +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) { + vQueueDelete(qhdl); + return true; +} + TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) { return xQueueReceive(qhdl, data, _osal_ms2tick(msec)); } diff --git a/src/osal/osal_mynewt.h b/src/osal/osal_mynewt.h index b8ea2087c..16def0d2a 100644 --- a/src/osal/osal_mynewt.h +++ b/src/osal/osal_mynewt.h @@ -36,8 +36,7 @@ //--------------------------------------------------------------------+ // TASK API //--------------------------------------------------------------------+ -TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) -{ +TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { os_time_delay( os_time_ms_to_ticks32(msec) ); } @@ -47,25 +46,26 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) typedef struct os_sem osal_semaphore_def_t; typedef struct os_sem* osal_semaphore_t; -TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) -{ +TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) { return (os_sem_init(semdef, 0) == OS_OK) ? (osal_semaphore_t) semdef : NULL; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) { + (void) semd_hdl; + return true; // nothing to do +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { (void) in_isr; return os_sem_release(sem_hdl) == OS_OK; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? OS_TIMEOUT_NEVER : os_time_ms_to_ticks32(msec); return os_sem_pend(sem_hdl, ticks) == OS_OK; } -static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) -{ +static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) { // TODO implement later } @@ -75,19 +75,21 @@ static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) typedef struct os_mutex osal_mutex_def_t; typedef struct os_mutex* osal_mutex_t; -TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) -{ +TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) { return (os_mutex_init(mdef) == OS_OK) ? (osal_mutex_t) mdef : NULL; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) { + (void) mutex_hdl; + return true; // nothing to do +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) { uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? OS_TIMEOUT_NEVER : os_time_ms_to_ticks32(msec); return os_mutex_pend(mutex_hdl, ticks) == OS_OK; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { return os_mutex_release(mutex_hdl) == OS_OK; } @@ -101,8 +103,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hd static struct os_event _name##_##evbuf[_depth];\ osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf, .evbuf = _name##_##evbuf};\ -typedef struct -{ +typedef struct { uint16_t depth; uint16_t item_sz; void* buf; @@ -116,17 +117,20 @@ typedef struct typedef osal_queue_def_t* osal_queue_t; -TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) -{ - if ( OS_OK != os_mempool_init(&qdef->mpool, qdef->depth, qdef->item_sz, qdef->buf, "usbd queue") ) return NULL; - if ( OS_OK != os_mempool_init(&qdef->epool, qdef->depth, sizeof(struct os_event), qdef->evbuf, "usbd evqueue") ) return NULL; +TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { + if ( OS_OK != os_mempool_init(&qdef->mpool, qdef->depth, qdef->item_sz, qdef->buf, "usb queue") ) return NULL; + if ( OS_OK != os_mempool_init(&qdef->epool, qdef->depth, sizeof(struct os_event), qdef->evbuf, "usb evqueue") ) return NULL; os_eventq_init(&qdef->evq); return (osal_queue_t) qdef; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) { + (void) qhdl; + return true; // nothing to do +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) { (void) msec; // os_eventq_get() does not take timeout, always behave as msec = WAIT_FOREVER struct os_event* ev; @@ -139,8 +143,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, v return true; } -static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) -{ +static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) { (void) in_isr; // get a block from mem pool for data @@ -150,8 +153,7 @@ static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in // get a block from event pool to put into queue struct os_event* ev = (struct os_event*) os_memblock_get(&qhdl->epool); - if (!ev) - { + if (!ev) { os_memblock_put(&qhdl->mpool, ptr); return false; } @@ -163,8 +165,7 @@ static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in return true; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { return STAILQ_EMPTY(&qhdl->evq.evq_list); } diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 76e77c25d..c93f7a86c 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -24,11 +24,11 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_OSAL_NONE_H_ -#define _TUSB_OSAL_NONE_H_ +#ifndef TUSB_OSAL_NONE_H_ +#define TUSB_OSAL_NONE_H_ #ifdef __cplusplus - extern "C" { +extern "C" { #endif //--------------------------------------------------------------------+ @@ -43,39 +43,40 @@ TU_ATTR_WEAK void osal_task_delay(uint32_t msec); //--------------------------------------------------------------------+ // Binary Semaphore API //--------------------------------------------------------------------+ -typedef struct -{ +typedef struct { volatile uint16_t count; -}osal_semaphore_def_t; +} osal_semaphore_def_t; typedef osal_semaphore_def_t* osal_semaphore_t; -TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) -{ +TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) { semdef->count = 0; return semdef; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) { + (void) semd_hdl; + return true; // nothing to do +} + + +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { (void) in_isr; sem_hdl->count++; return true; } // TODO blocking for now -TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { (void) msec; - while (sem_hdl->count == 0) { } + while (sem_hdl->count == 0) {} sem_hdl->count--; return true; } -TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) -{ +TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) { sem_hdl->count = 0; } @@ -90,19 +91,21 @@ typedef osal_semaphore_t osal_mutex_t; // Note: multiple cores MCUs usually do provide IPC API for mutex // or we can use std atomic function -TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) -{ +TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) { mdef->count = 1; return mdef; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) { + (void) mutex_hdl; + return true; // nothing to do +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) { return osal_semaphore_wait(mutex_hdl, msec); } -TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { return osal_semaphore_post(mutex_hdl, false); } @@ -119,11 +122,10 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hd //--------------------------------------------------------------------+ #include "common/tusb_fifo.h" -typedef struct -{ - void (*interrupt_set)(bool); +typedef struct { + void (* interrupt_set)(bool); tu_fifo_t ff; -}osal_queue_def_t; +} osal_queue_def_t; typedef osal_queue_def_t* osal_queue_t; @@ -136,27 +138,28 @@ typedef osal_queue_def_t* osal_queue_t; } // lock queue by disable USB interrupt -TU_ATTR_ALWAYS_INLINE static inline void _osal_q_lock(osal_queue_t qhdl) -{ +TU_ATTR_ALWAYS_INLINE static inline void _osal_q_lock(osal_queue_t qhdl) { // disable dcd/hcd interrupt qhdl->interrupt_set(false); } // unlock queue -TU_ATTR_ALWAYS_INLINE static inline void _osal_q_unlock(osal_queue_t qhdl) -{ +TU_ATTR_ALWAYS_INLINE static inline void _osal_q_unlock(osal_queue_t qhdl) { // enable dcd/hcd interrupt qhdl->interrupt_set(true); } -TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) -{ +TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { tu_fifo_clear(&qdef->ff); return (osal_queue_t) qdef; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) { + (void) qhdl; + return true; // nothing to do +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) { (void) msec; // not used, always behave as msec = 0 _osal_q_lock(qhdl); @@ -166,8 +169,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, v return success; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const* data, bool in_isr) { if (!in_isr) { _osal_q_lock(qhdl); } @@ -178,20 +180,17 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void _osal_q_unlock(qhdl); } - TU_ASSERT(success); - return success; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { // Skip queue lock/unlock since this function is primarily called // with interrupt disabled before going into low power mode return tu_fifo_empty(&qhdl->ff); } #ifdef __cplusplus - } +} #endif -#endif /* _TUSB_OSAL_NONE_H_ */ +#endif diff --git a/src/osal/osal_pico.h b/src/osal/osal_pico.h index e6efa0968..315de0950 100644 --- a/src/osal/osal_pico.h +++ b/src/osal/osal_pico.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_OSAL_PICO_H_ -#define _TUSB_OSAL_PICO_H_ +#ifndef TUSB_OSAL_PICO_H_ +#define TUSB_OSAL_PICO_H_ #include "pico/time.h" #include "pico/sem.h" @@ -33,42 +33,42 @@ #include "pico/critical_section.h" #ifdef __cplusplus - extern "C" { +extern "C" { #endif //--------------------------------------------------------------------+ // TASK API //--------------------------------------------------------------------+ -TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) -{ +TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { sleep_ms(msec); } //--------------------------------------------------------------------+ // Binary Semaphore API //--------------------------------------------------------------------+ -typedef struct semaphore osal_semaphore_def_t, *osal_semaphore_t; +typedef struct semaphore osal_semaphore_def_t, * osal_semaphore_t; -TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) -{ +TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) { sem_init(semdef, 0, 255); return semdef; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) { + (void) semd_hdl; + return true; // nothing to do +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { (void) in_isr; sem_release(sem_hdl); return true; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { return sem_acquire_timeout_ms(sem_hdl, msec); } -TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) -{ +TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) { sem_reset(sem_hdl, 0); } @@ -76,21 +76,23 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t s // MUTEX API // Within tinyusb, mutex is never used in ISR context //--------------------------------------------------------------------+ -typedef struct mutex osal_mutex_def_t, *osal_mutex_t; +typedef struct mutex osal_mutex_def_t, * osal_mutex_t; -TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) -{ +TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) { mutex_init(mdef); return mdef; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) { + (void) mutex_hdl; + return true; // nothing to do +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) { return mutex_enter_timeout_ms(mutex_hdl, msec); } -TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { mutex_exit(mutex_hdl); return true; } @@ -100,75 +102,53 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hd //--------------------------------------------------------------------+ #include "common/tusb_fifo.h" -typedef struct -{ - tu_fifo_t ff; - struct critical_section critsec; // osal_queue may be used in IRQs, so need critical section +typedef struct { + tu_fifo_t ff; + struct critical_section critsec; // osal_queue may be used in IRQs, so need critical section } osal_queue_def_t; typedef osal_queue_def_t* osal_queue_t; // role device/host is used by OS NONE for mutex (disable usb isr) only -#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ +#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ uint8_t _name##_buf[_depth*sizeof(_type)]; \ osal_queue_def_t _name = { \ .ff = TU_FIFO_INIT(_name##_buf, _depth, _type, false) \ } -// lock queue by disable USB interrupt -TU_ATTR_ALWAYS_INLINE static inline void _osal_q_lock(osal_queue_t qhdl) -{ - critical_section_enter_blocking(&qhdl->critsec); -} - -// unlock queue -TU_ATTR_ALWAYS_INLINE static inline void _osal_q_unlock(osal_queue_t qhdl) -{ - critical_section_exit(&qhdl->critsec); -} - -TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) -{ +TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { critical_section_init(&qdef->critsec); tu_fifo_clear(&qdef->ff); return (osal_queue_t) qdef; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) { + osal_queue_def_t* qdef = (osal_queue_def_t*) qhdl; + critical_section_deinit(&qdef->critsec); + return true; +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) { (void) msec; // not used, always behave as msec = 0 - // TODO: revisit... docs say that mutexes are never used from IRQ context, - // however osal_queue_recieve may be. therefore my assumption is that - // the fifo mutex is not populated for queues used from an IRQ context - //assert(!qhdl->ff.mutex); - - _osal_q_lock(qhdl); + critical_section_enter_blocking(&qhdl->critsec); bool success = tu_fifo_read(&qhdl->ff, data); - _osal_q_unlock(qhdl); + critical_section_exit(&qhdl->critsec); return success; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) -{ - // TODO: revisit... docs say that mutexes are never used from IRQ context, - // however osal_queue_recieve may be. therefore my assumption is that - // the fifo mutex is not populated for queues used from an IRQ context - //assert(!qhdl->ff.mutex); +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const* data, bool in_isr) { (void) in_isr; - _osal_q_lock(qhdl); + critical_section_enter_blocking(&qhdl->critsec); bool success = tu_fifo_write(&qhdl->ff, data); - _osal_q_unlock(qhdl); - - TU_ASSERT(success); + critical_section_exit(&qhdl->critsec); return success; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { // TODO: revisit; whether this is true or not currently, tu_fifo_empty is a single // volatile read. @@ -178,7 +158,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) } #ifdef __cplusplus - } +} #endif -#endif /* _TUSB_OSAL_PICO_H_ */ +#endif diff --git a/src/osal/osal_rtthread.h b/src/osal/osal_rtthread.h index 18eb9c693..c27814835 100644 --- a/src/osal/osal_rtthread.h +++ b/src/osal/osal_rtthread.h @@ -2,6 +2,7 @@ * The MIT License (MIT) * * Copyright (c) 2020 tfx2001 (2479727366@qq.com) + * Copyright (c) 2020 yekai (2857693944@qq.com) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,8 +25,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_OSAL_RTTHREAD_H_ -#define _TUSB_OSAL_RTTHREAD_H_ +#ifndef TUSB_OSAL_RTTHREAD_H_ +#define TUSB_OSAL_RTTHREAD_H_ // RT-Thread Headers #include "rtthread.h" @@ -47,23 +48,27 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { typedef struct rt_semaphore osal_semaphore_def_t; typedef rt_sem_t osal_semaphore_t; -TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t -osal_semaphore_create(osal_semaphore_def_t *semdef) { - rt_sem_init(semdef, "tusb", 0, RT_IPC_FLAG_PRIO); - return semdef; +TU_ATTR_ALWAYS_INLINE static inline +osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t *semdef) { + rt_sem_init(semdef, "tusb", 0, RT_IPC_FLAG_PRIO); + return semdef; +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) { + return RT_EOK == rt_sem_detach(semd_hdl); } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { - (void) in_isr; - return rt_sem_release(sem_hdl) == RT_EOK; + (void) in_isr; + return rt_sem_release(sem_hdl) == RT_EOK; } TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { - return rt_sem_take(sem_hdl, rt_tick_from_millisecond((rt_int32_t) msec)) == RT_EOK; + return rt_sem_take(sem_hdl, rt_tick_from_millisecond((rt_int32_t) msec)) == RT_EOK; } TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) { - rt_sem_control(sem_hdl, RT_IPC_CMD_RESET, 0); + rt_sem_control(sem_hdl, RT_IPC_CMD_RESET, 0); } //--------------------------------------------------------------------+ @@ -73,16 +78,20 @@ typedef struct rt_mutex osal_mutex_def_t; typedef rt_mutex_t osal_mutex_t; TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t *mdef) { - rt_mutex_init(mdef, "tusb", RT_IPC_FLAG_PRIO); - return mdef; + rt_mutex_init(mdef, "tusb", RT_IPC_FLAG_PRIO); + return mdef; +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) { + return RT_EOK == rt_mutex_detach(mutex_hdl); } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) { - return rt_mutex_take(mutex_hdl, rt_tick_from_millisecond((rt_int32_t) msec)) == RT_EOK; + return rt_mutex_take(mutex_hdl, rt_tick_from_millisecond((rt_int32_t) msec)) == RT_EOK; } TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { - return rt_mutex_release(mutex_hdl) == RT_EOK; + return rt_mutex_release(mutex_hdl) == RT_EOK; } //--------------------------------------------------------------------+ @@ -105,28 +114,35 @@ typedef struct { typedef rt_mq_t osal_queue_t; TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t *qdef) { - rt_mq_init(&(qdef->sq), "tusb", qdef->buf, qdef->item_sz, - qdef->item_sz * qdef->depth, RT_IPC_FLAG_PRIO); - return &(qdef->sq); + rt_mq_init(&(qdef->sq), "tusb", qdef->buf, qdef->item_sz, + qdef->item_sz * qdef->depth, RT_IPC_FLAG_PRIO); + return &(qdef->sq); +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) { + return RT_EOK == rt_mq_detach(qhdl); } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void *data, uint32_t msec) { - - rt_tick_t tick = rt_tick_from_millisecond((rt_int32_t) msec); - return rt_mq_recv(qhdl, data, qhdl->msg_size, tick) == RT_EOK; + rt_tick_t tick = rt_tick_from_millisecond((rt_int32_t) msec); +#if RT_VERSION_MAJOR >= 5 + return rt_mq_recv(qhdl, data, qhdl->msg_size, tick) > 0; +#else + return rt_mq_recv(qhdl, data, qhdl->msg_size, tick) == RT_EOK; +#endif /* RT_VERSION_MAJOR >= 5 */ } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const *data, bool in_isr) { - (void) in_isr; - return rt_mq_send(qhdl, (void *)data, qhdl->msg_size) == RT_EOK; + (void) in_isr; + return rt_mq_send(qhdl, (void *)data, qhdl->msg_size) == RT_EOK; } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { - return (qhdl->entry) == 0; + return (qhdl->entry) == 0; } #ifdef __cplusplus } #endif -#endif /* _TUSB_OSAL_RTTHREAD_H_ */ +#endif diff --git a/src/osal/osal_rtx4.h b/src/osal/osal_rtx4.h index e443135e0..35909e4d6 100644 --- a/src/osal/osal_rtx4.h +++ b/src/osal/osal_rtx4.h @@ -25,8 +25,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_OSAL_RTX4_H_ -#define _TUSB_OSAL_RTX4_H_ +#ifndef TUSB_OSAL_RTX4_H_ +#define TUSB_OSAL_RTX4_H_ #include @@ -37,8 +37,7 @@ extern "C" { //--------------------------------------------------------------------+ // TASK API //--------------------------------------------------------------------+ -TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) -{ +TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { uint16_t hi = msec >> 16; uint16_t lo = msec; while (hi--) { @@ -48,12 +47,13 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) } TU_ATTR_ALWAYS_INLINE static inline uint16_t msec2wait(uint32_t msec) { - if (msec == OSAL_TIMEOUT_WAIT_FOREVER) + if (msec == OSAL_TIMEOUT_WAIT_FOREVER) { return 0xFFFF; - else if (msec >= 0xFFFE) + } else if (msec >= 0xFFFE) { return 0xFFFE; - else + } else { return msec; + } } //--------------------------------------------------------------------+ @@ -67,6 +67,11 @@ TU_ATTR_ALWAYS_INLINE static inline OS_ID osal_semaphore_create(osal_semaphore_d return semdef; } +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) { + (void) semd_hdl; + return true; // nothing to do +} + TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { if ( !in_isr ) { os_sem_send(sem_hdl); @@ -90,19 +95,21 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t c typedef OS_MUT osal_mutex_def_t; typedef OS_ID osal_mutex_t; -TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) -{ +TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) { os_mut_init(mdef); return mdef; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) { + (void) mutex_hdl; + return true; // nothing to do +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) { return os_mut_wait(mutex_hdl, msec2wait(msec)) != OS_R_TMO; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { return os_mut_release(mutex_hdl) == OS_R_OK; } @@ -116,9 +123,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hd _declare_box(_name##__pool, sizeof(_type), _depth); \ osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .pool = _name##__pool, .mbox = _name##__mbox }; - -typedef struct -{ +typedef struct { uint16_t depth; uint16_t item_sz; U32* pool; @@ -127,15 +132,13 @@ typedef struct typedef osal_queue_def_t* osal_queue_t; -TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) -{ +TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { os_mbx_init(qdef->mbox, (qdef->depth + 4) * 4); _init_box(qdef->pool, ((qdef->item_sz+3)/4)*(qdef->depth) + 3, qdef->item_sz); return qdef; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) { void* buf; os_mbx_wait(qhdl->mbox, &buf, msec2wait(msec)); memcpy(data, buf, qhdl->item_sz); @@ -143,23 +146,23 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, v return true; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) { + (void) qhdl; + return true; // nothing to do ? +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) { void* buf = _alloc_box(qhdl->pool); memcpy(buf, data, qhdl->item_sz); - if ( !in_isr ) - { + if ( !in_isr ) { os_mbx_send(qhdl->mbox, buf, 0xFFFF); - } - else - { + } else { isr_mbx_send(qhdl->mbox, buf); } return true; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { return os_mbx_check(qhdl->mbox) == qhdl->depth; } diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c new file mode 100644 index 000000000..4dc93d2d8 --- /dev/null +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -0,0 +1,1012 @@ +/* + * 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. + */ + +#include "tusb_option.h" + +#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 + +#include +#include "host/hcd.h" +#include "host/usbh.h" + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ + +// Command format is +// Reg [7:3] | 0 [2] | Dir [1] | Ack [0] + +enum { + CMDBYTE_WRITE = 0x02, +}; + +enum { + RCVVFIFO_ADDR = 1u << 3, // 0x08 + SNDFIFO_ADDR = 2u << 3, // 0x10 + SUDFIFO_ADDR = 4u << 3, // 0x20 + RCVBC_ADDR = 6u << 3, // 0x30 + SNDBC_ADDR = 7u << 3, // 0x38 + USBIRQ_ADDR = 13u << 3, // 0x68 + USBIEN_ADDR = 14u << 3, // 0x70 + USBCTL_ADDR = 15u << 3, // 0x78 + CPUCTL_ADDR = 16u << 3, // 0x80 + PINCTL_ADDR = 17u << 3, // 0x88 + REVISION_ADDR = 18u << 3, // 0x90 + // 19 is not used + IOPINS1_ADDR = 20u << 3, // 0xA0 + IOPINS2_ADDR = 21u << 3, // 0xA8 + GPINIRQ_ADDR = 22u << 3, // 0xB0 + GPINIEN_ADDR = 23u << 3, // 0xB8 + GPINPOL_ADDR = 24u << 3, // 0xC0 + HIRQ_ADDR = 25u << 3, // 0xC8 + HIEN_ADDR = 26u << 3, // 0xD0 + MODE_ADDR = 27u << 3, // 0xD8 + PERADDR_ADDR = 28u << 3, // 0xE0 + HCTL_ADDR = 29u << 3, // 0xE8 + HXFR_ADDR = 30u << 3, // 0xF0 + HRSL_ADDR = 31u << 3, // 0xF8 +}; + +enum { + USBIRQ_OSCOK_IRQ = 1u << 0, + USBIRQ_NOVBUS_IRQ = 1u << 5, + USBIRQ_VBUS_IRQ = 1u << 6, +}; + +enum { + USBCTL_PWRDOWN = 1u << 4, + USBCTL_CHIPRES = 1u << 5, +}; + +enum { + CPUCTL_IE = 1u << 0, + CPUCTL_PULSEWID0 = 1u << 6, + CPUCTL_PULSEWID1 = 1u << 7, +}; + +enum { + PINCTL_GPXA = 1u << 0, + PINCTL_GPXB = 1u << 1, + PINCTL_POSINT = 1u << 2, + PINCTL_INTLEVEL = 1u << 3, + PINCTL_FDUPSPI = 1u << 4, +}; + +enum { + HIRQ_BUSEVENT_IRQ = 1u << 0, + HIRQ_RWU_IRQ = 1u << 1, + HIRQ_RCVDAV_IRQ = 1u << 2, + HIRQ_SNDBAV_IRQ = 1u << 3, + HIRQ_SUSDN_IRQ = 1u << 4, + HIRQ_CONDET_IRQ = 1u << 5, + HIRQ_FRAME_IRQ = 1u << 6, + HIRQ_HXFRDN_IRQ = 1u << 7, +}; + +enum { + MODE_HOST = 1u << 0, + MODE_LOWSPEED = 1u << 1, + MODE_HUBPRE = 1u << 2, + MODE_SOFKAENAB = 1u << 3, + MODE_SEPIRQ = 1u << 4, + MODE_DELAYISO = 1u << 5, + MODE_DMPULLDN = 1u << 6, + MODE_DPPULLDN = 1u << 7, +}; + +enum { + HCTL_BUSRST = 1u << 0, + HCTL_FRMRST = 1u << 1, + HCTL_SAMPLEBUS = 1u << 2, + HCTL_SIGRSM = 1u << 3, + HCTL_RCVTOG0 = 1u << 4, + HCTL_RCVTOG1 = 1u << 5, + HCTL_SNDTOG0 = 1u << 6, + HCTL_SNDTOG1 = 1u << 7, +}; + +enum { + HXFR_EPNUM_MASK = 0x0f, + HXFR_SETUP = 1u << 4, + HXFR_OUT_NIN = 1u << 5, + HXFR_ISO = 1u << 6, + HXFR_HS = 1u << 7, +}; + +enum { + HRSL_RESULT_MASK = 0x0f, + HRSL_RCVTOGRD = 1u << 4, + HRSL_SNDTOGRD = 1u << 5, + HRSL_KSTATUS = 1u << 6, + HRSL_JSTATUS = 1u << 7, +}; + +enum { + HRSL_SUCCESS = 0, + HRSL_BUSY, + HRSL_BAD_REQ, + HRSL_UNDEF, + HRSL_NAK, + HRSL_STALL, + HRSL_TOG_ERR, + HRSL_WRONG_PID, + HRSL_BAD_BYTECOUNT, + HRSL_PID_ERR, + HRSL_PKT_ERR, + HRSL_CRC_ERR, + HRSL_K_ERR, + HRSL_J_ERR, + HRSL_TIMEOUT, + HRSL_BABBLE, +}; + +enum { + DEFAULT_HIEN = HIRQ_CONDET_IRQ | HIRQ_FRAME_IRQ | HIRQ_HXFRDN_IRQ | HIRQ_RCVDAV_IRQ +}; + +enum { + MAX_NAK_DEFAULT = 1 // Number of NAK per endpoint per usb frame +}; + +enum { + EP_STATE_IDLE = 0, + EP_STATE_COMPLETE = 1, + EP_STATE_ATTEMPT_1 = 2, // pending 1st attempt + EP_STATE_ATTEMPT_MAX = 15 +}; + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ + +typedef struct { + uint8_t daddr; + + union { ; + struct TU_ATTR_PACKED { + uint8_t ep_num : 4; + uint8_t is_setup : 1; + uint8_t is_out : 1; + uint8_t is_iso : 1; + }hxfr_bm; + + uint8_t hxfr; + }; + + struct TU_ATTR_PACKED { + uint8_t state : 4; + uint8_t data_toggle : 1; + uint16_t packet_size : 11; + }; + + uint16_t total_len; + uint16_t xferred_len; + uint8_t* buf; +} max3421_ep_t; + +TU_VERIFY_STATIC(sizeof(max3421_ep_t) == 12, "size is not correct"); + +typedef struct { + volatile uint16_t frame_count; + + // cached register + uint8_t sndbc; + uint8_t hirq; + uint8_t hien; + uint8_t mode; + uint8_t peraddr; + uint8_t hxfr; + + atomic_flag busy; // busy transferring + +#if OSAL_MUTEX_REQUIRED + OSAL_MUTEX_DEF(spi_mutexdef); + osal_mutex_t spi_mutex; +#endif + + max3421_ep_t ep[CFG_TUH_MAX3421_ENDPOINT_TOTAL]; // [0] is reserved for addr0 +} max3421_data_t; + +static max3421_data_t _hcd_data; + +// max NAK before giving up in a frame. 0 means infinite NAKs +static tuh_configure_max3421_t _tuh_cfg = { + .max_nak = MAX_NAK_DEFAULT, + .cpuctl = 0, // default: INT pulse width = 10.6 us + .pinctl = 0, // default: negative edge interrupt +}; + +//--------------------------------------------------------------------+ +// API: SPI transfer with MAX3421E +// - spi_cs_api(), spi_xfer_api(), int_api(): must be implemented by application +// - reg_read(), reg_write(): is implemented by this driver, can be used by application +//--------------------------------------------------------------------+ + +// API to control MAX3421 SPI CS +extern void tuh_max3421_spi_cs_api(uint8_t rhport, bool active); + +// API to transfer data with MAX3421 SPI +// Either tx_buf or rx_buf can be NULL, which means transfer is write or read only +extern bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const* tx_buf, uint8_t* rx_buf, size_t xfer_bytes); + +// API to enable/disable MAX3421 INTR pin interrupt +extern void tuh_max3421_int_api(uint8_t rhport, bool enabled); + +// API to read MAX3421's register. Implemented by TinyUSB +uint8_t tuh_max3421_reg_read(uint8_t rhport, uint8_t reg, bool in_isr); + +// API to write MAX3421's register. Implemented by TinyUSB +bool tuh_max3421_reg_write(uint8_t rhport, uint8_t reg, uint8_t data, bool in_isr); + +//--------------------------------------------------------------------+ +// SPI Commands and Helper +//--------------------------------------------------------------------+ + +#define reg_read tuh_max3421_reg_read +#define reg_write tuh_max3421_reg_write + +static void max3421_spi_lock(uint8_t rhport, bool in_isr) { + // disable interrupt and mutex lock (for pre-emptive RTOS) if not in_isr + if (!in_isr) { + (void) osal_mutex_lock(_hcd_data.spi_mutex, OSAL_TIMEOUT_WAIT_FOREVER); + tuh_max3421_int_api(rhport, false); + } + + // assert CS + tuh_max3421_spi_cs_api(rhport, true); +} + +static void max3421_spi_unlock(uint8_t rhport, bool in_isr) { + // de-assert CS + tuh_max3421_spi_cs_api(rhport, false); + + // mutex unlock and re-enable interrupt + if (!in_isr) { + tuh_max3421_int_api(rhport, true); + (void) osal_mutex_unlock(_hcd_data.spi_mutex); + } +} + +uint8_t tuh_max3421_reg_read(uint8_t rhport, uint8_t reg, bool in_isr) { + uint8_t tx_buf[2] = {reg, 0}; + uint8_t rx_buf[2] = {0, 0}; + + max3421_spi_lock(rhport, in_isr); + bool ret = tuh_max3421_spi_xfer_api(rhport, tx_buf, rx_buf, 2); + max3421_spi_unlock(rhport, in_isr); + + _hcd_data.hirq = rx_buf[0]; + return ret ? rx_buf[1] : 0; +} + +bool tuh_max3421_reg_write(uint8_t rhport, uint8_t reg, uint8_t data, bool in_isr) { + uint8_t tx_buf[2] = {reg | CMDBYTE_WRITE, data}; + uint8_t rx_buf[2] = {0, 0}; + + max3421_spi_lock(rhport, in_isr); + bool ret = tuh_max3421_spi_xfer_api(rhport, tx_buf, rx_buf, 2); + max3421_spi_unlock(rhport, in_isr); + + // HIRQ register since we are in full-duplex mode + _hcd_data.hirq = rx_buf[0]; + + return ret; +} + +static void fifo_write(uint8_t rhport, uint8_t reg, uint8_t const * buffer, uint16_t len, bool in_isr) { + uint8_t hirq; + reg |= CMDBYTE_WRITE; + + max3421_spi_lock(rhport, in_isr); + + tuh_max3421_spi_xfer_api(rhport, ®, &hirq, 1); + _hcd_data.hirq = hirq; + tuh_max3421_spi_xfer_api(rhport, buffer, NULL, len); + + max3421_spi_unlock(rhport, in_isr); +} + +static void fifo_read(uint8_t rhport, uint8_t * buffer, uint16_t len, bool in_isr) { + uint8_t hirq; + uint8_t const reg = RCVVFIFO_ADDR; + + max3421_spi_lock(rhport, in_isr); + + tuh_max3421_spi_xfer_api(rhport, ®, &hirq, 1); + _hcd_data.hirq = hirq; + tuh_max3421_spi_xfer_api(rhport, NULL, buffer, len); + + max3421_spi_unlock(rhport, in_isr); +} + +//------------- register write helper -------------// +TU_ATTR_ALWAYS_INLINE static inline void hirq_write(uint8_t rhport, uint8_t data, bool in_isr) { + reg_write(rhport, HIRQ_ADDR, data, in_isr); + // HIRQ write 1 is clear + _hcd_data.hirq &= (uint8_t) ~data; +} + +TU_ATTR_ALWAYS_INLINE static inline void hien_write(uint8_t rhport, uint8_t data, bool in_isr) { + _hcd_data.hien = data; + reg_write(rhport, HIEN_ADDR, data, in_isr); +} + +TU_ATTR_ALWAYS_INLINE static inline void mode_write(uint8_t rhport, uint8_t data, bool in_isr) { + _hcd_data.mode = data; + reg_write(rhport, MODE_ADDR, data, in_isr); +} + +TU_ATTR_ALWAYS_INLINE static inline void peraddr_write(uint8_t rhport, uint8_t data, bool in_isr) { + if ( _hcd_data.peraddr == data ) return; // no need to change address + + _hcd_data.peraddr = data; + reg_write(rhport, PERADDR_ADDR, data, in_isr); +} + +TU_ATTR_ALWAYS_INLINE static inline void hxfr_write(uint8_t rhport, uint8_t data, bool in_isr) { + _hcd_data.hxfr = data; + reg_write(rhport, HXFR_ADDR, data, in_isr); +} + +TU_ATTR_ALWAYS_INLINE static inline void sndbc_write(uint8_t rhport, uint8_t data, bool in_isr) { + _hcd_data.sndbc = data; + reg_write(rhport, SNDBC_ADDR, data, in_isr); +} + +//--------------------------------------------------------------------+ +// Endpoint helper +//--------------------------------------------------------------------+ + +static max3421_ep_t* find_ep_not_addr0(uint8_t daddr, uint8_t ep_num, uint8_t ep_dir) { + uint8_t const is_out = 1-ep_dir; + for(size_t i=1; idaddr && ep_num == ep->hxfr_bm.ep_num && (ep_num == 0 || is_out == ep->hxfr_bm.is_out)) { + return ep; + } + } + + return NULL; +} + +// daddr = 0 and ep_num = 0 means find a free (allocate) endpoint +TU_ATTR_ALWAYS_INLINE static inline max3421_ep_t * allocate_ep(void) { + return find_ep_not_addr0(0, 0, 0); +} + +TU_ATTR_ALWAYS_INLINE static inline max3421_ep_t * find_opened_ep(uint8_t daddr, uint8_t ep_num, uint8_t ep_dir) { + if (daddr == 0 && ep_num == 0) { + return &_hcd_data.ep[0]; + }else{ + return find_ep_not_addr0(daddr, ep_num, ep_dir); + } +} + +// free all endpoints belong to device address +static void free_ep(uint8_t daddr) { + for (size_t i=1; idaddr == daddr) { + tu_memclr(ep, sizeof(max3421_ep_t)); + } + } +} + +// Check if endpoint has an queued transfer and not reach max NAK +TU_ATTR_ALWAYS_INLINE static inline bool is_ep_pending(max3421_ep_t const * ep) { + uint8_t const state = ep->state; + return ep->packet_size && (state >= EP_STATE_ATTEMPT_1) && + (_tuh_cfg.max_nak == 0 || state < EP_STATE_ATTEMPT_1 + _tuh_cfg.max_nak); +} + +// Find the next pending endpoint using round-robin scheduling, starting from next endpoint. +// return NULL if not found +// TODO respect interrupt endpoint's interval +static max3421_ep_t * find_next_pending_ep(max3421_ep_t * cur_ep) { + size_t const idx = (size_t) (cur_ep - _hcd_data.ep); + + // starting from next endpoint + for (size_t i = idx + 1; i < CFG_TUH_MAX3421_ENDPOINT_TOTAL; i++) { + max3421_ep_t* ep = &_hcd_data.ep[i]; + if (is_ep_pending(ep)) { + return ep; + } + } + + // wrap around including current endpoint + for (size_t i = 0; i <= idx; i++) { + max3421_ep_t* ep = &_hcd_data.ep[i]; + if (is_ep_pending(ep)) { + return ep; + } + } + + return NULL; +} + +//--------------------------------------------------------------------+ +// Controller API +//--------------------------------------------------------------------+ + +// optional hcd configuration, called by tuh_configure() +bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { + (void) rhport; + TU_VERIFY(cfg_id == TUH_CFGID_MAX3421 && cfg_param != NULL); + + tuh_configure_param_t const* cfg = (tuh_configure_param_t const*) cfg_param; + _tuh_cfg = cfg->max3421; + return true; +} + +// Initialize controller to host mode +bool hcd_init(uint8_t rhport) { + (void) rhport; + + tuh_max3421_int_api(rhport, false); + + TU_LOG2_INT(sizeof(max3421_ep_t)); + TU_LOG2_INT(sizeof(max3421_data_t)); + TU_LOG2_INT(offsetof(max3421_data_t, ep)); + + tu_memclr(&_hcd_data, sizeof(_hcd_data)); + _hcd_data.peraddr = 0xff; // invalid + +#if OSAL_MUTEX_REQUIRED + _hcd_data.spi_mutex = osal_mutex_create(&_hcd_data.spi_mutexdef); +#endif + + // NOTE: driver does not seem to work without nRST pin signal + + // full duplex, interrupt negative edge + reg_write(rhport, PINCTL_ADDR, _tuh_cfg.pinctl | PINCTL_FDUPSPI, false); + + // v1 is 0x01, v2 is 0x12, v3 is 0x13 + uint8_t const revision = reg_read(rhport, REVISION_ADDR, false); + TU_LOG2_HEX(revision); + TU_ASSERT(revision == 0x01 || revision == 0x12 || revision == 0x13, false); + + // reset + reg_write(rhport, USBCTL_ADDR, USBCTL_CHIPRES, false); + reg_write(rhport, USBCTL_ADDR, 0, false); + while( !(reg_read(rhport, USBIRQ_ADDR, false) & USBIRQ_OSCOK_IRQ) ) { + // wait for oscillator to stabilize + } + + // Mode: Host and DP/DM pull down + mode_write(rhport, MODE_DPPULLDN | MODE_DMPULLDN | MODE_HOST, false); + + // frame reset & bus reset, this will trigger CONDET IRQ if device is already connected + reg_write(rhport, HCTL_ADDR, HCTL_BUSRST | HCTL_FRMRST, false); + + // clear all previously pending IRQ + hirq_write(rhport, 0xff, false); + + // Enable IRQ + hien_write(rhport, DEFAULT_HIEN, false); + + tuh_max3421_int_api(rhport, true); + + // Enable Interrupt pin + reg_write(rhport, CPUCTL_ADDR, _tuh_cfg.cpuctl | CPUCTL_IE, false); + + return true; +} + +bool hcd_deinit(uint8_t rhport) { + (void) rhport; + + // disable interrupt + tuh_max3421_int_api(rhport, false); + + // reset max3421 and power down + reg_write(rhport, USBCTL_ADDR, USBCTL_CHIPRES, false); + reg_write(rhport, USBCTL_ADDR, USBCTL_PWRDOWN, false); + + #if OSAL_MUTEX_REQUIRED + osal_mutex_delete(_hcd_data.spi_mutex); + _hcd_data.spi_mutex = NULL; + #endif + + return true; +} + +// Enable USB interrupt +// Not actually enable GPIO interrupt, just set variable to prevent handler to process +void hcd_int_enable (uint8_t rhport) { + tuh_max3421_int_api(rhport, true); +} + +// Disable USB interrupt +// Not actually disable GPIO interrupt, just set variable to prevent handler to process +void hcd_int_disable(uint8_t rhport) { + tuh_max3421_int_api(rhport, false); +} + +// Get frame number (1ms) +uint32_t hcd_frame_number(uint8_t rhport) { + (void) rhport; + return (uint32_t ) _hcd_data.frame_count; +} + +//--------------------------------------------------------------------+ +// Port API +//--------------------------------------------------------------------+ + +// Get the current connect status of roothub port +bool hcd_port_connect_status(uint8_t rhport) { + (void) rhport; + return (_hcd_data.mode & MODE_SOFKAENAB) ? true : false; +} + +// Reset USB bus on the port. Return immediately, bus reset sequence may not be complete. +// Some port would require hcd_port_reset_end() to be invoked after 10ms to complete the reset sequence. +void hcd_port_reset(uint8_t rhport) { + reg_write(rhport, HCTL_ADDR, HCTL_BUSRST, false); +} + +// Complete bus reset sequence, may be required by some controllers +void hcd_port_reset_end(uint8_t rhport) { + reg_write(rhport, HCTL_ADDR, 0, false); +} + +// Get port link speed +tusb_speed_t hcd_port_speed_get(uint8_t rhport) { + (void) rhport; + return (_hcd_data.mode & MODE_LOWSPEED) ? TUSB_SPEED_LOW : TUSB_SPEED_FULL; +} + +// HCD closes all opened endpoints belong to this device +void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { + (void) rhport; + (void) dev_addr; +} + +//--------------------------------------------------------------------+ +// Endpoints API +//--------------------------------------------------------------------+ + +// Open an endpoint +bool hcd_edpt_open(uint8_t rhport, uint8_t daddr, tusb_desc_endpoint_t const * ep_desc) { + (void) rhport; + + uint8_t const ep_num = tu_edpt_number(ep_desc->bEndpointAddress); + tusb_dir_t const ep_dir = tu_edpt_dir(ep_desc->bEndpointAddress); + + max3421_ep_t * ep; + if (daddr == 0 && ep_num == 0) { + ep = &_hcd_data.ep[0]; + }else { + ep = allocate_ep(); + TU_ASSERT(ep); + ep->daddr = daddr; + ep->hxfr_bm.ep_num = (uint8_t) (ep_num & 0x0f); + ep->hxfr_bm.is_out = (ep_dir == TUSB_DIR_OUT) ? 1 : 0; + ep->hxfr_bm.is_iso = (TUSB_XFER_ISOCHRONOUS == ep_desc->bmAttributes.xfer) ? 1 : 0; + } + + ep->packet_size = (uint16_t) (tu_edpt_packet_size(ep_desc) & 0x7ff); + + return true; +} + +static void xact_out(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) { + // Page 12: Programming BULK-OUT Transfers + // TODO double buffered + if (switch_ep) { + peraddr_write(rhport, ep->daddr, in_isr); + + uint8_t const hctl = (ep->data_toggle ? HCTL_SNDTOG1 : HCTL_SNDTOG0); + reg_write(rhport, HCTL_ADDR, hctl, in_isr); + } + + uint8_t const xact_len = (uint8_t) tu_min16(ep->total_len - ep->xferred_len, ep->packet_size); + TU_ASSERT(_hcd_data.hirq & HIRQ_SNDBAV_IRQ,); + if (xact_len) { + fifo_write(rhport, SNDFIFO_ADDR, ep->buf, xact_len, in_isr); + } + sndbc_write(rhport, xact_len, in_isr); + hxfr_write(rhport, ep->hxfr, in_isr); +} + +static void xact_in(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) { + // Page 13: Programming BULK-IN Transfers + if (switch_ep) { + peraddr_write(rhport, ep->daddr, in_isr); + + uint8_t const hctl = (ep->data_toggle ? HCTL_RCVTOG1 : HCTL_RCVTOG0); + reg_write(rhport, HCTL_ADDR, hctl, in_isr); + } + + hxfr_write(rhport, ep->hxfr, in_isr); +} + +static void xact_setup(uint8_t rhport, max3421_ep_t *ep, bool in_isr) { + peraddr_write(rhport, ep->daddr, in_isr); + fifo_write(rhport, SUDFIFO_ADDR, ep->buf, 8, in_isr); + hxfr_write(rhport, HXFR_SETUP, in_isr); +} + +static void xact_generic(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) { + if (ep->hxfr_bm.ep_num == 0 ) { + // setup + if (ep->hxfr_bm.is_setup) { + xact_setup(rhport, ep, in_isr); + return; + } + + // status + if (ep->buf == NULL || ep->total_len == 0) { + uint8_t const hxfr = (uint8_t) (HXFR_HS | (ep->hxfr & HXFR_OUT_NIN)); + peraddr_write(rhport, ep->daddr, in_isr); + hxfr_write(rhport, hxfr, in_isr); + return; + } + } + + if (ep->hxfr_bm.is_out) { + xact_out(rhport, ep, switch_ep, in_isr); + }else { + xact_in(rhport, ep, switch_ep, in_isr); + } +} + +// Submit a transfer, when complete hcd_event_xfer_complete() must be invoked +bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) { + uint8_t const ep_num = tu_edpt_number(ep_addr); + uint8_t const ep_dir = (uint8_t) tu_edpt_dir(ep_addr); + + max3421_ep_t* ep = find_opened_ep(daddr, ep_num, ep_dir); + TU_VERIFY(ep); + + if (ep_num == 0) { + // control transfer can switch direction + ep->hxfr_bm.is_out = ep_dir ? 0 : 1; + ep->hxfr_bm.is_setup = 0; + ep->data_toggle = 1; + } + + ep->buf = buffer; + ep->total_len = buflen; + ep->xferred_len = 0; + ep->state = EP_STATE_ATTEMPT_1; + + // carry out transfer if not busy + if (!atomic_flag_test_and_set(&_hcd_data.busy)) { + xact_generic(rhport, ep, true, false); + } + + return true; +} + +// 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) { + (void) rhport; + (void) dev_addr; + (void) ep_addr; + + return false; +} + +// 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 daddr, uint8_t const setup_packet[8]) { + (void) rhport; + + max3421_ep_t* ep = find_opened_ep(daddr, 0, 0); + TU_ASSERT(ep); + + ep->hxfr_bm.is_out = 1; + ep->hxfr_bm.is_setup = 1; + ep->buf = (uint8_t*)(uintptr_t) setup_packet; + ep->total_len = 8; + ep->xferred_len = 0; + ep->state = EP_STATE_ATTEMPT_1; + + // carry out transfer if not busy + if (!atomic_flag_test_and_set(&_hcd_data.busy)) { + xact_setup(rhport, ep, false); + } + + return true; +} + +// clear stall, data toggle is also reset to DATA0 +bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { + (void) rhport; + (void) dev_addr; + (void) ep_addr; + + return false; +} + +//--------------------------------------------------------------------+ +// Interrupt Handler +//--------------------------------------------------------------------+ + +static void handle_connect_irq(uint8_t rhport, bool in_isr) { + uint8_t const hrsl = reg_read(rhport, HRSL_ADDR, in_isr); + uint8_t const jk = hrsl & (HRSL_JSTATUS | HRSL_KSTATUS); + + uint8_t new_mode = MODE_DPPULLDN | MODE_DMPULLDN | MODE_HOST; + TU_LOG2_HEX(jk); + + switch(jk) { + case 0x00: // SEO is disconnected + case (HRSL_JSTATUS | HRSL_KSTATUS): // SE1 is illegal + mode_write(rhport, new_mode, in_isr); + + // port reset anyway, this will help to stable bus signal for next connection + reg_write(rhport, HCTL_ADDR, HCTL_BUSRST, in_isr); + hcd_event_device_remove(rhport, in_isr); + reg_write(rhport, HCTL_ADDR, 0, in_isr); + break; + + default: { + // Bus Reset also cause CONDET IRQ, skip if we are already connected and doing bus reset + if ((_hcd_data.hirq & HIRQ_BUSEVENT_IRQ) && (_hcd_data.mode & MODE_SOFKAENAB)) { + break; + } + + // Low speed if (LS = 1 and J-state) or (LS = 0 and K-State) + // However, since we are always in full speed mode, we can just check J-state + if (jk == HRSL_KSTATUS) { + new_mode |= MODE_LOWSPEED; + TU_LOG3("Low speed\r\n"); + }else { + TU_LOG3("Full speed\r\n"); + } + new_mode |= MODE_SOFKAENAB; + mode_write(rhport, new_mode, in_isr); + + // FIXME multiple MAX3421 rootdevice address is not 1 + uint8_t const daddr = 1; + free_ep(daddr); + + hcd_event_device_attach(rhport, in_isr); + break; + } + } +} + +static void xfer_complete_isr(uint8_t rhport, max3421_ep_t *ep, xfer_result_t result, uint8_t hrsl, bool in_isr) { + uint8_t const ep_dir = 1-ep->hxfr_bm.is_out; + uint8_t const ep_addr = tu_edpt_addr(ep->hxfr_bm.ep_num, ep_dir); + + // save data toggle + if (ep_dir) { + ep->data_toggle = (hrsl & HRSL_RCVTOGRD) ? 1u : 0u; + }else { + ep->data_toggle = (hrsl & HRSL_SNDTOGRD) ? 1u : 0u; + } + + ep->state = EP_STATE_IDLE; + hcd_event_xfer_complete(ep->daddr, ep_addr, ep->xferred_len, result, in_isr); + + // Find next pending endpoint + max3421_ep_t * next_ep = find_next_pending_ep(ep); + if (next_ep) { + xact_generic(rhport, next_ep, true, in_isr); + }else { + // no more pending + atomic_flag_clear(&_hcd_data.busy); + } +} + +static void handle_xfer_done(uint8_t rhport, bool in_isr) { + uint8_t const hrsl = reg_read(rhport, HRSL_ADDR, in_isr); + uint8_t const hresult = hrsl & HRSL_RESULT_MASK; + + uint8_t const ep_num = _hcd_data.hxfr & HXFR_EPNUM_MASK; + uint8_t const hxfr_type = _hcd_data.hxfr & 0xf0; + uint8_t const ep_dir = ((hxfr_type & HXFR_SETUP) || (hxfr_type & HXFR_OUT_NIN)) ? 0 : 1; + + max3421_ep_t *ep = find_opened_ep(_hcd_data.peraddr, ep_num, ep_dir); + TU_VERIFY(ep, ); + + xfer_result_t xfer_result; + switch(hresult) { + case HRSL_SUCCESS: + xfer_result = XFER_RESULT_SUCCESS; + break; + + case HRSL_STALL: + xfer_result = XFER_RESULT_STALLED; + break; + + case HRSL_NAK: + if (ep_num == 0) { + // control endpoint -> retry immediately + hxfr_write(rhport, _hcd_data.hxfr, in_isr); + } else { + if (ep->state < EP_STATE_ATTEMPT_MAX) { + ep->state++; + } + + max3421_ep_t * next_ep = find_next_pending_ep(ep); + if (ep == next_ep) { + // this endpoint is only one pending -> retry immediately + hxfr_write(rhport, _hcd_data.hxfr, in_isr); + } else if (next_ep) { + // switch to next pending endpoint TODO could have issue with double buffered if not clear previously out data + xact_generic(rhport, next_ep, true, in_isr); + } else { + // no more pending in this frame -> clear busy + atomic_flag_clear(&_hcd_data.busy); + } + } + return; + + case HRSL_BAD_REQ: + // occurred when initialized without any pending transfer. Skip for now + return; + + default: + TU_LOG3("HRSL: %02X\r\n", hrsl); + xfer_result = XFER_RESULT_FAILED; + break; + } + + if (xfer_result != XFER_RESULT_SUCCESS) { + xfer_complete_isr(rhport, ep, xfer_result, hrsl, in_isr); + return; + } + + if (ep_dir) { + // IN transfer: fifo data is already received in RCVDAV IRQ + + // mark control handshake as complete + if (hxfr_type & HXFR_HS) { + ep->state = EP_STATE_COMPLETE; + } + + // short packet or all bytes transferred + if (ep->state == EP_STATE_COMPLETE) { + xfer_complete_isr(rhport, ep, xfer_result, hrsl, in_isr); + }else { + // more to transfer + hxfr_write(rhport, _hcd_data.hxfr, in_isr); + } + } else { + // SETUP or OUT transfer + uint8_t xact_len; + + if (hxfr_type & HXFR_SETUP) { + xact_len = 8; + } else if (hxfr_type & HXFR_HS) { + xact_len = 0; + } else { + xact_len = _hcd_data.sndbc; + } + + ep->xferred_len += xact_len; + ep->buf += xact_len; + + if (xact_len < ep->packet_size || ep->xferred_len >= ep->total_len) { + xfer_complete_isr(rhport, ep, xfer_result, hrsl, in_isr); + } else { + // more to transfer + xact_out(rhport, ep, false, in_isr); + } + } +} + +#if CFG_TUSB_DEBUG >= 3 +void print_hirq(uint8_t hirq) { + TU_LOG3_HEX(hirq); + + if (hirq & HIRQ_HXFRDN_IRQ) TU_LOG3(" HXFRDN"); + if (hirq & HIRQ_FRAME_IRQ) TU_LOG3(" FRAME"); + if (hirq & HIRQ_CONDET_IRQ) TU_LOG3(" CONDET"); + if (hirq & HIRQ_SUSDN_IRQ) TU_LOG3(" SUSDN"); + if (hirq & HIRQ_SNDBAV_IRQ) TU_LOG3(" SNDBAV"); + if (hirq & HIRQ_RCVDAV_IRQ) TU_LOG3(" RCVDAV"); + if (hirq & HIRQ_RWU_IRQ) TU_LOG3(" RWU"); + if (hirq & HIRQ_BUSEVENT_IRQ) TU_LOG3(" BUSEVENT"); + + TU_LOG3("\r\n"); +} +#else + #define print_hirq(hirq) +#endif + +// Interrupt handler +void hcd_int_handler(uint8_t rhport, bool in_isr) { + uint8_t hirq = reg_read(rhport, HIRQ_ADDR, in_isr) & _hcd_data.hien; + if (!hirq) return; +// print_hirq(hirq); + + if (hirq & HIRQ_FRAME_IRQ) { + _hcd_data.frame_count++; + + max3421_ep_t* ep_retry = NULL; + + // reset all endpoints attempt counter + for (size_t i = 0; i < CFG_TUH_MAX3421_ENDPOINT_TOTAL; i++) { + max3421_ep_t* ep = &_hcd_data.ep[i]; + if (ep->packet_size && ep->state > EP_STATE_ATTEMPT_1) { + ep->state = EP_STATE_ATTEMPT_1; + + if (ep_retry == NULL) { + ep_retry = ep; + } + } + } + + // start usb transfer if not busy + if (ep_retry != NULL && !atomic_flag_test_and_set(&_hcd_data.busy)) { + xact_generic(rhport, ep_retry, true, in_isr); + } + } + + if (hirq & HIRQ_CONDET_IRQ) { + handle_connect_irq(rhport, in_isr); + } + + // queue more transfer in handle_xfer_done() can cause hirq to be set again while external IRQ may not catch and/or + // not call this handler again. So we need to loop until all IRQ are cleared + while (hirq & (HIRQ_RCVDAV_IRQ | HIRQ_HXFRDN_IRQ)) { + if (hirq & HIRQ_RCVDAV_IRQ) { + uint8_t const ep_num = _hcd_data.hxfr & HXFR_EPNUM_MASK; + max3421_ep_t* ep = find_opened_ep(_hcd_data.peraddr, ep_num, 1); + uint8_t xact_len = 0; + + // RCVDAV_IRQ can trigger 2 times (dual buffered) + while (hirq & HIRQ_RCVDAV_IRQ) { + uint8_t rcvbc = reg_read(rhport, RCVBC_ADDR, in_isr); + xact_len = (uint8_t) tu_min16(rcvbc, ep->total_len - ep->xferred_len); + if (xact_len) { + fifo_read(rhport, ep->buf, xact_len, in_isr); + ep->buf += xact_len; + ep->xferred_len += xact_len; + } + + // ack RCVDVAV IRQ + hirq_write(rhport, HIRQ_RCVDAV_IRQ, in_isr); + hirq = reg_read(rhport, HIRQ_ADDR, in_isr); + } + + if (xact_len < ep->packet_size || ep->xferred_len >= ep->total_len) { + ep->state = EP_STATE_COMPLETE; + } + } + + if (hirq & HIRQ_HXFRDN_IRQ) { + hirq_write(rhport, HIRQ_HXFRDN_IRQ, in_isr); + handle_xfer_done(rhport, in_isr); + } + + hirq = reg_read(rhport, HIRQ_ADDR, in_isr); + } + + // clear all interrupt except SNDBAV_IRQ (never clear by us). Note RCVDAV_IRQ, HXFRDN_IRQ already clear while processing + hirq &= (uint8_t) ~HIRQ_SNDBAV_IRQ; + if ( hirq ) { + hirq_write(rhport, hirq, in_isr); + } +} + +#endif diff --git a/src/portable/chipidea/ci_fs/ci_fs_kinetis.h b/src/portable/chipidea/ci_fs/ci_fs_kinetis.h index cd21af1c7..31e14a546 100644 --- a/src/portable/chipidea/ci_fs/ci_fs_kinetis.h +++ b/src/portable/chipidea/ci_fs/ci_fs_kinetis.h @@ -36,14 +36,12 @@ #define CI_FS_REG(_port) ((ci_fs_regs_t*) USB0_BASE) #define CI_REG CI_FS_REG(0) -void dcd_int_enable(uint8_t rhport) -{ +void dcd_int_enable(uint8_t rhport) { (void) rhport; NVIC_EnableIRQ(USB0_IRQn); } -void dcd_int_disable(uint8_t rhport) -{ +void dcd_int_disable(uint8_t rhport) { (void) rhport; NVIC_DisableIRQ(USB0_IRQn); } diff --git a/src/portable/chipidea/ci_fs/ci_fs_mcx.h b/src/portable/chipidea/ci_fs/ci_fs_mcx.h index 3bfcd398e..4b93a03a7 100644 --- a/src/portable/chipidea/ci_fs/ci_fs_mcx.h +++ b/src/portable/chipidea/ci_fs/ci_fs_mcx.h @@ -29,19 +29,28 @@ #include "fsl_device_registers.h" -#define CI_FS_REG(_port) ((ci_fs_regs_t*) USBFS0_BASE) -#define CI_REG CI_FS_REG(0) +#if CFG_TUSB_MCU == OPT_MCU_MCXN9 + #define CI_FS_REG(_port) ((ci_fs_regs_t*) USBFS0_BASE) + #define CIFS_IRQN USB0_FS_IRQn -void dcd_int_enable(uint8_t rhport) -{ +#elif CFG_TUSB_MCU == OPT_MCU_MCXA15 + #define CI_FS_REG(_port) ((ci_fs_regs_t*) USB0_BASE) + #define CIFS_IRQN USB0_IRQn + +#else + #error "MCU is not supported" +#endif + +#define CI_REG CI_FS_REG(0) + +void dcd_int_enable(uint8_t rhport) { (void) rhport; - NVIC_EnableIRQ(USB0_FS_IRQn); + NVIC_EnableIRQ(CIFS_IRQN); } -void dcd_int_disable(uint8_t rhport) -{ +void dcd_int_disable(uint8_t rhport) { (void) rhport; - NVIC_DisableIRQ(USB0_FS_IRQn); + NVIC_DisableIRQ(CIFS_IRQN); } #endif diff --git a/src/portable/chipidea/ci_fs/dcd_ci_fs.c b/src/portable/chipidea/ci_fs/dcd_ci_fs.c index 9327e09d8..02f813ab5 100644 --- a/src/portable/chipidea/ci_fs/dcd_ci_fs.c +++ b/src/portable/chipidea/ci_fs/dcd_ci_fs.c @@ -271,9 +271,21 @@ void dcd_init(uint8_t rhport) { (void) rhport; + // save crystal-less setting (if available) + #if defined(FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED) && FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED == 1 + uint32_t clk_recover_irc_en = CI_REG->CLK_RECOVER_IRC_EN; + uint32_t clk_recover_ctrl = CI_REG->CLK_RECOVER_CTRL; + #endif + CI_REG->USBTRC0 |= USB_USBTRC0_USBRESET_MASK; while (CI_REG->USBTRC0 & USB_USBTRC0_USBRESET_MASK); + // restore crystal-less setting (if available) + #if defined(FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED) && FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED == 1 + CI_REG->CLK_RECOVER_IRC_EN = clk_recover_irc_en; + CI_REG->CLK_RECOVER_CTRL |= clk_recover_ctrl; + #endif + tu_memclr(&_dcd, sizeof(_dcd)); CI_REG->USBTRC0 |= TU_BIT(6); /* software must set this bit to 1 */ CI_REG->BDT_PAGE1 = (uint8_t)((uintptr_t)_dcd.bdt >> 8); @@ -283,7 +295,7 @@ void dcd_init(uint8_t rhport) CI_REG->INT_EN = USB_INTEN_USBRSTEN_MASK; dcd_connect(rhport); - // NVIC_ClearPendingIRQ(USB0_IRQn); + // NVIC_ClearPendingIRQ(CIFS_IRQN); } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index 79811985c..01bbf62bf 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -92,7 +92,7 @@ CFG_TUH_MEM_SECTION TU_ATTR_ALIGNED(4096) static ehci_data_t ehci_data; //--------------------------------------------------------------------+ // Debug //--------------------------------------------------------------------+ -#if CFG_TUSB_DEBUG >= (EHCI_DBG + 1) +#if 0 && CFG_TUSB_DEBUG >= (EHCI_DBG + 1) static inline void print_portsc(ehci_registers_t* regs) { TU_LOG_HEX(EHCI_DBG, regs->portsc); TU_LOG(EHCI_DBG, " Connect Status : %u\r\n", regs->portsc_bm.current_connect_status); @@ -578,8 +578,10 @@ void qhd_xfer_complete_isr(ehci_qhd_t * 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 + // clear halted bit if not caused by STALL to allow more transfer xfer_result = XFER_RESULT_FAILED; - TU_LOG3(" QHD xfer err count: %d\n", qtd_overlay->err_count); + qtd_overlay->halted = false; + TU_LOG3(" QHD xfer err count: %d\r\n", qtd_overlay->err_count); // TU_BREAKPOINT(); // TODO skip unplugged device }else { // no error bits are set, endpoint is halted due to STALL @@ -654,15 +656,15 @@ void process_period_xfer_isr(uint8_t rhport, uint32_t interval_ms) } //------------- Host Controller Driver's Interrupt Handler -------------// -void hcd_int_handler(uint8_t rhport) -{ +void hcd_int_handler(uint8_t rhport, bool in_isr) { + (void) in_isr; ehci_registers_t* regs = ehci_data.regs; uint32_t const int_status = regs->status; if (int_status & EHCI_INT_MASK_HC_HALTED) { // something seriously wrong, maybe forget to flush/invalidate cache TU_BREAKPOINT(); - TU_LOG1(" HC halted\n"); + TU_LOG1(" HC halted\r\n"); return; } diff --git a/src/portable/espressif/esp32sx/dcd_esp32sx.c b/src/portable/espressif/esp32sx/dcd_esp32sx.c index 1fcfb6241..bfc0baa56 100644 --- a/src/portable/espressif/esp32sx/dcd_esp32sx.c +++ b/src/portable/espressif/esp32sx/dcd_esp32sx.c @@ -31,16 +31,26 @@ #if (((CFG_TUSB_MCU == OPT_MCU_ESP32S2) || (CFG_TUSB_MCU == OPT_MCU_ESP32S3)) && CFG_TUD_ENABLED) // Espressif -#include "freertos/xtensa_api.h" +#include "xtensa_api.h" #include "esp_intr_alloc.h" #include "esp_log.h" #include "soc/dport_reg.h" #include "soc/gpio_sig_map.h" #include "soc/usb_periph.h" +#include "soc/usb_reg.h" +#include "soc/usb_struct.h" #include "soc/periph_defs.h" // for interrupt source #include "device/dcd.h" +#ifndef USB_OUT_EP_NUM +#define USB_OUT_EP_NUM ((int) (sizeof(USB0.out_ep_reg) / sizeof(USB0.out_ep_reg[0]))) +#endif + +#ifndef USB_IN_EP_NUM +#define USB_IN_EP_NUM ((int) (sizeof(USB0.in_ep_reg) / sizeof(USB0.in_ep_reg[0]))) +#endif + // Max number of bi-directional endpoints including EP0 // Note: ESP32S2 specs say there are only up to 5 IN active endpoints include EP0 // We should probably prohibit enabling Endpoint IN > 4 (not done yet) diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 3c0114e41..a817c5d6e 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -158,9 +158,9 @@ static inline unsigned free_block_size(free_block_t const *blk) #if 0 static inline void print_block_list(free_block_t const *blk, unsigned num) { - TU_LOG1("*************\n"); + TU_LOG1("*************\r\n"); for (unsigned i = 0; i < num; ++i) { - TU_LOG1(" Blk%u %u %u\n", i, blk->beg, blk->end); + TU_LOG1(" Blk%u %u %u\r\n", i, blk->beg, blk->end); ++blk; } } diff --git a/src/portable/mentor/musb/hcd_musb.c b/src/portable/mentor/musb/hcd_musb.c index 02090df85..5312c2812 100644 --- a/src/portable/mentor/musb/hcd_musb.c +++ b/src/portable/mentor/musb/hcd_musb.c @@ -847,8 +847,10 @@ bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { /*------------------------------------------------------------------- * ISR *-------------------------------------------------------------------*/ -void hcd_int_handler(uint8_t rhport) +void hcd_int_handler(uint8_t rhport, bool in_isr) { + (void) in_isr; + uint_fast8_t is, txis, rxis; is = USB0->IS; /* read and clear interrupt status */ diff --git a/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c b/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c index c3d0c7297..d5c0daaeb 100644 --- a/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c +++ b/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c @@ -283,7 +283,18 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) /* Response with status first before changing device address */ dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); } + +#ifdef __GNUC__ // caused by extra declaration of SystemCoreClock in freeRTOSConfig.h +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wredundant-decls" +#endif + extern u32 SystemCoreClock; + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + void dcd_remote_wakeup(uint8_t rhport) { (void) rhport; diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index acc967bb3..2fe721d6b 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -40,7 +40,6 @@ #include "nrf.h" #include "nrf_clock.h" -#include "nrf_power.h" #include "nrfx_usbd_errata.h" #ifdef __GNUC__ @@ -57,28 +56,46 @@ #include "mcu/mcu.h" #endif +/* Try to detect nrfx version if not configured with CFG_TUD_NRF_NRFX_VERSION + * nrfx v1 and v2 are concurrently developed. There is no NRFX_VERSION only MDK VERSION which is as follows: + * - v3.0.0: 8.53.1 (conflict with v2.11.0), v3.1.0: 8.55.0 ... + * - v2.11.0: 8.53.1, v2.6.0: 8.44.1, v2.5.0: 8.40.2, v2.4.0: 8.37.0, v2.3.0: 8.35.0, v2.2.0: 8.32.1, v2.1.0: 8.30.2, v2.0.0: 8.29.0 + * - v1.9.0: 8.40.3, v1.8.6: 8.35.0 (conflict with v2.3.0), v1.8.5: 8.32.3, v1.8.4: 8.32.1 (conflict with v2.2.0), + * v1.8.2: 8.32.1 (conflict with v2.2.0), v1.8.1: 8.27.1 + * Therefore the check for v1 would be: + * - MDK < 8.29.0 (v2.0), MDK == 8.32.3, 8.40.3 + * - in case of conflict User of those version must upgrade to other 1.x version or set CFG_TUD_NRF_NRFX_VERSION +*/ +#ifndef CFG_TUD_NRF_NRFX_VERSION + #define _MDK_VERSION (10000*MDK_MAJOR_VERSION + 100*MDK_MINOR_VERSION + MDK_MICRO_VERSION) + + #if _MDK_VERSION < 82900 || _MDK_VERSION == 83203 || _MDK_VERSION == 84003 + // nrfx <= 1.8.1, or 1.8.5 or 1.9.0 + #define CFG_TUD_NRF_NRFX_VERSION 1 + #else + #define CFG_TUD_NRF_NRFX_VERSION 2 + #endif +#endif + /*------------------------------------------------------------------*/ /* MACRO TYPEDEF CONSTANT ENUM *------------------------------------------------------------------*/ -enum -{ +enum { // Max allowed by USB specs - MAX_PACKET_SIZE = 64, + MAX_PACKET_SIZE = 64, // Mask of all END event (IN & OUT) for all endpoints. ENDEPIN0-7, ENDEPOUT0-7, ENDISOIN, ENDISOOUT EDPT_END_ALL_MASK = (0xff << USBD_INTEN_ENDEPIN0_Pos) | (0xff << USBD_INTEN_ENDEPOUT0_Pos) | USBD_INTENCLR_ENDISOIN_Msk | USBD_INTEN_ENDISOOUT_Msk }; -enum -{ - EP_ISO_NUM = 8, // Endpoint number is fixed (8) for ISOOUT and ISOIN +enum { + EP_ISO_NUM = 8, // Endpoint number is fixed (8) for ISOOUT and ISOIN EP_CBI_COUNT = 8 // Control Bulk Interrupt endpoints count }; // Transfer Descriptor -typedef struct -{ +typedef struct { uint8_t* buffer; uint16_t total_len; volatile uint16_t actual_len; @@ -96,113 +113,82 @@ typedef struct } xfer_td_t; // Data for managing dcd -static struct -{ +static struct { // All 8 endpoints including control IN & OUT (offset 1) // +1 for ISO endpoints xfer_td_t xfer[EP_CBI_COUNT + 1][2]; // nRF can only carry one DMA at a time, this is used to guard the access to EasyDMA - atomic_bool dma_running; -}_dcd; + atomic_flag dma_running; +} _dcd; /*------------------------------------------------------------------*/ /* Control / Bulk / Interrupt (CBI) Transfer *------------------------------------------------------------------*/ -// NVIC_GetEnableIRQ is only available in CMSIS v5 -#ifndef NVIC_GetEnableIRQ -static inline uint32_t NVIC_GetEnableIRQ(IRQn_Type IRQn) -{ - if ((int32_t)(IRQn) >= 0) - { - return((uint32_t)(((NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); - } - else - { - return(0U); - } -} -#endif - // check if we are in ISR -TU_ATTR_ALWAYS_INLINE static inline bool is_in_isr(void) -{ +TU_ATTR_ALWAYS_INLINE static inline bool is_in_isr(void) { return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) ? true : false; } // helper to start DMA -static void start_dma(volatile uint32_t* reg_startep) -{ +static void start_dma(volatile uint32_t* reg_startep) { (*reg_startep) = 1; - __ISB(); __DSB(); + __ISB(); + __DSB(); // TASKS_EP0STATUS, TASKS_EP0RCVOUT seem to need EasyDMA to be available // However these don't trigger any DMA transfer and got ENDED event subsequently // Therefore dma_pending is corrected right away - if ( (reg_startep == &NRF_USBD->TASKS_EP0STATUS) || (reg_startep == &NRF_USBD->TASKS_EP0RCVOUT) ) - { + if ((reg_startep == &NRF_USBD->TASKS_EP0STATUS) || (reg_startep == &NRF_USBD->TASKS_EP0RCVOUT)) { atomic_flag_clear(&_dcd.dma_running); } } -static void edpt_dma_start(volatile uint32_t* reg_startep) -{ - if ( atomic_flag_test_and_set(&_dcd.dma_running) ) - { - usbd_defer_func((osal_task_func_t) edpt_dma_start, (void*) (uintptr_t) reg_startep, true); - }else - { +static void edpt_dma_start(volatile uint32_t* reg_startep) { + if (atomic_flag_test_and_set(&_dcd.dma_running)) { + usbd_defer_func((osal_task_func_t)(uintptr_t ) edpt_dma_start, (void*) (uintptr_t) reg_startep, true); + } else { start_dma(reg_startep); } } // DMA is complete -static void edpt_dma_end(void) -{ - TU_ASSERT(_dcd.dma_running, ); +static void edpt_dma_end(void) { atomic_flag_clear(&_dcd.dma_running); } // helper getting td -static inline xfer_td_t* get_td(uint8_t epnum, uint8_t dir) -{ +static inline xfer_td_t* get_td(uint8_t epnum, uint8_t dir) { return &_dcd.xfer[epnum][dir]; } static void xact_out_dma(uint8_t epnum); + // Function wraps xact_out_dma which wants uint8_t while usbd_defer_func wants void (*)(void *) -static void xact_out_dma_wrapper(void *epnum) -{ - xact_out_dma((uint8_t)((uintptr_t)epnum)); +static void xact_out_dma_wrapper(void* epnum) { + xact_out_dma((uint8_t) ((uintptr_t) epnum)); } // Start DMA to move data from Endpoint -> RAM -static void xact_out_dma(uint8_t epnum) -{ +static void xact_out_dma(uint8_t epnum) { xfer_td_t* xfer = get_td(epnum, TUSB_DIR_OUT); uint32_t xact_len; // DMA can't be active during read of SIZE.EPOUT or SIZE.ISOOUT, so try to lock, // If already running defer call regardless if it was called from ISR or task, - if ( atomic_flag_test_and_set(&_dcd.dma_running) ) - { - usbd_defer_func((osal_task_func_t)xact_out_dma_wrapper, (void *)(uint32_t)epnum, is_in_isr()); + if (atomic_flag_test_and_set(&_dcd.dma_running)) { + usbd_defer_func((osal_task_func_t) xact_out_dma_wrapper, (void*) (uint32_t) epnum, is_in_isr()); return; } - if (epnum == EP_ISO_NUM) - { + if (epnum == EP_ISO_NUM) { xact_len = NRF_USBD->SIZE.ISOOUT; // If ZERO bit is set, ignore ISOOUT length - if (xact_len & USBD_SIZE_ISOOUT_ZERO_Msk) - { + if (xact_len & USBD_SIZE_ISOOUT_ZERO_Msk) { xact_len = 0; atomic_flag_clear(&_dcd.dma_running); - } - else - { - if (xfer->started) - { + } else { + if (xfer->started) { // Trigger DMA move data from Endpoint -> SRAM NRF_USBD->ISOOUT.PTR = (uint32_t) xfer->buffer; NRF_USBD->ISOOUT.MAXCNT = xact_len; @@ -212,9 +198,7 @@ static void xact_out_dma(uint8_t epnum) atomic_flag_clear(&_dcd.dma_running); } } - } - else - { + } else { // limit xact len to remaining length xact_len = tu_min16((uint16_t) NRF_USBD->SIZE.EPOUT[epnum], xfer->total_len - xfer->actual_len); @@ -228,14 +212,13 @@ static void xact_out_dma(uint8_t epnum) // Prepare for a CBI transaction IN, call at the start // it start DMA to transfer data from RAM -> Endpoint -static void xact_in_dma(uint8_t epnum) -{ +static void xact_in_dma(uint8_t epnum) { xfer_td_t* xfer = get_td(epnum, TUSB_DIR_IN); // Each transaction is up to Max Packet Size uint16_t const xact_len = tu_min16(xfer->total_len - xfer->actual_len, xfer->mps); - NRF_USBD->EPIN[epnum].PTR = (uint32_t) xfer->buffer; + NRF_USBD->EPIN[epnum].PTR = (uint32_t) xfer->buffer; NRF_USBD->EPIN[epnum].MAXCNT = xact_len; edpt_dma_start(&NRF_USBD->TASKS_STARTEPIN[epnum]); @@ -244,26 +227,22 @@ static void xact_in_dma(uint8_t epnum) //--------------------------------------------------------------------+ // Controller API //--------------------------------------------------------------------+ -void dcd_init (uint8_t rhport) -{ - TU_LOG1("dcd init\r\n"); +void dcd_init(uint8_t rhport) { + TU_LOG2("dcd init\r\n"); (void) rhport; } -void dcd_int_enable(uint8_t rhport) -{ +void dcd_int_enable(uint8_t rhport) { (void) rhport; NVIC_EnableIRQ(USBD_IRQn); } -void dcd_int_disable(uint8_t rhport) -{ +void dcd_int_disable(uint8_t rhport) { (void) rhport; NVIC_DisableIRQ(USBD_IRQn); } -void dcd_set_address (uint8_t rhport, uint8_t dev_addr) -{ +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { (void) rhport; (void) dev_addr; // Set Address is automatically update by hw controller, nothing to do @@ -278,8 +257,7 @@ void dcd_set_address (uint8_t rhport, uint8_t dev_addr) NRF_USBD->INTENSET = USBD_INTEN_USBEVENT_Msk; } -void dcd_remote_wakeup(uint8_t rhport) -{ +void dcd_remote_wakeup(uint8_t rhport) { (void) rhport; // Bring controller out of low power mode @@ -288,8 +266,7 @@ void dcd_remote_wakeup(uint8_t rhport) } // disconnect by disabling internal pull-up resistor on D+/D- -void dcd_disconnect(uint8_t rhport) -{ +void dcd_disconnect(uint8_t rhport) { (void) rhport; NRF_USBD->USBPULLUP = 0; @@ -299,14 +276,12 @@ void dcd_disconnect(uint8_t rhport) } // connect by enabling internal pull-up resistor on D+/D- -void dcd_connect(uint8_t rhport) -{ +void dcd_connect(uint8_t rhport) { (void) rhport; NRF_USBD->USBPULLUP = 1; } -void dcd_sof_enable(uint8_t rhport, bool en) -{ +void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; (void) en; @@ -316,36 +291,32 @@ void dcd_sof_enable(uint8_t rhport, bool en) //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ -bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) -{ +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const* desc_edpt) { (void) rhport; uint8_t const ep_addr = desc_edpt->bEndpointAddress; - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); _dcd.xfer[epnum][dir].mps = tu_edpt_packet_size(desc_edpt); - if (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS) - { - if (dir == TUSB_DIR_OUT) - { + if (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS) { + if (dir == TUSB_DIR_OUT) { NRF_USBD->INTENSET = TU_BIT(USBD_INTEN_ENDEPOUT0_Pos + epnum); NRF_USBD->EPOUTEN |= TU_BIT(epnum); // Write any value to SIZE register will allow nRF to ACK/accept data NRF_USBD->SIZE.EPOUT[epnum] = 0; - }else - { + } else { NRF_USBD->INTENSET = TU_BIT(USBD_INTEN_ENDEPIN0_Pos + epnum); - NRF_USBD->EPINEN |= TU_BIT(epnum); + NRF_USBD->EPINEN |= TU_BIT(epnum); } - } - else - { + // clear stall and reset DataToggle + NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_UnStall << USBD_EPSTALL_STALL_Pos) | ep_addr; + NRF_USBD->DTOGGLE = (USBD_DTOGGLE_VALUE_Data0 << USBD_DTOGGLE_VALUE_Pos) | ep_addr; + } else { TU_ASSERT(epnum == EP_ISO_NUM); - if (dir == TUSB_DIR_OUT) - { + if (dir == TUSB_DIR_OUT) { // SPLIT ISO buffer when ISO IN endpoint is already opened. if (_dcd.xfer[EP_ISO_NUM][TUSB_DIR_IN].mps) NRF_USBD->ISOSPLIT = USBD_ISOSPLIT_SPLIT_HalfIN; @@ -358,9 +329,7 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) // Enable SOF and ISOOUT interrupts, and ISOOUT endpoint. NRF_USBD->INTENSET = USBD_INTENSET_ENDISOOUT_Msk | USBD_INTENSET_SOF_Msk; NRF_USBD->EPOUTEN |= USBD_EPOUTEN_ISOOUT_Msk; - } - else - { + } else { NRF_USBD->EVENTS_ENDISOIN = 0; // SPLIT ISO buffer when ISO OUT endpoint is already opened. @@ -371,43 +340,38 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) // Enable SOF and ISOIN interrupts, and ISOIN endpoint. NRF_USBD->INTENSET = USBD_INTENSET_ENDISOIN_Msk | USBD_INTENSET_SOF_Msk; - NRF_USBD->EPINEN |= USBD_EPINEN_ISOIN_Msk; + NRF_USBD->EPINEN |= USBD_EPINEN_ISOIN_Msk; } } - // clear stall and reset DataToggle - NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_UnStall << USBD_EPSTALL_STALL_Pos) | ep_addr; - NRF_USBD->DTOGGLE = (USBD_DTOGGLE_VALUE_Data0 << USBD_DTOGGLE_VALUE_Pos) | ep_addr; - - __ISB(); __DSB(); + __ISB(); + __DSB(); return true; } -void dcd_edpt_close_all (uint8_t rhport) -{ +void dcd_edpt_close_all(uint8_t rhport) { // disable interrupt to prevent race condition dcd_int_disable(rhport); // disable all non-control (bulk + interrupt) endpoints - for ( uint8_t ep = 1; ep < EP_CBI_COUNT; ep++ ) - { + for (uint8_t ep = 1; ep < EP_CBI_COUNT; ep++) { NRF_USBD->INTENCLR = TU_BIT(USBD_INTEN_ENDEPOUT0_Pos + ep) | TU_BIT(USBD_INTEN_ENDEPIN0_Pos + ep); NRF_USBD->TASKS_STARTEPIN[ep] = 0; NRF_USBD->TASKS_STARTEPOUT[ep] = 0; - tu_memclr(_dcd.xfer[ep], 2*sizeof(xfer_td_t)); + tu_memclr(_dcd.xfer[ep], 2 * sizeof(xfer_td_t)); } // disable both ISO NRF_USBD->INTENCLR = USBD_INTENCLR_SOF_Msk | USBD_INTENCLR_ENDISOOUT_Msk | USBD_INTENCLR_ENDISOIN_Msk; NRF_USBD->ISOSPLIT = USBD_ISOSPLIT_SPLIT_OneDir; - NRF_USBD->TASKS_STARTISOIN = 0; + NRF_USBD->TASKS_STARTISOIN = 0; NRF_USBD->TASKS_STARTISOOUT = 0; - tu_memclr(_dcd.xfer[EP_ISO_NUM], 2*sizeof(xfer_td_t)); + tu_memclr(_dcd.xfer[EP_ISO_NUM], 2 * sizeof(xfer_td_t)); // de-activate all non-control NRF_USBD->EPOUTEN = 1UL; @@ -416,107 +380,89 @@ void dcd_edpt_close_all (uint8_t rhport) dcd_int_enable(rhport); } -void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) -{ +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { (void) rhport; uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); - if (epnum != EP_ISO_NUM) - { + if (epnum != EP_ISO_NUM) { // CBI - if (dir == TUSB_DIR_OUT) - { + if (dir == TUSB_DIR_OUT) { NRF_USBD->INTENCLR = TU_BIT(USBD_INTEN_ENDEPOUT0_Pos + epnum); NRF_USBD->EPOUTEN &= ~TU_BIT(epnum); - } - else - { + } else { NRF_USBD->INTENCLR = TU_BIT(USBD_INTEN_ENDEPIN0_Pos + epnum); NRF_USBD->EPINEN &= ~TU_BIT(epnum); } - } - else - { + } else { _dcd.xfer[EP_ISO_NUM][dir].mps = 0; // ISO - if (dir == TUSB_DIR_OUT) - { + if (dir == TUSB_DIR_OUT) { NRF_USBD->INTENCLR = USBD_INTENCLR_ENDISOOUT_Msk; NRF_USBD->EPOUTEN &= ~USBD_EPOUTEN_ISOOUT_Msk; NRF_USBD->EVENTS_ENDISOOUT = 0; - } - else - { + } else { NRF_USBD->INTENCLR = USBD_INTENCLR_ENDISOIN_Msk; NRF_USBD->EPINEN &= ~USBD_EPINEN_ISOIN_Msk; } // One of the ISO endpoints closed, no need to split buffers any more. NRF_USBD->ISOSPLIT = USBD_ISOSPLIT_SPLIT_OneDir; // When both ISO endpoint are close there is no need for SOF any more. - if (_dcd.xfer[EP_ISO_NUM][TUSB_DIR_IN].mps + _dcd.xfer[EP_ISO_NUM][TUSB_DIR_OUT].mps == 0) NRF_USBD->INTENCLR = USBD_INTENCLR_SOF_Msk; + if (_dcd.xfer[EP_ISO_NUM][TUSB_DIR_IN].mps + _dcd.xfer[EP_ISO_NUM][TUSB_DIR_OUT].mps == 0) + NRF_USBD->INTENCLR = USBD_INTENCLR_SOF_Msk; } _dcd.xfer[epnum][dir].started = false; - __ISB(); __DSB(); + __ISB(); + __DSB(); } -bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) -{ +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) { (void) rhport; uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); xfer_td_t* xfer = get_td(epnum, dir); TU_ASSERT(!xfer->started); - xfer->buffer = buffer; - xfer->total_len = total_bytes; + xfer->buffer = buffer; + xfer->total_len = total_bytes; xfer->actual_len = 0; // Control endpoint with zero-length packet and opposite direction to 1st request byte --> status stage bool const control_status = (epnum == 0 && total_bytes == 0 && dir != tu_edpt_dir(NRF_USBD->BMREQUESTTYPE)); - if ( control_status ) - { + if (control_status) { // Status Phase also requires EasyDMA has to be available as well !!!! edpt_dma_start(&NRF_USBD->TASKS_EP0STATUS); // The nRF doesn't interrupt on status transmit so we queue up a success response. dcd_event_xfer_complete(0, ep_addr, 0, XFER_RESULT_SUCCESS, is_in_isr()); - } - else if ( dir == TUSB_DIR_OUT ) - { + } else if (dir == TUSB_DIR_OUT) { xfer->started = true; - if ( epnum == 0 ) - { + if (epnum == 0) { // Accept next Control Out packet. TASKS_EP0RCVOUT also require EasyDMA edpt_dma_start(&NRF_USBD->TASKS_EP0RCVOUT); - }else - { + } else { // started just set, it could start DMA transfer if interrupt was trigger after this line // code only needs to start transfer (from Endpoint to RAM) when data_received was set // before started was set. If started is NOT set but data_received is, it means that // current transfer was already finished and next data is already present in endpoint and // can be consumed by future transfer - __ISB(); __DSB(); - if ( xfer->data_received && xfer->started ) - { + __ISB(); + __DSB(); + if (xfer->data_received && xfer->started) { // Data is already received previously // start DMA to copy to SRAM xfer->data_received = false; xact_out_dma(epnum); - } - else - { + } else { // nRF auto accept next Bulk/Interrupt OUT packet // nothing to do } } - } - else - { + } else { // Start DMA to copy data from RAM -> Endpoint xact_in_dma(epnum); } @@ -524,42 +470,37 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t return true; } -void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) -{ +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); xfer_td_t* xfer = get_td(epnum, dir); - if ( epnum == 0 ) - { + if (epnum == 0) { NRF_USBD->TASKS_EP0STALL = 1; - }else if (epnum != EP_ISO_NUM) - { + } else if (epnum != EP_ISO_NUM) { NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_Stall << USBD_EPSTALL_STALL_Pos) | ep_addr; // Note: nRF can auto ACK packet OUT before get stalled. // There maybe data in endpoint fifo already, we need to pull it out - if ( (dir == TUSB_DIR_OUT) && xfer->data_received ) - { + if ((dir == TUSB_DIR_OUT) && xfer->data_received) { xfer->data_received = false; xact_out_dma(epnum); } } - __ISB(); __DSB(); + __ISB(); + __DSB(); } -void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) -{ +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); - if ( epnum != 0 && epnum != EP_ISO_NUM ) - { + if (epnum != 0 && epnum != EP_ISO_NUM) { // reset data toggle to DATA0 // First write this register with VALUE=Nop to select the endpoint, then either read it to get the status from // VALUE, or write it again with VALUE=Data0 or Data1 @@ -572,26 +513,25 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) // Write any value to SIZE register will allow nRF to ACK/accept data if (dir == TUSB_DIR_OUT) NRF_USBD->SIZE.EPOUT[epnum] = 0; - __ISB(); __DSB(); + __ISB(); + __DSB(); } } /*------------------------------------------------------------------*/ /* Interrupt Handler *------------------------------------------------------------------*/ -void bus_reset(void) -{ +void bus_reset(void) { // 6.35.6 USB controller automatically disabled all endpoints (except control) NRF_USBD->EPOUTEN = 1UL; NRF_USBD->EPINEN = 1UL; - for(int i=0; i<8; i++) - { + for (int i = 0; i < 8; i++) { NRF_USBD->TASKS_STARTEPIN[i] = 0; NRF_USBD->TASKS_STARTEPOUT[i] = 0; } - NRF_USBD->TASKS_STARTISOIN = 0; + NRF_USBD->TASKS_STARTISOIN = 0; NRF_USBD->TASKS_STARTISOOUT = 0; // Clear USB Event Interrupt @@ -601,43 +541,40 @@ void bus_reset(void) // Reset interrupt NRF_USBD->INTENCLR = NRF_USBD->INTEN; NRF_USBD->INTENSET = USBD_INTEN_USBRESET_Msk | USBD_INTEN_USBEVENT_Msk | USBD_INTEN_EPDATA_Msk | - USBD_INTEN_EP0SETUP_Msk | USBD_INTEN_EP0DATADONE_Msk | USBD_INTEN_ENDEPIN0_Msk | USBD_INTEN_ENDEPOUT0_Msk; + USBD_INTEN_EP0SETUP_Msk | USBD_INTEN_EP0DATADONE_Msk | USBD_INTEN_ENDEPIN0_Msk | + USBD_INTEN_ENDEPOUT0_Msk; tu_varclr(&_dcd); _dcd.xfer[0][TUSB_DIR_IN].mps = MAX_PACKET_SIZE; _dcd.xfer[0][TUSB_DIR_OUT].mps = MAX_PACKET_SIZE; } -void dcd_int_handler(uint8_t rhport) -{ +void dcd_int_handler(uint8_t rhport) { (void) rhport; - uint32_t const inten = NRF_USBD->INTEN; + uint32_t const inten = NRF_USBD->INTEN; uint32_t int_status = 0; volatile uint32_t* regevt = &NRF_USBD->EVENTS_USBRESET; - for(uint8_t i=0; iactual_len = NRF_USBD->ISOIN.AMOUNT; @@ -646,32 +583,31 @@ void dcd_int_handler(uint8_t rhport) xfer->iso_in_transfer_ready = true; } - if ( int_status & USBD_INTEN_SOF_Msk ) - { + if (int_status & USBD_INTEN_SOF_Msk) { bool iso_enabled = false; // ISOOUT: Transfer data gathered in previous frame from buffer to RAM - if (NRF_USBD->EPOUTEN & USBD_EPOUTEN_ISOOUT_Msk) - { + if (NRF_USBD->EPOUTEN & USBD_EPOUTEN_ISOOUT_Msk) { iso_enabled = true; - xact_out_dma(EP_ISO_NUM); + // Transfer from endpoint to RAM only if data is not corrupted + if ((int_status & USBD_INTEN_USBEVENT_Msk) == 0 || + (NRF_USBD->EVENTCAUSE & USBD_EVENTCAUSE_ISOOUTCRC_Msk) == 0) { + xact_out_dma(EP_ISO_NUM); + } } // ISOIN: Notify client that data was transferred - if (NRF_USBD->EPINEN & USBD_EPINEN_ISOIN_Msk) - { + if (NRF_USBD->EPINEN & USBD_EPINEN_ISOIN_Msk) { iso_enabled = true; xfer_td_t* xfer = get_td(EP_ISO_NUM, TUSB_DIR_IN); - if ( xfer->iso_in_transfer_ready ) - { + if (xfer->iso_in_transfer_ready) { xfer->iso_in_transfer_ready = false; dcd_event_xfer_complete(0, EP_ISO_NUM | TUSB_DIR_IN_MASK, xfer->actual_len, XFER_RESULT_SUCCESS, true); } } - if ( !iso_enabled ) - { + if (!iso_enabled) { // ISO endpoint is not used, SOF is only enabled one-time for remote wakeup // so we disable it now NRF_USBD->INTENCLR = USBD_INTENSET_SOF_Msk; @@ -680,16 +616,17 @@ void dcd_int_handler(uint8_t rhport) dcd_event_bus_signal(0, DCD_EVENT_SOF, true); } - if ( int_status & USBD_INTEN_USBEVENT_Msk ) - { - TU_LOG(2, "EVENTCAUSE = 0x%04lX\r\n", NRF_USBD->EVENTCAUSE); + if (int_status & USBD_INTEN_USBEVENT_Msk) { + TU_LOG(3, "EVENTCAUSE = 0x%04" PRIX32 "\r\n", NRF_USBD->EVENTCAUSE); - enum { EVT_CAUSE_MASK = USBD_EVENTCAUSE_SUSPEND_Msk | USBD_EVENTCAUSE_RESUME_Msk | USBD_EVENTCAUSE_USBWUALLOWED_Msk }; + enum { + EVT_CAUSE_MASK = USBD_EVENTCAUSE_SUSPEND_Msk | USBD_EVENTCAUSE_RESUME_Msk | USBD_EVENTCAUSE_USBWUALLOWED_Msk | + USBD_EVENTCAUSE_ISOOUTCRC_Msk + }; uint32_t const evt_cause = NRF_USBD->EVENTCAUSE & EVT_CAUSE_MASK; NRF_USBD->EVENTCAUSE = evt_cause; // clear interrupt - if ( evt_cause & USBD_EVENTCAUSE_SUSPEND_Msk ) - { + if (evt_cause & USBD_EVENTCAUSE_SUSPEND_Msk) { // Put controller into low power mode // Leave HFXO disable to application, since it may be used by other peripherals NRF_USBD->LOWPOWER = 1; @@ -697,8 +634,7 @@ void dcd_int_handler(uint8_t rhport) dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); } - if ( evt_cause & USBD_EVENTCAUSE_USBWUALLOWED_Msk ) - { + if (evt_cause & USBD_EVENTCAUSE_USBWUALLOWED_Msk) { // USB is out of low power mode, and wakeup is allowed // Initiate RESUME signal NRF_USBD->DPDMVALUE = USBD_DPDMVALUE_STATE_Resume; @@ -710,34 +646,29 @@ void dcd_int_handler(uint8_t rhport) NRF_USBD->INTENSET = USBD_INTENSET_SOF_Msk; } - if ( evt_cause & USBD_EVENTCAUSE_RESUME_Msk ) - { + if (evt_cause & USBD_EVENTCAUSE_RESUME_Msk) { dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); } } // Setup tokens are specific to the Control endpoint. - if ( int_status & USBD_INTEN_EP0SETUP_Msk ) - { - uint8_t const setup[8] = - { - NRF_USBD->BMREQUESTTYPE , NRF_USBD->BREQUEST, NRF_USBD->WVALUEL , NRF_USBD->WVALUEH, - NRF_USBD->WINDEXL , NRF_USBD->WINDEXH , NRF_USBD->WLENGTHL, NRF_USBD->WLENGTHH + if (int_status & USBD_INTEN_EP0SETUP_Msk) { + uint8_t const setup[8] = { + NRF_USBD->BMREQUESTTYPE, NRF_USBD->BREQUEST, NRF_USBD->WVALUEL, NRF_USBD->WVALUEH, + NRF_USBD->WINDEXL, NRF_USBD->WINDEXH, NRF_USBD->WLENGTHL, NRF_USBD->WLENGTHH }; // nrf5x hw auto handle set address, there is no need to inform usb stack - tusb_control_request_t const * request = (tusb_control_request_t const *) setup; + tusb_control_request_t const* request = (tusb_control_request_t const*) setup; - if ( !(TUSB_REQ_RCPT_DEVICE == request->bmRequestType_bit.recipient && - TUSB_REQ_TYPE_STANDARD == request->bmRequestType_bit.type && - TUSB_REQ_SET_ADDRESS == request->bRequest) ) - { + if (!(TUSB_REQ_RCPT_DEVICE == request->bmRequestType_bit.recipient && + TUSB_REQ_TYPE_STANDARD == request->bmRequestType_bit.type && + TUSB_REQ_SET_ADDRESS == request->bRequest)) { dcd_event_setup_received(0, setup, true); } } - if ( int_status & EDPT_END_ALL_MASK ) - { + if (int_status & EDPT_END_ALL_MASK) { // DMA complete move data from SRAM <-> Endpoint // Must before endpoint transfer handling edpt_dma_end(); @@ -779,30 +710,24 @@ void dcd_int_handler(uint8_t rhport) * len if Host decides to sent fewer bytes, it this case transaction is also * complete and next transfer is not initiated here like for CBI. */ - for(uint8_t epnum=0; epnumEPOUT[epnum].AMOUNT; - xfer->buffer += xact_len; + xfer->buffer += xact_len; xfer->actual_len += xact_len; // Transfer complete if transaction len < Max Packet Size or total len is transferred - if ( (epnum != EP_ISO_NUM) && (xact_len == xfer->mps) && (xfer->actual_len < xfer->total_len) ) - { - if ( epnum == 0 ) - { + if ((epnum != EP_ISO_NUM) && (xact_len == xfer->mps) && (xfer->actual_len < xfer->total_len)) { + if (epnum == 0) { // Accept next Control Out packet. TASKS_EP0RCVOUT also require EasyDMA edpt_dma_start(&NRF_USBD->TASKS_EP0RCVOUT); - }else - { + } else { // nRF auto accept next Bulk/Interrupt OUT packet // nothing to do } - }else - { + } else { TU_ASSERT(xfer->started,); xfer->total_len = xfer->actual_len; xfer->started = false; @@ -816,11 +741,11 @@ void dcd_int_handler(uint8_t rhport) } // Endpoint <-> Host ( In & OUT ) - if ( int_status & (USBD_INTEN_EPDATA_Msk | USBD_INTEN_EP0DATADONE_Msk) ) - { + if (int_status & (USBD_INTEN_EPDATA_Msk | USBD_INTEN_EP0DATADONE_Msk)) { uint32_t data_status = NRF_USBD->EPDATASTATUS; NRF_USBD->EPDATASTATUS = data_status; - __ISB(); __DSB(); + __ISB(); + __DSB(); // EP0DATADONE is set with either Control Out on IN Data // Since EPDATASTATUS cannot be used to determine whether it is control OUT or IN. @@ -829,22 +754,18 @@ void dcd_int_handler(uint8_t rhport) bool const is_control_out = (int_status & USBD_INTEN_EP0DATADONE_Msk) && !(NRF_USBD->BMREQUESTTYPE & TUSB_DIR_IN_MASK); // CBI In: Endpoint -> Host (transaction complete) - for(uint8_t epnum=0; epnumEPIN[epnum].AMOUNT; - xfer->buffer += xact_len; + xfer->buffer += xact_len; xfer->actual_len += xact_len; - if ( xfer->actual_len < xfer->total_len ) - { + if (xfer->actual_len < xfer->total_len) { // Start DMA to copy next data packet xact_in_dma(epnum); - } else - { + } else { // CBI IN complete dcd_event_xfer_complete(0, epnum | TUSB_DIR_IN_MASK, xfer->actual_len, XFER_RESULT_SUCCESS, true); } @@ -852,17 +773,13 @@ void dcd_int_handler(uint8_t rhport) } // CBI OUT: Host -> Endpoint - for(uint8_t epnum=0; epnumstarted && xfer->actual_len < xfer->total_len ) - { + if (xfer->started && xfer->actual_len < xfer->total_len) { xact_out_dma(epnum); - }else - { + } else { // Data overflow !!! Nah, nRF will auto accept next Bulk/Interrupt OUT packet // Mark this endpoint with data received xfer->data_received = true; @@ -886,76 +803,80 @@ void dcd_int_handler(uint8_t rhport) #define SD_MAGIC_NUMBER 0x51B1E5DB #endif -static inline bool is_sd_existed(void) -{ +TU_ATTR_ALWAYS_INLINE static inline bool is_sd_existed(void) { return *((uint32_t*)(SOFTDEVICE_INFO_STRUCT_ADDRESS+4)) == SD_MAGIC_NUMBER; } // check if SD is existed and enabled -static inline bool is_sd_enabled(void) -{ +TU_ATTR_ALWAYS_INLINE static inline bool is_sd_enabled(void) { if ( !is_sd_existed() ) return false; - uint8_t sd_en = false; (void) sd_softdevice_is_enabled(&sd_en); return sd_en; } #endif -static bool hfclk_running(void) -{ +static bool hfclk_running(void) { #ifdef SOFTDEVICE_PRESENT - if ( is_sd_enabled() ) - { + if ( is_sd_enabled() ) { uint32_t is_running = 0; (void) sd_clock_hfclk_is_running(&is_running); return (is_running ? true : false); } #endif +#if CFG_TUD_NRF_NRFX_VERSION == 1 + return nrf_clock_hf_is_running(NRF_CLOCK_HFCLK_HIGH_ACCURACY); +#else return nrf_clock_hf_is_running(NRF_CLOCK, NRF_CLOCK_HFCLK_HIGH_ACCURACY); +#endif } -static void hfclk_enable(void) -{ +static void hfclk_enable(void) { #if CFG_TUSB_OS == OPT_OS_MYNEWT usb_clock_request(); return; #else // already running, nothing to do - if ( hfclk_running() ) return; + if (hfclk_running()) return; #ifdef SOFTDEVICE_PRESENT - if ( is_sd_enabled() ) - { + if ( is_sd_enabled() ) { (void)sd_clock_hfclk_request(); return; } #endif +#if CFG_TUD_NRF_NRFX_VERSION == 1 + nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED); + nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTART); +#else nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_HFCLKSTARTED); nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTART); #endif +#endif } -static void hfclk_disable(void) -{ +static void hfclk_disable(void) { #if CFG_TUSB_OS == OPT_OS_MYNEWT usb_clock_release(); return; #else #ifdef SOFTDEVICE_PRESENT - if ( is_sd_enabled() ) - { + if ( is_sd_enabled() ) { (void)sd_clock_hfclk_release(); return; } #endif +#if CFG_TUD_NRF_NRFX_VERSION == 1 + nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTOP); +#else nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTOP); #endif +#endif } // Power & Clock Peripheral on nRF5x to manage USB @@ -968,8 +889,7 @@ static void hfclk_disable(void) // Therefore this function must be called to handle USB power event by // - nrfx_power_usbevt_init() : if Softdevice is not used or enabled // - SoftDevice SOC event : if SD is used and enabled -void tusb_hal_nrf_power_event (uint32_t event) -{ +void tusb_hal_nrf_power_event(uint32_t event) { // Value is chosen to be as same as NRFX_POWER_USB_EVT_* in nrfx_power.h enum { USB_EVT_DETECTED = 0, @@ -978,50 +898,41 @@ void tusb_hal_nrf_power_event (uint32_t event) }; #if CFG_TUSB_DEBUG >= 2 - const char* const power_evt_str[] = { "Detected", "Removed", "Ready" }; + const char* const power_evt_str[] = {"Detected", "Removed", "Ready"}; TU_LOG(2, "Power USB event: %s\r\n", power_evt_str[event]); #endif - switch ( event ) - { + switch (event) { case USB_EVT_DETECTED: - if ( !NRF_USBD->ENABLE ) - { + if (!NRF_USBD->ENABLE) { // Prepare for receiving READY event: disable interrupt since we will blocking wait NRF_USBD->INTENCLR = USBD_INTEN_USBEVENT_Msk; NRF_USBD->EVENTCAUSE = USBD_EVENTCAUSE_READY_Msk; - __ISB(); __DSB(); // for sync + __ISB(); + __DSB(); // for sync #ifdef NRF52_SERIES // NRF53 does not need this errata // ERRATA 171, 187, 166 - if ( nrfx_usbd_errata_187() ) - { + if (nrfx_usbd_errata_187()) { // CRITICAL_REGION_ENTER(); - if ( *((volatile uint32_t *) (0x4006EC00)) == 0x00000000 ) - { - *((volatile uint32_t *) (0x4006EC00)) = 0x00009375; - *((volatile uint32_t *) (0x4006ED14)) = 0x00000003; - *((volatile uint32_t *) (0x4006EC00)) = 0x00009375; - } - else - { - *((volatile uint32_t *) (0x4006ED14)) = 0x00000003; + if (*((volatile uint32_t*) (0x4006EC00)) == 0x00000000) { + *((volatile uint32_t*) (0x4006EC00)) = 0x00009375; + *((volatile uint32_t*) (0x4006ED14)) = 0x00000003; + *((volatile uint32_t*) (0x4006EC00)) = 0x00009375; + } else { + *((volatile uint32_t*) (0x4006ED14)) = 0x00000003; } // CRITICAL_REGION_EXIT(); } - if ( nrfx_usbd_errata_171() ) - { + if (nrfx_usbd_errata_171()) { // CRITICAL_REGION_ENTER(); - if ( *((volatile uint32_t *) (0x4006EC00)) == 0x00000000 ) - { - *((volatile uint32_t *) (0x4006EC00)) = 0x00009375; - *((volatile uint32_t *) (0x4006EC14)) = 0x000000C0; - *((volatile uint32_t *) (0x4006EC00)) = 0x00009375; - } - else - { - *((volatile uint32_t *) (0x4006EC14)) = 0x000000C0; + if (*((volatile uint32_t*) (0x4006EC00)) == 0x00000000) { + *((volatile uint32_t*) (0x4006EC00)) = 0x00009375; + *((volatile uint32_t*) (0x4006EC14)) = 0x000000C0; + *((volatile uint32_t*) (0x4006EC00)) = 0x00009375; + } else { + *((volatile uint32_t*) (0x4006EC14)) = 0x000000C0; } // CRITICAL_REGION_EXIT(); } @@ -1029,64 +940,58 @@ void tusb_hal_nrf_power_event (uint32_t event) // Enable the peripheral (will cause Ready event) NRF_USBD->ENABLE = 1; - __ISB(); __DSB(); // for sync + __ISB(); + __DSB(); // for sync // Enable HFCLK hfclk_enable(); } - break; + break; case USB_EVT_READY: // Skip if pull-up is enabled and HCLK is already running. // Application probably call this more than necessary. - if ( NRF_USBD->USBPULLUP && hfclk_running() ) break; + if (NRF_USBD->USBPULLUP && hfclk_running()) break; // Waiting for USBD peripheral enabled - while ( !(USBD_EVENTCAUSE_READY_Msk & NRF_USBD->EVENTCAUSE) ) { } + while (!(USBD_EVENTCAUSE_READY_Msk & NRF_USBD->EVENTCAUSE)) {} NRF_USBD->EVENTCAUSE = USBD_EVENTCAUSE_READY_Msk; - __ISB(); __DSB(); // for sync + __ISB(); + __DSB(); // for sync #ifdef NRF52_SERIES - if ( nrfx_usbd_errata_171() ) - { + if (nrfx_usbd_errata_171()) { // CRITICAL_REGION_ENTER(); - if ( *((volatile uint32_t *) (0x4006EC00)) == 0x00000000 ) - { - *((volatile uint32_t *) (0x4006EC00)) = 0x00009375; - *((volatile uint32_t *) (0x4006EC14)) = 0x00000000; - *((volatile uint32_t *) (0x4006EC00)) = 0x00009375; - } - else - { - *((volatile uint32_t *) (0x4006EC14)) = 0x00000000; + if (*((volatile uint32_t*) (0x4006EC00)) == 0x00000000) { + *((volatile uint32_t*) (0x4006EC00)) = 0x00009375; + *((volatile uint32_t*) (0x4006EC14)) = 0x00000000; + *((volatile uint32_t*) (0x4006EC00)) = 0x00009375; + } else { + *((volatile uint32_t*) (0x4006EC14)) = 0x00000000; } // CRITICAL_REGION_EXIT(); } - if ( nrfx_usbd_errata_187() ) - { + if (nrfx_usbd_errata_187()) { // CRITICAL_REGION_ENTER(); - if ( *((volatile uint32_t *) (0x4006EC00)) == 0x00000000 ) - { - *((volatile uint32_t *) (0x4006EC00)) = 0x00009375; - *((volatile uint32_t *) (0x4006ED14)) = 0x00000000; - *((volatile uint32_t *) (0x4006EC00)) = 0x00009375; - } - else - { - *((volatile uint32_t *) (0x4006ED14)) = 0x00000000; + if (*((volatile uint32_t*) (0x4006EC00)) == 0x00000000) { + *((volatile uint32_t*) (0x4006EC00)) = 0x00009375; + *((volatile uint32_t*) (0x4006ED14)) = 0x00000000; + *((volatile uint32_t*) (0x4006EC00)) = 0x00009375; + } else { + *((volatile uint32_t*) (0x4006ED14)) = 0x00000000; } // CRITICAL_REGION_EXIT(); } - if ( nrfx_usbd_errata_166() ) - { - *((volatile uint32_t *) (NRF_USBD_BASE + 0x800)) = 0x7E3; - *((volatile uint32_t *) (NRF_USBD_BASE + 0x804)) = 0x40; + if (nrfx_usbd_errata_166()) { + *((volatile uint32_t*) (NRF_USBD_BASE + 0x800)) = 0x7E3; + *((volatile uint32_t*) (NRF_USBD_BASE + 0x804)) = 0x40; - __ISB(); __DSB(); + __ISB(); + __DSB(); } #endif @@ -1098,30 +1003,31 @@ void tusb_hal_nrf_power_event (uint32_t event) // Enable interrupt, priorities should be set by application NVIC_ClearPendingIRQ(USBD_IRQn); + // Don't enable USBD interrupt yet, if dcd_init() did not finish yet // Interrupt will be enabled by tud_init(), when USB stack is ready // to handle interrupts. - if (tud_inited()) - { + if (tud_inited()) { NVIC_EnableIRQ(USBD_IRQn); } // Wait for HFCLK - while ( !hfclk_running() ) { } + while (!hfclk_running()) {} // Enable pull up NRF_USBD->USBPULLUP = 1; - __ISB(); __DSB(); // for sync - break; + __ISB(); + __DSB(); // for sync + break; case USB_EVT_REMOVED: - if ( NRF_USBD->ENABLE ) - { + if (NRF_USBD->ENABLE) { // Abort all transfers // Disable pull up NRF_USBD->USBPULLUP = 0; - __ISB(); __DSB(); // for sync + __ISB(); + __DSB(); // for sync // Disable Interrupt NVIC_DisableIRQ(USBD_IRQn); @@ -1130,15 +1036,17 @@ void tusb_hal_nrf_power_event (uint32_t event) NRF_USBD->INTENCLR = NRF_USBD->INTEN; NRF_USBD->ENABLE = 0; - __ISB(); __DSB(); // for sync + __ISB(); + __DSB(); // for sync hfclk_disable(); dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, is_in_isr()); } - break; + break; - default: break; + default: + break; } } diff --git a/src/portable/nxp/khci/dcd_khci.c b/src/portable/nxp/khci/dcd_khci.c index 5c65ea33d..dc71117b3 100644 --- a/src/portable/nxp/khci/dcd_khci.c +++ b/src/portable/nxp/khci/dcd_khci.c @@ -269,9 +269,21 @@ void dcd_init(uint8_t rhport) { (void) rhport; + // save crystal-less setting (if available) + #if defined(FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED) && FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED == 1 + uint32_t clk_recover_irc_en = KHCI->CLK_RECOVER_IRC_EN; + uint32_t clk_recover_ctrl = KHCI->CLK_RECOVER_CTRL; + #endif + KHCI->USBTRC0 |= USB_USBTRC0_USBRESET_MASK; while (KHCI->USBTRC0 & USB_USBTRC0_USBRESET_MASK); + // restore crystal-less setting (if available) + #if defined(FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED) && FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED == 1 + KHCI->CLK_RECOVER_IRC_EN = clk_recover_irc_en; + KHCI->CLK_RECOVER_CTRL |= clk_recover_ctrl; + #endif + tu_memclr(&_dcd, sizeof(_dcd)); KHCI->USBTRC0 |= TU_BIT(6); /* software must set this bit to 1 */ KHCI->BDTPAGE1 = (uint8_t)((uintptr_t)_dcd.bdt >> 8); diff --git a/src/portable/nxp/khci/hcd_khci.c b/src/portable/nxp/khci/hcd_khci.c index 55327e02d..57684b259 100644 --- a/src/portable/nxp/khci/hcd_khci.c +++ b/src/portable/nxp/khci/hcd_khci.c @@ -447,6 +447,10 @@ void hcd_port_reset(uint8_t rhport) _hcd.need_reset = false; } +void hcd_port_reset_end(uint8_t rhport) { + (void) rhport; +} + tusb_speed_t hcd_port_speed_get(uint8_t rhport) { (void)rhport; @@ -583,8 +587,9 @@ bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { /*--------------------------------------------------------------------+ * ISR *--------------------------------------------------------------------+*/ -void hcd_int_handler(uint8_t rhport) +void hcd_int_handler(uint8_t rhport, bool in_isr) { + (void) in_isr; uint32_t is = KHCI->ISTAT; uint32_t msk = KHCI->INTEN; diff --git a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c index 7ca698a93..cc18cf59b 100644 --- a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c +++ b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c @@ -34,20 +34,26 @@ * - LPC54114 * - LPC55s69 */ -#if CFG_TUD_ENABLED && ( CFG_TUSB_MCU == OPT_MCU_LPC11UXX || \ - CFG_TUSB_MCU == OPT_MCU_LPC13XX || \ - CFG_TUSB_MCU == OPT_MCU_LPC15XX || \ - CFG_TUSB_MCU == OPT_MCU_LPC51UXX || \ - CFG_TUSB_MCU == OPT_MCU_LPC54XXX || \ - CFG_TUSB_MCU == OPT_MCU_LPC55XX) +#if CFG_TUD_ENABLED && defined(TUP_USBIP_IP3511) //--------------------------------------------------------------------+ // INCLUDE //--------------------------------------------------------------------+ -#if CFG_TUSB_MCU == OPT_MCU_LPC11UXX || CFG_TUSB_MCU == OPT_MCU_LPC13XX || CFG_TUSB_MCU == OPT_MCU_LPC15XX +#if TU_CHECK_MCU(OPT_MCU_LPC11UXX, OPT_MCU_LPC13XX, OPT_MCU_LPC15XX) // LPCOpen + #ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wunused-parameter" + #pragma GCC diagnostic ignored "-Wstrict-prototypes" + #endif + #include "chip.h" + + #ifdef __GNUC__ + #pragma GCC diagnostic pop + #endif + #else // SDK #include "fsl_device_registers.h" @@ -80,7 +86,7 @@ typedef struct { enum { NBYTES_ISO_FS_MAX = 1023, // FS ISO NBYTES_ISO_HS_MAX = 1024, // HS ISO - NBYTES_CBI_FS_MAX = 64, // FS control/bulk/interrupt + NBYTES_CBI_FS_MAX = 64, // FS control/bulk/interrupt. TODO some FS can do burst with higher size e.g 1024. Need to test NBYTES_CBI_HS_MAX = 32767 // can be up to all 15-bit, but only tested with 4096 }; @@ -90,26 +96,36 @@ enum { }; enum { - CMDSTAT_DEVICE_ADDR_MASK = TU_BIT(7 )-1, - CMDSTAT_DEVICE_ENABLE_MASK = TU_BIT(7 ), - CMDSTAT_SETUP_RECEIVED_MASK = TU_BIT(8 ), - CMDSTAT_DEVICE_CONNECT_MASK = TU_BIT(16), // reflect the soft-connect only, does not reflect the actual attached state - CMDSTAT_DEVICE_SUSPEND_MASK = TU_BIT(17), - // 23-22 is link speed (only available for HighSpeed port) - CMDSTAT_CONNECT_CHANGE_MASK = TU_BIT(24), - CMDSTAT_SUSPEND_CHANGE_MASK = TU_BIT(25), - CMDSTAT_RESET_CHANGE_MASK = TU_BIT(26), - CMDSTAT_VBUS_DEBOUNCED_MASK = TU_BIT(28), + DEVCMDSTAT_DEVICE_ADDR_MASK = TU_BIT(7 )-1, + DEVCMDSTAT_DEVICE_ENABLE_MASK = TU_BIT(7 ), + DEVCMDSTAT_SETUP_RECEIVED_MASK = TU_BIT(8 ), + DEVCMDSTAT_DEVICE_CONNECT_MASK = TU_BIT(16), // reflect the soft-connect only, does not reflect the actual attached state + DEVCMDSTAT_DEVICE_SUSPEND_MASK = TU_BIT(17), + // 23-22 is link speed (only available for HighSpeed port) + DEVCMDSTAT_CONNECT_CHANGE_MASK = TU_BIT(24), + DEVCMDSTAT_SUSPEND_CHANGE_MASK = TU_BIT(25), + DEVCMDSTAT_RESET_CHANGE_MASK = TU_BIT(26), + DEVCMDSTAT_VBUS_DEBOUNCED_MASK = TU_BIT(28), }; enum { - CMDSTAT_SPEED_SHIFT = 22 + DEVCMDSTAT_SPEED_SHIFT = 22 }; //--------------------------------------------------------------------+ // Endpoint Command/Status List //--------------------------------------------------------------------+ +// EP Command/Status field definition +enum { + EPCS_TYPE = TU_BIT(26), + EPCS_RF_TV = TU_BIT(27), + EPCS_TOGGLE_RESET = TU_BIT(28), + EPCS_STALL = TU_BIT(29), + EPCS_DISABLED = TU_BIT(30), + EPCS_ACTIVE = TU_BIT(31), +}; + // Endpoint Command/Status typedef union TU_ATTR_PACKED { @@ -133,8 +149,8 @@ typedef union TU_ATTR_PACKED volatile struct { uint32_t TU_RESERVED : 26; - uint32_t is_iso : 1 ; - uint32_t toggle_mode : 1 ; + uint32_t type : 1 ; + uint32_t rf_tv : 1 ; // rate feedback or toggle value uint32_t toggle_reset : 1 ; uint32_t stall : 1 ; uint32_t disable : 1 ; @@ -180,6 +196,7 @@ typedef struct 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) +// TODO find way to save memory CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(64) static uint8_t dummy[8]; //--------------------------------------------------------------------+ @@ -188,59 +205,73 @@ CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(64) static uint8_t dummy[8]; typedef struct { - dcd_registers_t* regs; // registers - const tusb_speed_t max_speed; // max link speed - const IRQn_Type irqnum; // IRQ number - const uint8_t ep_pairs; // Max bi-directional Endpoints + dcd_registers_t* regs; // registers + const bool is_highspeed; // max link speed + const IRQn_Type irqnum; // IRQ number + const uint8_t ep_pairs; // Max bi-directional Endpoints }dcd_controller_t; #ifdef INCLUDE_FSL_DEVICE_REGISTERS -static const dcd_controller_t _dcd_controller[] = -{ - { .regs = (dcd_registers_t*) USB0_BASE , .max_speed = TUSB_SPEED_FULL, .irqnum = USB0_IRQn, .ep_pairs = FSL_FEATURE_USB_EP_NUM }, +static const dcd_controller_t _dcd_controller[] = { + { .regs = (dcd_registers_t*) USB0_BASE , .is_highspeed = false, .irqnum = USB0_IRQn, .ep_pairs = FSL_FEATURE_USB_EP_NUM }, #if defined(FSL_FEATURE_SOC_USBHSD_COUNT) && FSL_FEATURE_SOC_USBHSD_COUNT - { .regs = (dcd_registers_t*) USBHSD_BASE, .max_speed = TUSB_SPEED_HIGH, .irqnum = USB1_IRQn, .ep_pairs = FSL_FEATURE_USBHSD_EP_NUM } + { .regs = (dcd_registers_t*) USBHSD_BASE, .is_highspeed = true, .irqnum = USB1_IRQn, .ep_pairs = FSL_FEATURE_USBHSD_EP_NUM } #endif }; #else -static const dcd_controller_t _dcd_controller[] = -{ - { .regs = (dcd_registers_t*) LPC_USB0_BASE, .max_speed = TUSB_SPEED_FULL, .irqnum = USB0_IRQn, .ep_pairs = 5 }, +static const dcd_controller_t _dcd_controller[] = { + { .regs = (dcd_registers_t*) LPC_USB0_BASE, .is_highspeed = false, .irqnum = USB0_IRQn, .ep_pairs = 5 }, }; #endif +#if defined(FSL_FEATURE_SOC_USBHSD_COUNT) && FSL_FEATURE_SOC_USBHSD_COUNT + #define IP3511_HAS_HIGHSPEED +#endif + //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ -static inline uint16_t get_buf_offset(void const * buffer) -{ +TU_ATTR_ALWAYS_INLINE static inline uint16_t get_buf_offset(void const * buffer) { uint32_t addr = (uint32_t) buffer; TU_ASSERT( (addr & 0x3f) == 0, 0 ); return ( (addr >> 6) & 0xFFFFUL ) ; } -static inline uint8_t ep_addr2id(uint8_t ep_addr) -{ +TU_ATTR_ALWAYS_INLINE static inline uint8_t ep_addr2id(uint8_t ep_addr) { return 2*(ep_addr & 0x0F) + ((ep_addr & TUSB_DIR_IN_MASK) ? 1 : 0); } +TU_ATTR_ALWAYS_INLINE static inline bool ep_is_iso(ep_cmd_sts_t* ep_cs, bool is_highspeed) { + return is_highspeed ? (ep_cs[0].cmd_sts.type && !ep_cs[0].cmd_sts.rf_tv) : ep_cs->cmd_sts.type; +} + +TU_ATTR_ALWAYS_INLINE TU_ATTR_UNUSED static inline bool ep_is_bulk(ep_cmd_sts_t* ep_cs) { + return (ep_cs[0].cmd_sts.type == 0) && (ep_cs[0].cmd_sts.rf_tv == 0); +} + +TU_ATTR_ALWAYS_INLINE static inline ep_cmd_sts_t* get_ep_cs(uint8_t ep_id) { + return _dcd.ep[ep_id]; +} + +TU_ATTR_ALWAYS_INLINE static inline bool rhport_is_highspeed(uint8_t rhport) { + return _dcd_controller[rhport].is_highspeed; +} + //--------------------------------------------------------------------+ // CONTROLLER API //--------------------------------------------------------------------+ -static void prepare_setup_packet(uint8_t rhport) -{ - if (_dcd_controller[rhport].max_speed == TUSB_SPEED_FULL ) - { - _dcd.ep[0][1].buffer_fs.offset = get_buf_offset(_dcd.setup_packet); - }else - { - _dcd.ep[0][1].buffer_hs.offset = get_buf_offset(_dcd.setup_packet); +static void prepare_setup_packet(uint8_t rhport) { + uint16_t const buf_offset = get_buf_offset(_dcd.setup_packet); + if ( _dcd_controller[rhport].is_highspeed ) { + _dcd.ep[0][1].buffer_hs.offset = buf_offset; + } else { + _dcd.ep[0][1].buffer_fs.offset = buf_offset; } } @@ -268,8 +299,8 @@ void dcd_init(uint8_t rhport) dcd_reg->DATABUFSTART = tu_align((uint32_t) &_dcd, TU_BIT(22)); // 22-bit alignment dcd_reg->INTSTAT |= dcd_reg->INTSTAT; // clear all pending interrupt dcd_reg->INTEN = INT_DEVICE_STATUS_MASK; - dcd_reg->DEVCMDSTAT |= CMDSTAT_DEVICE_ENABLE_MASK | CMDSTAT_DEVICE_CONNECT_MASK | - CMDSTAT_RESET_CHANGE_MASK | CMDSTAT_CONNECT_CHANGE_MASK | CMDSTAT_SUSPEND_CHANGE_MASK; + dcd_reg->DEVCMDSTAT |= DEVCMDSTAT_DEVICE_ENABLE_MASK | DEVCMDSTAT_DEVICE_CONNECT_MASK | + DEVCMDSTAT_RESET_CHANGE_MASK | DEVCMDSTAT_CONNECT_CHANGE_MASK | DEVCMDSTAT_SUSPEND_CHANGE_MASK; NVIC_ClearPendingIRQ(_dcd_controller[rhport].irqnum); } @@ -291,7 +322,7 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) // Response with status first before changing device address dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); - dcd_reg->DEVCMDSTAT &= ~CMDSTAT_DEVICE_ADDR_MASK; + dcd_reg->DEVCMDSTAT &= ~DEVCMDSTAT_DEVICE_ADDR_MASK; dcd_reg->DEVCMDSTAT |= dev_addr; } @@ -303,13 +334,13 @@ void dcd_remote_wakeup(uint8_t rhport) void dcd_connect(uint8_t rhport) { dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; - dcd_reg->DEVCMDSTAT |= CMDSTAT_DEVICE_CONNECT_MASK; + dcd_reg->DEVCMDSTAT |= DEVCMDSTAT_DEVICE_CONNECT_MASK; } void dcd_disconnect(uint8_t rhport) { dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; - dcd_reg->DEVCMDSTAT &= ~CMDSTAT_DEVICE_CONNECT_MASK; + dcd_reg->DEVCMDSTAT &= ~DEVCMDSTAT_DEVICE_CONNECT_MASK; } void dcd_sof_enable(uint8_t rhport, bool en) @@ -340,19 +371,39 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) _dcd.ep[ep_id][0].cmd_sts.stall = 0; _dcd.ep[ep_id][0].cmd_sts.toggle_reset = 1; - _dcd.ep[ep_id][0].cmd_sts.toggle_mode = 0; + _dcd.ep[ep_id][0].cmd_sts.rf_tv = 0; } bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) { //------------- Prepare Queue Head -------------// uint8_t ep_id = ep_addr2id(p_endpoint_desc->bEndpointAddress); + ep_cmd_sts_t* ep_cs = get_ep_cs(ep_id); // Check if endpoint is available - TU_ASSERT( _dcd.ep[ep_id][0].cmd_sts.disable && _dcd.ep[ep_id][1].cmd_sts.disable ); + TU_ASSERT( ep_cs[0].cmd_sts.disable && ep_cs[1].cmd_sts.disable ); edpt_reset(rhport, ep_id); - _dcd.ep[ep_id][0].cmd_sts.is_iso = (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS); + + switch (p_endpoint_desc->bmAttributes.xfer) { + case TUSB_XFER_ISOCHRONOUS: + ep_cs[0].cmd_sts.type = 1; + break; + + case TUSB_XFER_INTERRUPT: + // What is interrupt endpoint in rate feedback mode ? + if ( rhport_is_highspeed(rhport) ) { + ep_cs[0].cmd_sts.type = 1; + ep_cs[0].cmd_sts.rf_tv = 1; + } + break; + + case TUSB_XFER_BULK: + // nothing to do both type and rf_tv are 0 + break; + + default: break; + } // Enable EP interrupt dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; @@ -379,42 +430,50 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) _dcd.ep[ep_id][0].cmd_sts.disable = _dcd.ep[ep_id][1].cmd_sts.disable = 1; } -static void prepare_ep_xfer(uint8_t rhport, uint8_t ep_id, uint16_t buf_offset, uint16_t total_bytes) -{ +static void prepare_ep_xfer(uint8_t rhport, uint8_t ep_id, uint16_t buf_offset, uint16_t total_bytes) { uint16_t nbytes; + ep_cmd_sts_t* ep_cs = get_ep_cs(ep_id); - if (_dcd_controller[rhport].max_speed == TUSB_SPEED_FULL ) - { - nbytes = tu_min16(total_bytes, _dcd.ep[ep_id][0].cmd_sts.is_iso ? NBYTES_ISO_FS_MAX : NBYTES_CBI_FS_MAX); - _dcd.ep[ep_id][0].buffer_fs.offset = buf_offset; - _dcd.ep[ep_id][0].buffer_fs.nbytes = nbytes; - }else - { - nbytes = tu_min16(total_bytes, NBYTES_CBI_HS_MAX); - _dcd.ep[ep_id][0].buffer_hs.offset = buf_offset; - _dcd.ep[ep_id][0].buffer_hs.nbytes = nbytes; + const bool is_iso = ep_is_iso(ep_cs, _dcd_controller[rhport].is_highspeed); + + if ( rhport_is_highspeed(rhport) ) { + nbytes = tu_min16(total_bytes, is_iso ? NBYTES_ISO_HS_MAX : NBYTES_CBI_HS_MAX); + #if TU_CHECK_MCU(OPT_MCU_LPC54) + // LPC54 Errata USB.1: In USB high-speed device mode, the NBytes field does not decrement after BULK OUT transfer. + // Suggested Work-around: Program the NByte to the max packet size (512) + // Actual Work-around: round up NByte to multiple of 4. + // Note: this can cause buffer overflowed and corrupt data if host send more data than total_bytes + if ( (ep_id > 1) && (ep_id & 0x01) == 0 && ep_is_bulk(ep_cs) ) { + if ( nbytes & 0x03 ) { + nbytes = tu_align4(nbytes) + 4; + } + } + #endif + + ep_cs[0].buffer_hs.offset = buf_offset; + ep_cs[0].buffer_hs.nbytes = nbytes; + }else { + nbytes = tu_min16(total_bytes, is_iso ? NBYTES_ISO_FS_MAX : NBYTES_CBI_FS_MAX); + ep_cs[0].buffer_fs.offset = buf_offset; + ep_cs[0].buffer_fs.nbytes = nbytes; } _dcd.dma[ep_id].nbytes = nbytes; - - _dcd.ep[ep_id][0].cmd_sts.active = 1; + ep_cs[0].cmd_sts.active = 1; } -bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) -{ +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) { uint8_t const ep_id = ep_addr2id(ep_addr); + if (!buffer || total_bytes == 0) { + // Although having no data, ZLPs can cause buffer overwritten to zeroes. Probably due to USB/DMA controller side + // effect/bug. Assigned buffer offset to (valid) dummy to prevent overwriting to DATABUFSTART + buffer = (uint8_t *) (uint32_t) dummy; + } + tu_memclr(&_dcd.dma[ep_id], sizeof(xfer_dma_t)); _dcd.dma[ep_id].total_bytes = total_bytes; - if (!buffer) - { - // Although having no data, ZLPs can cause buffer overwritten to zeroes. - // Probably due to USB/DMA controller side effect/bug. - // Assigned buffer offset to (valid) dummy to prevent overwriting to DATABUFSTART - buffer = (uint8_t*)(uint32_t)dummy; - } - prepare_ep_xfer(rhport, ep_id, get_buf_offset(buffer), total_bytes); return true; @@ -441,23 +500,19 @@ static void bus_reset(uint8_t rhport) dcd_reg->EPSKIP = 0xFFFFFFFF; dcd_reg->INTSTAT = dcd_reg->INTSTAT; // clear all pending interrupt - dcd_reg->DEVCMDSTAT |= CMDSTAT_SETUP_RECEIVED_MASK; // clear setup received interrupt + dcd_reg->DEVCMDSTAT |= DEVCMDSTAT_SETUP_RECEIVED_MASK; // clear setup received interrupt dcd_reg->INTEN = INT_DEVICE_STATUS_MASK | TU_BIT(0) | TU_BIT(1); // enable device status & control endpoints } -static void process_xfer_isr(uint8_t rhport, uint32_t int_status) -{ +static void process_xfer_isr(uint8_t rhport, uint32_t int_status) { uint8_t const max_ep = 2*_dcd_controller[rhport].ep_pairs; - for(uint8_t ep_id = 0; ep_id < max_ep; ep_id++ ) - { - if ( tu_bit_test(int_status, ep_id) ) - { + for(uint8_t ep_id = 0; ep_id < max_ep; ep_id++ ) { + if ( tu_bit_test(int_status, ep_id) ) { ep_cmd_sts_t * ep_cs = &_dcd.ep[ep_id][0]; xfer_dma_t* xfer_dma = &_dcd.dma[ep_id]; - if ( ep_id == 0 || ep_id == 1) - { + if ( ep_id <= 1 ) { // For control endpoint, we need to manually clear Active bit ep_cs->cmd_sts.active = 0; } @@ -465,26 +520,29 @@ static void process_xfer_isr(uint8_t rhport, uint32_t int_status) uint16_t buf_offset; uint16_t buf_nbytes; - if (_dcd_controller[rhport].max_speed == TUSB_SPEED_FULL) - { - buf_offset = ep_cs->buffer_fs.offset; - buf_nbytes = ep_cs->buffer_fs.nbytes; - }else - { + if ( rhport_is_highspeed(rhport) ) { buf_offset = ep_cs->buffer_hs.offset; buf_nbytes = ep_cs->buffer_hs.nbytes; + + #if TU_CHECK_MCU(OPT_MCU_LPC54) + // LPC54 Errata USB.2: In USB high-speed device mode, the NBytes field is not correct after BULK IN transfer + // There is no work-around. For EP in transfer, the NByte value can be ignored after a packet is transmitted. + if ( (ep_id > 1) && (ep_id & 0x01) == 1 && ep_is_bulk(ep_cs) ) { + buf_nbytes = 0; + } + #endif + } else { + buf_offset = ep_cs->buffer_fs.offset; + buf_nbytes = ep_cs->buffer_fs.nbytes; } xfer_dma->xferred_bytes += xfer_dma->nbytes - buf_nbytes; - if ( (buf_nbytes == 0) && (xfer_dma->total_bytes > xfer_dma->xferred_bytes) ) - { + if ( (buf_nbytes == 0) && (xfer_dma->total_bytes > xfer_dma->xferred_bytes) ) { // There is more data to transfer // buff_offset has been already increased by hw to correct value for next transfer prepare_ep_xfer(rhport, ep_id, buf_offset, xfer_dma->total_bytes - xfer_dma->xferred_bytes); - } - else - { + } else { // for detecting ZLP xfer_dma->total_bytes = xfer_dma->xferred_bytes; @@ -511,19 +569,16 @@ void dcd_int_handler(uint8_t rhport) //------------- Device Status -------------// if ( int_status & INT_DEVICE_STATUS_MASK ) { - dcd_reg->DEVCMDSTAT |= CMDSTAT_RESET_CHANGE_MASK | CMDSTAT_CONNECT_CHANGE_MASK | CMDSTAT_SUSPEND_CHANGE_MASK; + dcd_reg->DEVCMDSTAT |= DEVCMDSTAT_RESET_CHANGE_MASK | DEVCMDSTAT_CONNECT_CHANGE_MASK | DEVCMDSTAT_SUSPEND_CHANGE_MASK; - if ( cmd_stat & CMDSTAT_RESET_CHANGE_MASK) // bus reset + if ( cmd_stat & DEVCMDSTAT_RESET_CHANGE_MASK) // bus reset { bus_reset(rhport); tusb_speed_t speed = TUSB_SPEED_FULL; - - if (_dcd_controller[rhport].max_speed == TUSB_SPEED_HIGH) - { + if ( _dcd_controller[rhport].is_highspeed ) { // 0 : reserved, 1 : full, 2 : high, 3: super - if ( 2 == ((cmd_stat >> CMDSTAT_SPEED_SHIFT) & 0x3UL) ) - { + if ( 2 == ((cmd_stat >> DEVCMDSTAT_SPEED_SHIFT) & 0x3UL) ) { speed= TUSB_SPEED_HIGH; } } @@ -531,35 +586,35 @@ void dcd_int_handler(uint8_t rhport) dcd_event_bus_reset(rhport, speed, true); } - if (cmd_stat & CMDSTAT_CONNECT_CHANGE_MASK) + if (cmd_stat & DEVCMDSTAT_CONNECT_CHANGE_MASK) { // device disconnect - if (cmd_stat & CMDSTAT_DEVICE_ADDR_MASK) + if (cmd_stat & DEVCMDSTAT_DEVICE_ADDR_MASK) { // debouncing as this can be set when device is powering dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); } } - if (cmd_stat & CMDSTAT_SUSPEND_CHANGE_MASK) + if (cmd_stat & DEVCMDSTAT_SUSPEND_CHANGE_MASK) { // suspend signal, bus idle for more than 3ms // Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration. - if (cmd_stat & CMDSTAT_DEVICE_ADDR_MASK) + if (cmd_stat & DEVCMDSTAT_DEVICE_ADDR_MASK) { - dcd_event_bus_signal(rhport, (cmd_stat & CMDSTAT_DEVICE_SUSPEND_MASK) ? DCD_EVENT_SUSPEND : DCD_EVENT_RESUME, true); + dcd_event_bus_signal(rhport, (cmd_stat & DEVCMDSTAT_DEVICE_SUSPEND_MASK) ? DCD_EVENT_SUSPEND : DCD_EVENT_RESUME, true); } } } // Setup Receive - if ( tu_bit_test(int_status, 0) && (cmd_stat & CMDSTAT_SETUP_RECEIVED_MASK) ) + if ( tu_bit_test(int_status, 0) && (cmd_stat & DEVCMDSTAT_SETUP_RECEIVED_MASK) ) { // Follow UM flowchart to clear Active & Stall on both Control IN/OUT endpoints _dcd.ep[0][0].cmd_sts.active = _dcd.ep[1][0].cmd_sts.active = 0; _dcd.ep[0][0].cmd_sts.stall = _dcd.ep[1][0].cmd_sts.stall = 0; - dcd_reg->DEVCMDSTAT |= CMDSTAT_SETUP_RECEIVED_MASK; + dcd_reg->DEVCMDSTAT |= DEVCMDSTAT_SETUP_RECEIVED_MASK; dcd_event_setup_received(rhport, _dcd.setup_packet, true); diff --git a/src/portable/ohci/ohci.c b/src/portable/ohci/ohci.c index 413e72037..c59d4755e 100644 --- a/src/portable/ohci/ohci.c +++ b/src/portable/ohci/ohci.c @@ -157,6 +157,7 @@ static ohci_ed_t * const p_ed_head[] = static void ed_list_insert(ohci_ed_t * p_pre, ohci_ed_t * p_ed); static void ed_list_remove_by_addr(ohci_ed_t * p_head, uint8_t dev_addr); +static gtd_extra_data_t *gtd_get_extra_data(ohci_gtd_t const * const gtd); //--------------------------------------------------------------------+ // USBH-HCD API @@ -345,7 +346,7 @@ 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; + gtd_get_extra_data(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; @@ -610,6 +611,15 @@ static inline ohci_ed_t* gtd_get_ed(ohci_gtd_t const * const p_qtd) } } +static gtd_extra_data_t *gtd_get_extra_data(ohci_gtd_t const * const gtd) { + if ( gtd_is_control(gtd) ) { + uint8_t idx = ((uintptr_t)gtd - (uintptr_t)&ohci_data.control->gtd) / sizeof(ohci_data.control[0]); + return &ohci_data.gtd_extra_control[idx]; + }else { + return &ohci_data.gtd_extra[gtd - ohci_data.gtd_pool]; + } +} + static inline uint32_t gtd_xfer_byte_left(uint32_t buffer_end, uint32_t current_buffer) { // 5.2.9 OHCI sample code @@ -641,8 +651,7 @@ static void done_queue_isr(uint8_t hostid) if ( (qtd->delay_interrupt == OHCI_INT_ON_COMPLETE_YES) || (event != XFER_RESULT_SUCCESS) ) { ohci_ed_t * const ed = gtd_get_ed(qtd); - - uint32_t const xferred_bytes = qtd->expected_bytes - gtd_xfer_byte_left((uint32_t) qtd->buffer_end, (uint32_t) qtd->current_buffer_pointer); + uint32_t const xferred_bytes = gtd_get_extra_data(qtd)->expected_bytes - gtd_xfer_byte_left((uint32_t) qtd->buffer_end, (uint32_t) qtd->current_buffer_pointer); // NOTE Assuming the current list is BULK and there is no other EDs in the list has queued TDs. // When there is a error resulting this ED is halted, and this EP still has other queued TD @@ -651,7 +660,7 @@ static void done_queue_isr(uint8_t hostid) // --> HC will not process Control list (due to service ratio when Bulk list not empty) // To walk-around this, the halted ED will have TailP = HeadP (empty list condition), when clearing halt // the TailP must be set back to NULL for processing remaining TDs - if ((event != XFER_RESULT_SUCCESS)) + if (event != XFER_RESULT_SUCCESS) { ed->td_tail &= 0x0Ful; ed->td_tail |= tu_align16(ed->td_head.address); // mark halted EP as empty queue @@ -667,8 +676,9 @@ static void done_queue_isr(uint8_t hostid) } } -void hcd_int_handler(uint8_t hostid) -{ +void hcd_int_handler(uint8_t hostid, bool in_isr) { + (void) in_isr; + uint32_t const int_en = OHCI_REG->interrupt_enable; uint32_t const int_status = OHCI_REG->interrupt_status & int_en; diff --git a/src/portable/ohci/ohci.h b/src/portable/ohci/ohci.h index 2081ffabb..94bad5df7 100644 --- a/src/portable/ohci/ohci.h +++ b/src/portable/ohci/ohci.h @@ -45,6 +45,9 @@ enum { #define ED_MAX (CFG_TUH_DEVICE_MAX*CFG_TUH_ENDPOINT_MAX) #define GTD_MAX ED_MAX +// tinyUSB's OHCI implementation caps number of EDs to 8 bits +TU_VERIFY_STATIC (ED_MAX <= 256, "Reduce CFG_TUH_DEVICE_MAX or CFG_TUH_ENDPOINT_MAX"); + //--------------------------------------------------------------------+ // OHCI Data Structure //--------------------------------------------------------------------+ @@ -70,9 +73,8 @@ typedef struct TU_ATTR_ALIGNED(16) { // Word 0 uint32_t used : 1; - uint32_t index : 4; // endpoint index the td belongs to, or device address in case of control xfer - uint32_t expected_bytes : 13; // TODO available for hcd - + uint32_t index : 8; // endpoint index the gtd belongs to, or device address in case of control xfer + uint32_t : 9; // can be used uint32_t buffer_rounding : 1; uint32_t pid : 2; uint32_t delay_interrupt : 3; @@ -81,7 +83,7 @@ typedef struct TU_ATTR_ALIGNED(16) volatile uint32_t condition_code : 4; // Word 1 - volatile uint8_t* current_buffer_pointer; + uint8_t* volatile current_buffer_pointer; // Word 2 : next TD volatile uint32_t next; @@ -152,9 +154,12 @@ typedef struct TU_ATTR_ALIGNED(32) TU_VERIFY_STATIC( sizeof(ochi_itd_t) == 32, "size is not correct" ); +typedef struct { + uint16_t expected_bytes; // up to 8192 bytes so max is 13 bits +} gtd_extra_data_t; + // structure with member alignment required from large to small -typedef struct TU_ATTR_ALIGNED(256) -{ +typedef struct TU_ATTR_ALIGNED(256) { ohci_hcca_t hcca; ohci_ed_t bulk_head_ed; // static bulk head (dummy) @@ -164,14 +169,17 @@ typedef struct TU_ATTR_ALIGNED(256) struct { ohci_ed_t ed; ohci_gtd_t gtd; - }control[CFG_TUH_DEVICE_MAX+CFG_TUH_HUB+1]; + } control[CFG_TUH_DEVICE_MAX + CFG_TUH_HUB + 1]; // ochi_itd_t itd[OHCI_MAX_ITD]; // itd requires alignment of 32 ohci_ed_t ed_pool[ED_MAX]; ohci_gtd_t gtd_pool[GTD_MAX]; - volatile uint16_t frame_number_hi; + // extra data needed by TDs that can't fit in the TD struct + gtd_extra_data_t gtd_extra_control[CFG_TUH_DEVICE_MAX + CFG_TUH_HUB + 1]; + gtd_extra_data_t gtd_extra[GTD_MAX]; + volatile uint16_t frame_number_hi; } ohci_data_t; //--------------------------------------------------------------------+ diff --git a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c index 93bc1bf43..f4de3c51d 100644 --- a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c @@ -182,14 +182,6 @@ void __no_inline_not_in_flash_func(pio_usb_host_irq_handler)(uint8_t root_id) { root_port_t *rport = PIO_USB_ROOT_PORT(root_id); uint32_t const ints = rport->ints; - if ( ints & PIO_USB_INTS_CONNECT_BITS ) { - hcd_event_device_attach(tu_rhport, true); - } - - if ( ints & PIO_USB_INTS_DISCONNECT_BITS ) { - hcd_event_device_remove(tu_rhport, true); - } - if ( ints & PIO_USB_INTS_ENDPOINT_COMPLETE_BITS ) { handle_endpoint_irq(rport, XFER_RESULT_SUCCESS, &rport->ep_complete); } @@ -202,6 +194,14 @@ void __no_inline_not_in_flash_func(pio_usb_host_irq_handler)(uint8_t root_id) { handle_endpoint_irq(rport, XFER_RESULT_FAILED, &rport->ep_error); } + if ( ints & PIO_USB_INTS_CONNECT_BITS ) { + hcd_event_device_attach(tu_rhport, true); + } + + if ( ints & PIO_USB_INTS_DISCONNECT_BITS ) { + hcd_event_device_remove(tu_rhport, true); + } + // clear all rport->ints &= ~ints; } diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index e8cee73fd..bc0deee32 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -48,7 +48,7 @@ *------------------------------------------------------------------*/ // Init these in dcd_init -static uint8_t *next_buffer_ptr; +static uint8_t* next_buffer_ptr; // USB_MAX_ENDPOINTS Endpoints, direction TUSB_DIR_OUT for out and TUSB_DIR_IN for in. static struct hw_endpoint hw_endpoints[USB_MAX_ENDPOINTS][2]; @@ -56,79 +56,70 @@ static struct hw_endpoint hw_endpoints[USB_MAX_ENDPOINTS][2]; // SOF may be used by remote wakeup as RESUME, this indicate whether SOF is actually used by usbd static bool _sof_enable = false; -TU_ATTR_ALWAYS_INLINE static inline struct hw_endpoint *hw_endpoint_get_by_num(uint8_t num, tusb_dir_t dir) -{ +TU_ATTR_ALWAYS_INLINE static inline struct hw_endpoint* hw_endpoint_get_by_num(uint8_t num, tusb_dir_t dir) { return &hw_endpoints[num][dir]; } -static struct hw_endpoint *hw_endpoint_get_by_addr(uint8_t ep_addr) -{ +TU_ATTR_ALWAYS_INLINE static inline struct hw_endpoint* hw_endpoint_get_by_addr(uint8_t ep_addr) { uint8_t num = tu_edpt_number(ep_addr); tusb_dir_t dir = tu_edpt_dir(ep_addr); return hw_endpoint_get_by_num(num, dir); } -static void _hw_endpoint_alloc(struct hw_endpoint *ep, uint8_t transfer_type) -{ +static void _hw_endpoint_alloc(struct hw_endpoint* ep, uint8_t transfer_type) { // size must be multiple of 64 uint size = tu_div_ceil(ep->wMaxPacketSize, 64) * 64u; // double buffered Bulk endpoint - if ( transfer_type == TUSB_XFER_BULK ) - { + if (transfer_type == TUSB_XFER_BULK) { size *= 2u; } ep->hw_data_buf = next_buffer_ptr; next_buffer_ptr += size; - assert(((uintptr_t )next_buffer_ptr & 0b111111u) == 0); + assert(((uintptr_t) next_buffer_ptr & 0b111111u) == 0); uint dpram_offset = hw_data_offset(ep->hw_data_buf); hard_assert(hw_data_offset(next_buffer_ptr) <= USB_DPRAM_MAX); pico_info(" Allocated %d bytes at offset 0x%x (0x%p)\r\n", size, dpram_offset, ep->hw_data_buf); // Fill in endpoint control register with buffer offset - uint32_t const reg = EP_CTRL_ENABLE_BITS | ((uint)transfer_type << EP_CTRL_BUFFER_TYPE_LSB) | dpram_offset; + uint32_t const reg = EP_CTRL_ENABLE_BITS | ((uint) transfer_type << EP_CTRL_BUFFER_TYPE_LSB) | dpram_offset; *ep->endpoint_control = reg; } -static void _hw_endpoint_close(struct hw_endpoint *ep) -{ - // Clear hardware registers and then zero the struct - // Clears endpoint enable - *ep->endpoint_control = 0; - // Clears buffer available, etc - *ep->buffer_control = 0; - // Clear any endpoint state - memset(ep, 0, sizeof(struct hw_endpoint)); +static void _hw_endpoint_close(struct hw_endpoint* ep) { + // Clear hardware registers and then zero the struct + // Clears endpoint enable + *ep->endpoint_control = 0; + // Clears buffer available, etc + *ep->buffer_control = 0; + // Clear any endpoint state + memset(ep, 0, sizeof(struct hw_endpoint)); - // Reclaim buffer space if all endpoints are closed - bool reclaim_buffers = true; - for ( uint8_t i = 1; i < USB_MAX_ENDPOINTS; i++ ) - { - if (hw_endpoint_get_by_num(i, TUSB_DIR_OUT)->hw_data_buf != NULL || hw_endpoint_get_by_num(i, TUSB_DIR_IN)->hw_data_buf != NULL) - { - reclaim_buffers = false; - break; - } - } - if (reclaim_buffers) - { - next_buffer_ptr = &usb_dpram->epx_data[0]; + // Reclaim buffer space if all endpoints are closed + bool reclaim_buffers = true; + for (uint8_t i = 1; i < USB_MAX_ENDPOINTS; i++) { + if (hw_endpoint_get_by_num(i, TUSB_DIR_OUT)->hw_data_buf != NULL || + hw_endpoint_get_by_num(i, TUSB_DIR_IN)->hw_data_buf != NULL) { + reclaim_buffers = false; + break; } + } + if (reclaim_buffers) { + next_buffer_ptr = &usb_dpram->epx_data[0]; + } } -static void hw_endpoint_close(uint8_t ep_addr) -{ - struct hw_endpoint *ep = hw_endpoint_get_by_addr(ep_addr); - _hw_endpoint_close(ep); +static void hw_endpoint_close(uint8_t ep_addr) { + struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr); + _hw_endpoint_close(ep); } -static void hw_endpoint_init(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type) -{ - struct hw_endpoint *ep = hw_endpoint_get_by_addr(ep_addr); +static void hw_endpoint_init(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type) { + struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr); const uint8_t num = tu_edpt_number(ep_addr); const tusb_dir_t dir = tu_edpt_dir(ep_addr); @@ -143,35 +134,26 @@ static void hw_endpoint_init(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t t ep->transfer_type = transfer_type; // Every endpoint has a buffer control register in dpram - if ( dir == TUSB_DIR_IN ) - { + if (dir == TUSB_DIR_IN) { ep->buffer_control = &usb_dpram->ep_buf_ctrl[num].in; - } - else - { + } else { ep->buffer_control = &usb_dpram->ep_buf_ctrl[num].out; } // Clear existing buffer control state *ep->buffer_control = 0; - if ( num == 0 ) - { + if (num == 0) { // EP0 has no endpoint control register because the buffer offsets are fixed ep->endpoint_control = NULL; // Buffer offset is fixed (also double buffered) ep->hw_data_buf = (uint8_t*) &usb_dpram->ep0_buf_a[0]; - } - else - { + } else { // Set the endpoint control register (starts at EP1, hence num-1) - if ( dir == TUSB_DIR_IN ) - { + if (dir == TUSB_DIR_IN) { ep->endpoint_control = &usb_dpram->ep_ctrl[num - 1].in; - } - else - { + } else { ep->endpoint_control = &usb_dpram->ep_ctrl[num - 1].out; } @@ -180,76 +162,82 @@ static void hw_endpoint_init(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t t } } -static void hw_endpoint_xfer(uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) -{ - struct hw_endpoint *ep = hw_endpoint_get_by_addr(ep_addr); - hw_endpoint_xfer_start(ep, buffer, total_bytes); +static void hw_endpoint_xfer(uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) { + struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr); + hw_endpoint_xfer_start(ep, buffer, total_bytes); } -static void __tusb_irq_path_func(hw_handle_buff_status)(void) -{ - uint32_t remaining_buffers = usb_hw->buf_status; - pico_trace("buf_status = 0x%08lx\r\n", remaining_buffers); - uint bit = 1u; - for (uint8_t i = 0; remaining_buffers && i < USB_MAX_ENDPOINTS * 2; i++) - { - if (remaining_buffers & bit) - { - // clear this in advance - usb_hw_clear->buf_status = bit; +static void __tusb_irq_path_func(hw_handle_buff_status)(void) { + uint32_t remaining_buffers = usb_hw->buf_status; + pico_trace("buf_status = 0x%08lx\r\n", remaining_buffers); + uint bit = 1u; + for (uint8_t i = 0; remaining_buffers && i < USB_MAX_ENDPOINTS * 2; i++) { + if (remaining_buffers & bit) { + // clear this in advance + usb_hw_clear->buf_status = bit; - // IN transfer for even i, OUT transfer for odd i - struct hw_endpoint *ep = hw_endpoint_get_by_num(i >> 1u, (i & 1u) ? TUSB_DIR_OUT : TUSB_DIR_IN); + // IN transfer for even i, OUT transfer for odd i + struct hw_endpoint* ep = hw_endpoint_get_by_num(i >> 1u, (i & 1u) ? TUSB_DIR_OUT : TUSB_DIR_IN); - // Continue xfer - bool done = hw_endpoint_xfer_continue(ep); - if (done) - { - // Notify - dcd_event_xfer_complete(0, ep->ep_addr, ep->xferred_len, XFER_RESULT_SUCCESS, true); - hw_endpoint_reset_transfer(ep); - } - remaining_buffers &= ~bit; - } - bit <<= 1u; + // Continue xfer + bool done = hw_endpoint_xfer_continue(ep); + if (done) { + // Notify + dcd_event_xfer_complete(0, ep->ep_addr, ep->xferred_len, XFER_RESULT_SUCCESS, true); + hw_endpoint_reset_transfer(ep); + } + remaining_buffers &= ~bit; } + bit <<= 1u; + } } -TU_ATTR_ALWAYS_INLINE static inline void reset_ep0_pid(void) -{ - // If we have finished this transfer on EP0 set pid back to 1 for next - // setup transfer. Also clear a stall in case - uint8_t addrs[] = {0x0, 0x80}; - for (uint i = 0 ; i < TU_ARRAY_SIZE(addrs); i++) - { - struct hw_endpoint *ep = hw_endpoint_get_by_addr(addrs[i]); - ep->next_pid = 1u; +TU_ATTR_ALWAYS_INLINE static inline void reset_ep0(void) { + // If we have finished this transfer on EP0 set pid back to 1 for next + // setup transfer. Also clear a stall in case + for (uint8_t dir = 0; dir < 2; dir++) { + struct hw_endpoint* ep = hw_endpoint_get_by_num(0, dir); + if (ep->active) { + // Abort any pending transfer from a prior control transfer per USB specs + // Due to Errata RP2040-E2: ABORT flag is only applicable for B2 and later (unusable for B0, B1). + // Which means we are not guaranteed to safely abort pending transfer on B0 and B1. + uint32_t const abort_mask = (dir ? USB_EP_ABORT_EP0_IN_BITS : USB_EP_ABORT_EP0_OUT_BITS); + if (rp2040_chip_version() >= 2) { + usb_hw_set->abort = abort_mask; + while ((usb_hw->abort_done & abort_mask) != abort_mask) {} + } + + _hw_endpoint_buffer_control_set_value32(ep, USB_BUF_CTRL_DATA1_PID | USB_BUF_CTRL_SEL); + hw_endpoint_reset_transfer(ep); + + if (rp2040_chip_version() >= 2) { + usb_hw_clear->abort_done = abort_mask; + usb_hw_clear->abort = abort_mask; + } } + ep->next_pid = 1u; + } } -static void __tusb_irq_path_func(reset_non_control_endpoints)(void) -{ +static void __tusb_irq_path_func(reset_non_control_endpoints)(void) { // Disable all non-control - for ( uint8_t i = 0; i < USB_MAX_ENDPOINTS-1; i++ ) - { + for (uint8_t i = 0; i < USB_MAX_ENDPOINTS - 1; i++) { usb_dpram->ep_ctrl[i].in = 0; usb_dpram->ep_ctrl[i].out = 0; } // clear non-control hw endpoints - tu_memclr(hw_endpoints[1], sizeof(hw_endpoints) - 2*sizeof(hw_endpoint_t)); + tu_memclr(hw_endpoints[1], sizeof(hw_endpoints) - 2 * sizeof(hw_endpoint_t)); // reclaim buffer space next_buffer_ptr = &usb_dpram->epx_data[0]; } -static void __tusb_irq_path_func(dcd_rp2040_irq)(void) -{ +static void __tusb_irq_path_func(dcd_rp2040_irq)(void) { uint32_t const status = usb_hw->ints; uint32_t handled = 0; - if ( status & USB_INTF_DEV_SOF_BITS ) - { + if (status & USB_INTF_DEV_SOF_BITS) { bool keep_sof_alive = false; handled |= USB_INTF_DEV_SOF_BITS; @@ -258,20 +246,17 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) // Errata 15 workaround for Device Bulk-In endpoint e15_last_sof = time_us_32(); - for ( uint8_t i = 0; i < USB_MAX_ENDPOINTS; i++ ) - { - struct hw_endpoint * ep = hw_endpoint_get_by_num(i, TUSB_DIR_IN); + for (uint8_t i = 0; i < USB_MAX_ENDPOINTS; i++) { + struct hw_endpoint* ep = hw_endpoint_get_by_num(i, TUSB_DIR_IN); // Active Bulk IN endpoint requires SOF - if ( (ep->transfer_type == TUSB_XFER_BULK) && ep->active ) - { + if ((ep->transfer_type == TUSB_XFER_BULK) && ep->active) { keep_sof_alive = true; hw_endpoint_lock_update(ep, 1); // Deferred enable? - if ( ep->pending ) - { + if (ep->pending) { ep->pending = 0; hw_endpoint_start_next_buffer(ep); } @@ -282,26 +267,24 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) #endif // disable SOF interrupt if it is used for RESUME in remote wakeup - if ( !keep_sof_alive && !_sof_enable ) usb_hw_clear->inte = USB_INTS_DEV_SOF_BITS; + if (!keep_sof_alive && !_sof_enable) usb_hw_clear->inte = USB_INTS_DEV_SOF_BITS; dcd_event_sof(0, usb_hw->sof_rd & USB_SOF_RD_BITS, true); } // xfer events are handled before setup req. So if a transfer completes immediately // before closing the EP, the events will be delivered in same order. - if ( status & USB_INTS_BUFF_STATUS_BITS ) - { + if (status & USB_INTS_BUFF_STATUS_BITS) { handled |= USB_INTS_BUFF_STATUS_BITS; hw_handle_buff_status(); } - if ( status & USB_INTS_SETUP_REQ_BITS ) - { + if (status & USB_INTS_SETUP_REQ_BITS) { handled |= USB_INTS_SETUP_REQ_BITS; - uint8_t const * setup = remove_volatile_cast(uint8_t const*, &usb_dpram->setup_packet); + uint8_t const* setup = remove_volatile_cast(uint8_t const*, &usb_dpram->setup_packet); // reset pid to both 1 (data and ack) - reset_ep0_pid(); + reset_ep0(); // Pass setup packet to tiny usb dcd_event_setup_received(0, setup, true); @@ -329,8 +312,7 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) #endif // SE0 for 2.5 us or more (will last at least 10ms) - if ( status & USB_INTS_BUS_RESET_BITS ) - { + if (status & USB_INTS_BUS_RESET_BITS) { pico_trace("BUS RESET\r\n"); handled |= USB_INTS_BUS_RESET_BITS; @@ -342,7 +324,7 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) #if TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX // Only run enumeration workaround if pull up is enabled - if ( usb_hw->sie_ctrl & USB_SIE_CTRL_PULLUP_EN_BITS ) rp2040_usb_device_enumeration_fix(); + if (usb_hw->sie_ctrl & USB_SIE_CTRL_PULLUP_EN_BITS) rp2040_usb_device_enumeration_fix(); #endif } @@ -354,22 +336,19 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) * because without VBUS detection, it is impossible to tell the difference between * being disconnected and suspended. */ - if ( status & USB_INTS_DEV_SUSPEND_BITS ) - { + if (status & USB_INTS_DEV_SUSPEND_BITS) { handled |= USB_INTS_DEV_SUSPEND_BITS; dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); usb_hw_clear->sie_status = USB_SIE_STATUS_SUSPENDED_BITS; } - if ( status & USB_INTS_DEV_RESUME_FROM_HOST_BITS ) - { + if (status & USB_INTS_DEV_RESUME_FROM_HOST_BITS) { handled |= USB_INTS_DEV_RESUME_FROM_HOST_BITS; dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); usb_hw_clear->sie_status = USB_SIE_STATUS_RESUME_BITS; } - if ( status ^ handled ) - { + if (status ^ handled) { panic("Unhandled IRQ 0x%x\n", (uint) (status ^ handled)); } } @@ -390,10 +369,11 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) #define PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY 0xff #endif -void dcd_init (uint8_t rhport) -{ +void dcd_init(uint8_t rhport) { assert(rhport == 0); + TU_LOG(2, "Chip Version B%u\r\n", rp2040_chip_version()); + // Reset hardware to default state rp2040_usb_init(); @@ -405,7 +385,7 @@ void dcd_init (uint8_t rhport) irq_add_shared_handler(USBCTRL_IRQ, dcd_rp2040_irq, PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY); // Init control endpoints - tu_memclr(hw_endpoints[0], 2*sizeof(hw_endpoint_t)); + tu_memclr(hw_endpoints[0], 2 * sizeof(hw_endpoint_t)); hw_endpoint_init(0x0, 64, TUSB_XFER_CONTROL); hw_endpoint_init(0x80, 64, TUSB_XFER_CONTROL); @@ -420,27 +400,37 @@ void dcd_init (uint8_t rhport) // for the global interrupt enable... // Note: Force VBUS detect cause disconnection not detectable usb_hw->sie_ctrl = USB_SIE_CTRL_EP0_INT_1BUF_BITS; - usb_hw->inte = USB_INTS_BUFF_STATUS_BITS | USB_INTS_BUS_RESET_BITS | USB_INTS_SETUP_REQ_BITS | - USB_INTS_DEV_SUSPEND_BITS | USB_INTS_DEV_RESUME_FROM_HOST_BITS | - (FORCE_VBUS_DETECT ? 0 : USB_INTS_DEV_CONN_DIS_BITS); + usb_hw->inte = USB_INTS_BUFF_STATUS_BITS | USB_INTS_BUS_RESET_BITS | USB_INTS_SETUP_REQ_BITS | + USB_INTS_DEV_SUSPEND_BITS | USB_INTS_DEV_RESUME_FROM_HOST_BITS | + (FORCE_VBUS_DETECT ? 0 : USB_INTS_DEV_CONN_DIS_BITS); dcd_connect(rhport); } -void dcd_int_enable(__unused uint8_t rhport) -{ - assert(rhport == 0); - irq_set_enabled(USBCTRL_IRQ, true); +bool dcd_deinit(uint8_t rhport) { + (void) rhport; + + reset_non_control_endpoints(); + irq_remove_handler(USBCTRL_IRQ, dcd_rp2040_irq); + + // reset usb hardware into initial state + reset_block(RESETS_RESET_USBCTRL_BITS); + unreset_block_wait(RESETS_RESET_USBCTRL_BITS); + + return true; } -void dcd_int_disable(__unused uint8_t rhport) -{ - assert(rhport == 0); - irq_set_enabled(USBCTRL_IRQ, false); +void dcd_int_enable(__unused uint8_t rhport) { + assert(rhport == 0); + irq_set_enabled(USBCTRL_IRQ, true); } -void dcd_set_address (__unused uint8_t rhport, __unused uint8_t dev_addr) -{ +void dcd_int_disable(__unused uint8_t rhport) { + assert(rhport == 0); + irq_set_enabled(USBCTRL_IRQ, false); +} + +void dcd_set_address(__unused uint8_t rhport, __unused uint8_t dev_addr) { assert(rhport == 0); // Can't set device address in hardware until status xfer has complete @@ -448,8 +438,7 @@ void dcd_set_address (__unused uint8_t rhport, __unused uint8_t dev_addr) hw_endpoint_xfer(0x80, NULL, 0); } -void dcd_remote_wakeup(__unused uint8_t rhport) -{ +void dcd_remote_wakeup(__unused uint8_t rhport) { pico_info("dcd_remote_wakeup %d\n", rhport); assert(rhport == 0); @@ -460,100 +449,88 @@ void dcd_remote_wakeup(__unused uint8_t rhport) } // disconnect by disabling internal pull-up resistor on D+/D- -void dcd_disconnect(__unused uint8_t rhport) -{ +void dcd_disconnect(__unused uint8_t rhport) { (void) rhport; usb_hw_clear->sie_ctrl = USB_SIE_CTRL_PULLUP_EN_BITS; } // connect by enabling internal pull-up resistor on D+/D- -void dcd_connect(__unused uint8_t rhport) -{ +void dcd_connect(__unused uint8_t rhport) { (void) rhport; usb_hw_set->sie_ctrl = USB_SIE_CTRL_PULLUP_EN_BITS; } -void dcd_sof_enable(uint8_t rhport, bool en) -{ +void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; _sof_enable = en; - if (en) - { + if (en) { usb_hw_set->inte = USB_INTS_DEV_SOF_BITS; - }else - { + } +#if !TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX + else { // Don't clear immediately if the SOF workaround is in use. // The SOF handler will conditionally disable the interrupt. -#if !TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX usb_hw_clear->inte = USB_INTS_DEV_SOF_BITS; -#endif } +#endif } /*------------------------------------------------------------------*/ /* DCD Endpoint port *------------------------------------------------------------------*/ -void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) -{ +void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const* request) { (void) rhport; - if ( request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && - request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && - request->bRequest == TUSB_REQ_SET_ADDRESS ) - { + if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && + request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && + request->bRequest == TUSB_REQ_SET_ADDRESS) { usb_hw->dev_addr_ctrl = (uint8_t) request->wValue; } } -bool dcd_edpt_open (__unused uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) -{ - assert(rhport == 0); - hw_endpoint_init(desc_edpt->bEndpointAddress, tu_edpt_packet_size(desc_edpt), desc_edpt->bmAttributes.xfer); - return true; +bool dcd_edpt_open(__unused uint8_t rhport, tusb_desc_endpoint_t const* desc_edpt) { + assert(rhport == 0); + hw_endpoint_init(desc_edpt->bEndpointAddress, tu_edpt_packet_size(desc_edpt), desc_edpt->bmAttributes.xfer); + return true; } -void dcd_edpt_close_all (uint8_t rhport) -{ +void dcd_edpt_close_all(uint8_t rhport) { (void) rhport; // may need to use EP Abort reset_non_control_endpoints(); } -bool dcd_edpt_xfer(__unused uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) -{ - assert(rhport == 0); - hw_endpoint_xfer(ep_addr, buffer, total_bytes); - return true; +bool dcd_edpt_xfer(__unused uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) { + assert(rhport == 0); + hw_endpoint_xfer(ep_addr, buffer, total_bytes); + return true; } -void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) -{ +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; - if ( tu_edpt_number(ep_addr) == 0 ) - { + if (tu_edpt_number(ep_addr) == 0) { // A stall on EP0 has to be armed so it can be cleared on the next setup packet - usb_hw_set->ep_stall_arm = (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) ? USB_EP_STALL_ARM_EP0_IN_BITS : USB_EP_STALL_ARM_EP0_OUT_BITS; + usb_hw_set->ep_stall_arm = (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) ? USB_EP_STALL_ARM_EP0_IN_BITS + : USB_EP_STALL_ARM_EP0_OUT_BITS; } - struct hw_endpoint *ep = hw_endpoint_get_by_addr(ep_addr); + struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr); // stall and clear current pending buffer // may need to use EP_ABORT _hw_endpoint_buffer_control_set_value32(ep, USB_BUF_CTRL_STALL); } -void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) -{ +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; - if (tu_edpt_number(ep_addr)) - { - struct hw_endpoint *ep = hw_endpoint_get_by_addr(ep_addr); + if (tu_edpt_number(ep_addr)) { + struct hw_endpoint* ep = hw_endpoint_get_by_addr(ep_addr); // clear stall also reset toggle to DATA0, ready for next transfer ep->next_pid = 0; @@ -561,16 +538,13 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) } } -void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) -{ - (void) rhport; - - pico_trace("dcd_edpt_close %02x\r\n", ep_addr); - hw_endpoint_close(ep_addr); +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { + (void) rhport; + pico_trace("dcd_edpt_close %02x\r\n", ep_addr); + hw_endpoint_close(ep_addr); } -void __tusb_irq_path_func(dcd_int_handler)(uint8_t rhport) -{ +void __tusb_irq_path_func(dcd_int_handler)(uint8_t rhport) { (void) rhport; dcd_rp2040_irq(); } diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 21dc3f67d..222dbbbf0 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -27,7 +27,7 @@ #include "tusb_option.h" -#if CFG_TUH_ENABLED && (CFG_TUSB_MCU == OPT_MCU_RP2040) && !CFG_TUH_RPI_PIO_USB +#if CFG_TUH_ENABLED && (CFG_TUSB_MCU == OPT_MCU_RP2040) && !CFG_TUH_RPI_PIO_USB && !CFG_TUH_MAX3421 #include "pico.h" #include "rp2040_usb.h" @@ -113,7 +113,7 @@ static void __tusb_irq_path_func(_handle_buff_status_bit)(uint bit, struct hw_en static void __tusb_irq_path_func(hw_handle_buff_status)(void) { uint32_t remaining_buffers = usb_hw->buf_status; - pico_trace("buf_status 0x%08x\n", remaining_buffers); + pico_trace("buf_status 0x%08lx\n", remaining_buffers); // Check EPX first uint bit = 0b1; @@ -252,9 +252,9 @@ static void __tusb_irq_path_func(hcd_rp2040_irq)(void) } } -void __tusb_irq_path_func(hcd_int_handler)(uint8_t rhport) -{ +void __tusb_irq_path_func(hcd_int_handler)(uint8_t rhport, bool in_isr) { (void) rhport; + (void) in_isr; hcd_rp2040_irq(); } @@ -325,10 +325,8 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t ep->wMaxPacketSize = wMaxPacketSize; ep->transfer_type = transfer_type; - pico_trace("hw_endpoint_init dev %d ep %d %s xfer %d\n", ep->dev_addr, tu_edpt_number(ep->ep_addr), - ep_dir_string[tu_edpt_dir(ep->ep_addr)], ep->transfer_type); - pico_trace("dev %d ep %d %s setup buffer @ 0x%p\n", ep->dev_addr, tu_edpt_number(ep->ep_addr), - ep_dir_string[tu_edpt_dir(ep->ep_addr)], ep->hw_data_buf); + pico_trace("hw_endpoint_init dev %d ep %02X xfer %d\n", ep->dev_addr, ep->ep_addr, ep->transfer_type); + pico_trace("dev %d ep %02X setup buffer @ 0x%p\n", ep->dev_addr, ep->ep_addr, ep->hw_data_buf); uint dpram_offset = hw_data_offset(ep->hw_data_buf); // Bits 0-5 should be 0 assert(!(dpram_offset & 0b111111)); @@ -343,7 +341,7 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t ep_reg |= (uint32_t) ((bmInterval - 1) << EP_CTRL_HOST_INTERRUPT_INTERVAL_LSB); } *ep->endpoint_control = ep_reg; - pico_trace("endpoint control (0x%p) <- 0x%x\n", ep->endpoint_control, ep_reg); + pico_trace("endpoint control (0x%p) <- 0x%lx\n", ep->endpoint_control, ep_reg); ep->configured = true; if ( ep != &epx ) @@ -411,6 +409,16 @@ bool hcd_init(uint8_t rhport) return true; } +bool hcd_deinit(uint8_t rhport) { + (void) rhport; + + irq_remove_handler(USBCTRL_IRQ, hcd_rp2040_irq); + reset_block(RESETS_RESET_USBCTRL_BITS); + unreset_block_wait(RESETS_RESET_USBCTRL_BITS); + + return true; +} + void hcd_port_reset(uint8_t rhport) { (void) rhport; diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index a512dc34f..1ca711c77 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -35,26 +35,18 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTOTYPE //--------------------------------------------------------------------+ - -// Direction strings for debug -const char *ep_dir_string[] = { - "out", - "in", -}; - -static void _hw_endpoint_xfer_sync(struct hw_endpoint *ep); +static void _hw_endpoint_xfer_sync(struct hw_endpoint* ep); #if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX - static bool e15_is_bulkin_ep(struct hw_endpoint *ep); - static bool e15_is_critical_frame_period(struct hw_endpoint *ep); + static bool e15_is_bulkin_ep(struct hw_endpoint* ep); + static bool e15_is_critical_frame_period(struct hw_endpoint* ep); #else #define e15_is_bulkin_ep(x) (false) #define e15_is_critical_frame_period(x) (false) #endif // if usb hardware is in host mode -TU_ATTR_ALWAYS_INLINE static inline bool is_host_mode(void) -{ +TU_ATTR_ALWAYS_INLINE static inline bool is_host_mode(void) { return (usb_hw->main_ctrl & USB_MAIN_CTRL_HOST_NDEVICE_BITS) ? true : false; } @@ -62,8 +54,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool is_host_mode(void) // Implementation //--------------------------------------------------------------------+ -void rp2040_usb_init(void) -{ +void rp2040_usb_init(void) { // Reset usb controller reset_block(RESETS_RESET_USBCTRL_BITS); unreset_block_wait(RESETS_RESET_USBCTRL_BITS); @@ -88,46 +79,33 @@ void rp2040_usb_init(void) TU_LOG2_INT(sizeof(hw_endpoint_t)); } -void __tusb_irq_path_func(hw_endpoint_reset_transfer)(struct hw_endpoint *ep) -{ +void __tusb_irq_path_func(hw_endpoint_reset_transfer)(struct hw_endpoint* ep) { ep->active = false; ep->remaining_len = 0; ep->xferred_len = 0; ep->user_buf = 0; } -void __tusb_irq_path_func(_hw_endpoint_buffer_control_update32)(struct hw_endpoint *ep, uint32_t and_mask, uint32_t or_mask) -{ +void __tusb_irq_path_func(_hw_endpoint_buffer_control_update32)(struct hw_endpoint* ep, uint32_t and_mask, + uint32_t or_mask) { uint32_t value = 0; - if ( and_mask ) - { + if (and_mask) { value = *ep->buffer_control & and_mask; } - if ( or_mask ) - { + if (or_mask) { value |= or_mask; - if ( or_mask & USB_BUF_CTRL_AVAIL ) - { - if ( *ep->buffer_control & USB_BUF_CTRL_AVAIL ) - { - panic("ep %d %s was already available", tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)]); + if (or_mask & USB_BUF_CTRL_AVAIL) { + if (*ep->buffer_control & USB_BUF_CTRL_AVAIL) { + panic("ep %02X was already available", ep->ep_addr); } *ep->buffer_control = value & ~USB_BUF_CTRL_AVAIL; - // 12 cycle delay.. (should be good for 48*12Mhz = 576Mhz) + // 4.1.2.5.1 Con-current access: 12 cycles (should be good for 48*12Mhz = 576Mhz) after write to buffer control // Don't need delay in host mode as host is in charge -#if !CFG_TUH_ENABLED - __asm volatile ( - "b 1f\n" - "1: b 1f\n" - "1: b 1f\n" - "1: b 1f\n" - "1: b 1f\n" - "1: b 1f\n" - "1:\n" - : : : "memory"); -#endif + if ( !is_host_mode()) { + busy_wait_at_least_cycles(12); + } } } @@ -135,10 +113,9 @@ void __tusb_irq_path_func(_hw_endpoint_buffer_control_update32)(struct hw_endpoi } // prepare buffer, return buffer control -static uint32_t __tusb_irq_path_func(prepare_ep_buffer)(struct hw_endpoint *ep, uint8_t buf_id) -{ +static uint32_t __tusb_irq_path_func(prepare_ep_buffer)(struct hw_endpoint* ep, uint8_t buf_id) { uint16_t const buflen = tu_min16(ep->remaining_len, ep->wMaxPacketSize); - ep->remaining_len = (uint16_t)(ep->remaining_len - buflen); + ep->remaining_len = (uint16_t) (ep->remaining_len - buflen); uint32_t buf_ctrl = buflen | USB_BUF_CTRL_AVAIL; @@ -146,10 +123,9 @@ static uint32_t __tusb_irq_path_func(prepare_ep_buffer)(struct hw_endpoint *ep, buf_ctrl |= ep->next_pid ? USB_BUF_CTRL_DATA1_PID : USB_BUF_CTRL_DATA0_PID; ep->next_pid ^= 1u; - if ( !ep->rx ) - { + if (!ep->rx) { // Copy data from user buffer to hw buffer - memcpy(ep->hw_data_buf + buf_id*64, ep->user_buf, buflen); + memcpy(ep->hw_data_buf + buf_id * 64, ep->user_buf, buflen); ep->user_buf += buflen; // Mark as full @@ -159,8 +135,7 @@ static uint32_t __tusb_irq_path_func(prepare_ep_buffer)(struct hw_endpoint *ep, // Is this the last buffer? Only really matters for host mode. Will trigger // the trans complete irq but also stop it polling. We only really care about // trans complete for setup packets being sent - if (ep->remaining_len == 0) - { + if (ep->remaining_len == 0) { buf_ctrl |= USB_BUF_CTRL_LAST; } @@ -170,8 +145,7 @@ static uint32_t __tusb_irq_path_func(prepare_ep_buffer)(struct hw_endpoint *ep, } // Prepare buffer control register value -void __tusb_irq_path_func(hw_endpoint_start_next_buffer)(struct hw_endpoint *ep) -{ +void __tusb_irq_path_func(hw_endpoint_start_next_buffer)(struct hw_endpoint* ep) { uint32_t ep_ctrl = *ep->endpoint_control; // always compute and start with buffer 0 @@ -186,8 +160,7 @@ void __tusb_irq_path_func(hw_endpoint_start_next_buffer)(struct hw_endpoint *ep) bool const force_single = (!is_host && !tu_edpt_dir(ep->ep_addr)) || (is_host && tu_edpt_number(ep->ep_addr) != 0); - if(ep->remaining_len && !force_single) - { + if (ep->remaining_len && !force_single) { // Use buffer 1 (double buffered) if there is still data // TODO: Isochronous for buffer1 bit-field is different than CBI (control bulk, interrupt) @@ -196,8 +169,7 @@ void __tusb_irq_path_func(hw_endpoint_start_next_buffer)(struct hw_endpoint *ep) // Set endpoint control double buffered bit if needed ep_ctrl &= ~EP_CTRL_INTERRUPT_PER_BUFFER; ep_ctrl |= EP_CTRL_DOUBLE_BUFFERED_BITS | EP_CTRL_INTERRUPT_PER_DOUBLE_BUFFER; - }else - { + } else { // Single buffered since 1 is enough ep_ctrl &= ~(EP_CTRL_DOUBLE_BUFFERED_BITS | EP_CTRL_INTERRUPT_PER_DOUBLE_BUFFER); ep_ctrl |= EP_CTRL_INTERRUPT_PER_BUFFER; @@ -212,35 +184,28 @@ void __tusb_irq_path_func(hw_endpoint_start_next_buffer)(struct hw_endpoint *ep) _hw_endpoint_buffer_control_set_value32(ep, buf_ctrl); } -void hw_endpoint_xfer_start(struct hw_endpoint *ep, uint8_t *buffer, uint16_t total_len) -{ +void hw_endpoint_xfer_start(struct hw_endpoint* ep, uint8_t* buffer, uint16_t total_len) { hw_endpoint_lock_update(ep, 1); - if ( ep->active ) - { + if (ep->active) { // TODO: Is this acceptable for interrupt packets? - TU_LOG(1, "WARN: starting new transfer on already active ep %d %s\r\n", tu_edpt_number(ep->ep_addr), - ep_dir_string[tu_edpt_dir(ep->ep_addr)]); - + TU_LOG(1, "WARN: starting new transfer on already active ep %02X\r\n", ep->ep_addr); hw_endpoint_reset_transfer(ep); } // Fill in info now that we're kicking off the hw ep->remaining_len = total_len; - ep->xferred_len = 0; - ep->active = true; - ep->user_buf = buffer; + ep->xferred_len = 0; + ep->active = true; + ep->user_buf = buffer; - if ( e15_is_bulkin_ep(ep) ) - { + if (e15_is_bulkin_ep(ep)) { usb_hw_set->inte = USB_INTS_DEV_SOF_BITS; } - if ( e15_is_critical_frame_period(ep) ) - { + if (e15_is_critical_frame_period(ep)) { ep->pending = 1; - } else - { + } else { hw_endpoint_start_next_buffer(ep); } @@ -248,34 +213,30 @@ void hw_endpoint_xfer_start(struct hw_endpoint *ep, uint8_t *buffer, uint16_t to } // sync endpoint buffer and return transferred bytes -static uint16_t __tusb_irq_path_func(sync_ep_buffer)(struct hw_endpoint *ep, uint8_t buf_id) -{ +static uint16_t __tusb_irq_path_func(sync_ep_buffer)(struct hw_endpoint* ep, uint8_t buf_id) { uint32_t buf_ctrl = _hw_endpoint_buffer_control_get_value32(ep); - if (buf_id) buf_ctrl = buf_ctrl >> 16; + if (buf_id) buf_ctrl = buf_ctrl >> 16; uint16_t xferred_bytes = buf_ctrl & USB_BUF_CTRL_LEN_MASK; - if ( !ep->rx ) - { + if (!ep->rx) { // We are continuing a transfer here. If we are TX, we have successfully // sent some data can increase the length we have sent assert(!(buf_ctrl & USB_BUF_CTRL_FULL)); - ep->xferred_len = (uint16_t)(ep->xferred_len + xferred_bytes); - }else - { + ep->xferred_len = (uint16_t) (ep->xferred_len + xferred_bytes); + } else { // If we have received some data, so can increase the length // we have received AFTER we have copied it to the user buffer at the appropriate offset assert(buf_ctrl & USB_BUF_CTRL_FULL); - memcpy(ep->user_buf, ep->hw_data_buf + buf_id*64, xferred_bytes); - ep->xferred_len = (uint16_t)(ep->xferred_len + xferred_bytes); + memcpy(ep->user_buf, ep->hw_data_buf + buf_id * 64, xferred_bytes); + ep->xferred_len = (uint16_t) (ep->xferred_len + xferred_bytes); ep->user_buf += xferred_bytes; } // Short packet - if (xferred_bytes < ep->wMaxPacketSize) - { + if (xferred_bytes < ep->wMaxPacketSize) { pico_trace(" Short packet on buffer %d with %u bytes\r\n", buf_id, xferred_bytes); // Reduce total length as this is last packet ep->remaining_len = 0; @@ -284,8 +245,7 @@ static uint16_t __tusb_irq_path_func(sync_ep_buffer)(struct hw_endpoint *ep, uin return xferred_bytes; } -static void __tusb_irq_path_func(_hw_endpoint_xfer_sync) (struct hw_endpoint *ep) -{ +static void __tusb_irq_path_func(_hw_endpoint_xfer_sync)(struct hw_endpoint* ep) { // Update hw endpoint struct with info from hardware // after a buff status interrupt @@ -296,14 +256,11 @@ static void __tusb_irq_path_func(_hw_endpoint_xfer_sync) (struct hw_endpoint *ep uint16_t buf0_bytes = sync_ep_buffer(ep, 0); // sync buffer 1 if double buffered - if ( (*ep->endpoint_control) & EP_CTRL_DOUBLE_BUFFERED_BITS ) - { - if (buf0_bytes == ep->wMaxPacketSize) - { + if ((*ep->endpoint_control) & EP_CTRL_DOUBLE_BUFFERED_BITS) { + if (buf0_bytes == ep->wMaxPacketSize) { // sync buffer 1 if not short packet sync_ep_buffer(ep, 1); - }else - { + } else { // short packet on buffer 0 // TODO couldn't figure out how to handle this case which happen with net_lwip_webserver example // At this time (currently trigger per 2 buffer), the buffer1 is probably filled with data from @@ -335,14 +292,12 @@ static void __tusb_irq_path_func(_hw_endpoint_xfer_sync) (struct hw_endpoint *ep } // Returns true if transfer is complete -bool __tusb_irq_path_func(hw_endpoint_xfer_continue)(struct hw_endpoint *ep) -{ +bool __tusb_irq_path_func(hw_endpoint_xfer_continue)(struct hw_endpoint* ep) { hw_endpoint_lock_update(ep, 1); // Part way through a transfer - if (!ep->active) - { - panic("Can't continue xfer on inactive ep %d %s", tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)]); + if (!ep->active) { + panic("Can't continue xfer on inactive ep %02X", ep->ep_addr); } // Update EP struct from hardware state @@ -350,21 +305,15 @@ bool __tusb_irq_path_func(hw_endpoint_xfer_continue)(struct hw_endpoint *ep) // Now we have synced our state with the hardware. Is there more data to transfer? // If we are done then notify tinyusb - if (ep->remaining_len == 0) - { - pico_trace("Completed transfer of %d bytes on ep %d %s\r\n", - ep->xferred_len, tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)]); + if (ep->remaining_len == 0) { + pico_trace("Completed transfer of %d bytes on ep %02X\r\n", ep->xferred_len, ep->ep_addr); // Notify caller we are done so it can notify the tinyusb stack hw_endpoint_lock_update(ep, -1); return true; - } - else - { - if ( e15_is_critical_frame_period(ep) ) - { + } else { + if (e15_is_critical_frame_period(ep)) { ep->pending = 1; - } else - { + } else { hw_endpoint_start_next_buffer(ep); } } @@ -399,16 +348,14 @@ bool __tusb_irq_path_func(hw_endpoint_xfer_continue)(struct hw_endpoint *ep) volatile uint32_t e15_last_sof = 0; // check if Errata 15 is needed for this endpoint i.e device bulk-in -static bool __tusb_irq_path_func(e15_is_bulkin_ep) (struct hw_endpoint *ep) -{ +static bool __tusb_irq_path_func(e15_is_bulkin_ep)(struct hw_endpoint* ep) { return (!is_host_mode() && tu_edpt_dir(ep->ep_addr) == TUSB_DIR_IN && ep->transfer_type == TUSB_XFER_BULK); } // check if we need to apply Errata 15 workaround : i.e // Endpoint is BULK IN and is currently in critical frame period i.e 20% of last usb frame -static bool __tusb_irq_path_func(e15_is_critical_frame_period) (struct hw_endpoint *ep) -{ +static bool __tusb_irq_path_func(e15_is_critical_frame_period)(struct hw_endpoint* ep) { TU_VERIFY(e15_is_bulkin_ep(ep)); /* Avoid the last 200us (uframe 6.5-7) of a frame, up to the EOF2 point. @@ -419,11 +366,10 @@ static bool __tusb_irq_path_func(e15_is_critical_frame_period) (struct hw_endpoi if (delta < 800 || delta > 998) { return false; } - TU_LOG(3, "Avoiding sof %lu now %lu last %lu\r\n", (usb_hw->sof_rd + 1) & USB_SOF_RD_BITS, time_us_32(), e15_last_sof); + TU_LOG(3, "Avoiding sof %lu now %lu last %lu\r\n", (usb_hw->sof_rd + 1) & USB_SOF_RD_BITS, time_us_32(), + e15_last_sof); return true; } -#endif - - +#endif // TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX #endif diff --git a/src/portable/renesas/rusb2/dcd_rusb2.c b/src/portable/renesas/rusb2/dcd_rusb2.c index 3ec1b70b5..50400d1f5 100644 --- a/src/portable/renesas/rusb2/dcd_rusb2.c +++ b/src/portable/renesas/rusb2/dcd_rusb2.c @@ -57,29 +57,22 @@ //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ +enum { + PIPE_COUNT = 10, +}; -/* Start of definition of packed structs (used by the CCRX toolchain) */ -TU_ATTR_PACKED_BEGIN -TU_ATTR_BIT_FIELD_ORDER_BEGIN - -typedef struct TU_ATTR_PACKED -{ +typedef struct { void *buf; /* the start address of a transfer data buffer */ uint16_t length; /* the number of bytes in the buffer */ uint16_t remaining; /* the number of bytes remaining in the buffer */ - struct { - uint32_t ep : 8; /* an assigned endpoint address */ - uint32_t ff : 1; /* `buf` is TU_FUFO or POD */ - uint32_t : 0; - }; -} pipe_state_t; -TU_ATTR_PACKED_END // End of definition of packed structs (used by the CCRX toolchain) -TU_ATTR_BIT_FIELD_ORDER_END + uint8_t ep; /* an assigned endpoint address */ + uint8_t ff; /* `buf` is TU_FUFO or POD */ +} pipe_state_t; typedef struct { - pipe_state_t pipe[10]; + pipe_state_t pipe[PIPE_COUNT]; uint8_t ep[2][16]; /* a lookup table for a pipe index from an endpoint address */ } dcd_data_t; @@ -89,52 +82,44 @@ static dcd_data_t _dcd; // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ -// Transfer conditions specifiable for each pipe: + +// Transfer conditions specifiable for each pipe for most MCUs // - Pipe 0: Control transfer with 64-byte single buffer -// - Pipes 1 and 2: Bulk isochronous transfer continuous transfer mode with programmable buffer size up -// to 2 KB and optional double buffer -// - Pipes 3 to 5: Bulk transfer continuous transfer mode with programmable buffer size up to 2 KB and -// optional double buffer -// - Pipes 6 to 9: Interrupt transfer with 64-byte single buffer -enum { - PIPE_1ST_BULK = 3, - PIPE_1ST_INTERRUPT = 6, - PIPE_COUNT = 10, -}; +// - Pipes 1 and 2: Bulk or ISO +// - Pipes 3 to 5: Bulk +// - Pipes 6 to 9: Interrupt +// +// Note: for small mcu such as +// - RA2A1: only pipe 4-7 are available, and no support for ISO +static unsigned find_pipe(unsigned xfer_type) { + #if defined(BSP_MCU_GROUP_RA2A1) + const uint8_t pipe_idx_arr[4][2] = { + { 0, 0 }, // Control + { 0, 0 }, // Isochronous not supported + { 4, 5 }, // Bulk + { 6, 7 }, // Interrupt + }; + #else + const uint8_t pipe_idx_arr[4][2] = { + { 0, 0 }, // Control + { 1, 2 }, // Isochronous + { 1, 5 }, // Bulk + { 6, 9 }, // Interrupt + }; + #endif -static unsigned find_pipe(unsigned xfer) -{ - switch (xfer) { - case TUSB_XFER_ISOCHRONOUS: - for (int i = 1; i < PIPE_1ST_BULK; ++i) { - if (0 == _dcd.pipe[i].ep) return i; - } - break; + // find backward since only pipe 1, 2 support ISO + const uint8_t idx_first = pipe_idx_arr[xfer_type][0]; + const uint8_t idx_last = pipe_idx_arr[xfer_type][1]; - case TUSB_XFER_BULK: - for (int i = PIPE_1ST_BULK; i < PIPE_1ST_INTERRUPT; ++i) { - if (0 == _dcd.pipe[i].ep) return i; - } - for (int i = 1; i < PIPE_1ST_BULK; ++i) { - if (0 == _dcd.pipe[i].ep) return i; - } - break; - - case TUSB_XFER_INTERRUPT: - for (int i = PIPE_1ST_INTERRUPT; i < PIPE_COUNT; ++i) { - if (0 == _dcd.pipe[i].ep) return i; - } - break; - - default: - /* No support for control transfer */ - break; + for (int i = idx_last; i >= idx_first; i--) { + if (0 == _dcd.pipe[i].ep) return i; } + return 0; } -static volatile uint16_t* get_pipectr(rusb2_reg_t *rusb, unsigned num) -{ +static volatile uint16_t* get_pipectr(rusb2_reg_t *rusb, unsigned num) { if (num) { return (volatile uint16_t*)&(rusb->PIPE_CTR[num - 1]); } else { @@ -142,8 +127,7 @@ static volatile uint16_t* get_pipectr(rusb2_reg_t *rusb, unsigned num) } } -static volatile reg_pipetre_t* get_pipetre(rusb2_reg_t *rusb, unsigned num) -{ +static volatile reg_pipetre_t* get_pipetre(rusb2_reg_t *rusb, unsigned num) { volatile reg_pipetre_t* tre = NULL; if ((1 <= num) && (num <= 5)) { tre = (volatile reg_pipetre_t*)&(rusb->PIPE_TR[num - 1].E); @@ -151,8 +135,7 @@ static volatile reg_pipetre_t* get_pipetre(rusb2_reg_t *rusb, unsigned num) return tre; } -static volatile uint16_t* ep_addr_to_pipectr(uint8_t rhport, unsigned ep_addr) -{ +static volatile uint16_t* ep_addr_to_pipectr(uint8_t rhport, unsigned ep_addr) { rusb2_reg_t *rusb = RUSB2_REG(rhport); const unsigned epn = tu_edpt_number(ep_addr); @@ -165,19 +148,16 @@ static volatile uint16_t* ep_addr_to_pipectr(uint8_t rhport, unsigned ep_addr) } } -static uint16_t edpt0_max_packet_size(rusb2_reg_t* rusb) -{ +static uint16_t edpt0_max_packet_size(rusb2_reg_t* rusb) { return rusb->DCPMAXP_b.MXPS; } -static uint16_t edpt_max_packet_size(rusb2_reg_t *rusb, unsigned num) -{ +static uint16_t edpt_max_packet_size(rusb2_reg_t *rusb, unsigned num) { rusb->PIPESEL = num; return rusb->PIPEMAXP; } -static inline void pipe_wait_for_ready(rusb2_reg_t * rusb, unsigned num) -{ +static inline void pipe_wait_for_ready(rusb2_reg_t * rusb, unsigned num) { while ( rusb->D0FIFOSEL_b.CURPIPE != num ) {} while ( !rusb->D0FIFOCTR_b.FRDY ) {} } @@ -835,7 +815,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) } rusb->PIPECFG = cfg; - rusb->BRDYSTS = 0x1FFu ^ TU_BIT(num); + rusb->BRDYSTS = 0x3FFu ^ TU_BIT(num); rusb->BRDYENB |= TU_BIT(num); if (dir || (xfer != TUSB_XFER_BULK)) { @@ -935,6 +915,18 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) //--------------------------------------------------------------------+ // ISR //--------------------------------------------------------------------+ + +#if defined(__CCRX__) +TU_ATTR_ALWAYS_INLINE static inline unsigned __builtin_ctz(unsigned int value) { + unsigned int count = 0; + while ((value & 1) == 0) { + value >>= 1; + count++; + } + return count; +} +#endif + void dcd_int_handler(uint8_t rhport) { rusb2_reg_t* rusb = RUSB2_REG(rhport); @@ -1026,17 +1018,7 @@ void dcd_int_handler(uint8_t rhport) /* clear active bits (don't write 0 to already cleared bits according to the HW manual) */ rusb->BRDYSTS = ~s; while (s) { -#if defined(__CCRX__) - static const int Mod37BitPosition[] = { - -1, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4, - 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5, - 20, 8, 19, 18 - }; - - const unsigned num = Mod37BitPosition[(-s & s) % 37]; -#else const unsigned num = __builtin_ctz(s); -#endif process_pipe_brdy(rhport, num); s &= ~TU_BIT(num); } diff --git a/src/portable/renesas/rusb2/hcd_rusb2.c b/src/portable/renesas/rusb2/hcd_rusb2.c index 790cd6b32..f140da690 100644 --- a/src/portable/renesas/rusb2/hcd_rusb2.c +++ b/src/portable/renesas/rusb2/hcd_rusb2.c @@ -45,6 +45,9 @@ //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ +enum { + PIPE_COUNT = 10, +}; TU_ATTR_PACKED_BEGIN TU_ATTR_BIT_FIELD_ORDER_BEGIN @@ -75,7 +78,7 @@ TU_ATTR_BIT_FIELD_ORDER_END typedef struct { bool need_reset; /* The device has not been reset after connection. */ - pipe_state_t pipe[10]; + pipe_state_t pipe[PIPE_COUNT]; uint8_t ep[4][2][15]; /* a lookup table for a pipe index from an endpoint address */ uint8_t ctl_mps[5]; /* EP0 max packet size for each device */ } hcd_data_t; @@ -86,46 +89,30 @@ typedef struct static hcd_data_t _hcd; // TODO merged with DCD -// Transfer conditions specifiable for each pipe: +// Transfer conditions specifiable for each pipe for most MCUs // - Pipe 0: Control transfer with 64-byte single buffer -// - Pipes 1 and 2: Bulk isochronous transfer continuous transfer mode with programmable buffer size up -// to 2 KB and optional double buffer -// - Pipes 3 to 5: Bulk transfer continuous transfer mode with programmable buffer size up to 2 KB and -// optional double buffer -// - Pipes 6 to 9: Interrupt transfer with 64-byte single buffer -enum { - PIPE_1ST_BULK = 3, - PIPE_1ST_INTERRUPT = 6, - PIPE_COUNT = 10, -}; +// - Pipes 1 and 2: Bulk or ISO +// - Pipes 3 to 5: Bulk +// - Pipes 6 to 9: Interrupt +// +// Note: for small mcu such as +// - RA2A1: only pipe 4-7 are available, and no support for ISO +static unsigned find_pipe(unsigned xfer_type) { + const uint8_t pipe_idx_arr[4][2] = { + { 0, 0 }, // Control + { 1, 2 }, // Isochronous + { 1, 5 }, // Bulk + { 6, 9 }, // Interrupt + }; -static unsigned find_pipe(unsigned xfer) { - switch ( xfer ) { - case TUSB_XFER_ISOCHRONOUS: - for (int i = 1; i < PIPE_1ST_BULK; ++i) { - if ( 0 == _hcd.pipe[i].ep ) return i; - } - break; + // find backward since only pipe 1, 2 support ISO + const uint8_t idx_first = pipe_idx_arr[xfer_type][0]; + const uint8_t idx_last = pipe_idx_arr[xfer_type][1]; - case TUSB_XFER_BULK: - for (int i = PIPE_1ST_BULK; i < PIPE_1ST_INTERRUPT; ++i) { - if ( 0 == _hcd.pipe[i].ep ) return i; - } - for (int i = 1; i < PIPE_1ST_BULK; ++i) { - if ( 0 == _hcd.pipe[i].ep ) return i; - } - break; - - case TUSB_XFER_INTERRUPT: - for (int i = PIPE_1ST_INTERRUPT; i < PIPE_COUNT; ++i) { - if ( 0 == _hcd.pipe[i].ep ) return i; - } - break; - - default: - /* No support for control transfer */ - break; + for (int i = idx_last; i >= idx_first; i--) { + if (0 == _hcd.pipe[i].ep) return i; } + return 0; } @@ -718,7 +705,7 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const } rusb->PIPECFG = cfg; - rusb->BRDYSTS = 0x1FFu ^ TU_BIT(num); + rusb->BRDYSTS = 0x3FFu ^ TU_BIT(num); rusb->NRDYENB |= TU_BIT(num); rusb->BRDYENB |= TU_BIT(num); @@ -771,8 +758,20 @@ bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { //--------------------------------------------------------------------+ // ISR //--------------------------------------------------------------------+ -void hcd_int_handler(uint8_t rhport) -{ +#if defined(__CCRX__) +TU_ATTR_ALWAYS_INLINE static inline unsigned __builtin_ctz(unsigned int value) { + unsigned int count = 0; + while ((value & 1) == 0) { + value >>= 1; + count++; + } + return count; +} +#endif + +void hcd_int_handler(uint8_t rhport, bool in_isr) { + (void) in_isr; + rusb2_reg_t* rusb = RUSB2_REG(rhport); unsigned is0 = rusb->INTSTS0; unsigned is1 = rusb->INTSTS1; @@ -819,23 +818,12 @@ void hcd_int_handler(uint8_t rhport) } } -#if defined(__CCRX__) - static const int Mod37BitPosition[] = { - -1, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4, - 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5, - 20, 8, 19, 18}; -#endif - if (is0 & RUSB2_INTSTS0_NRDY_Msk) { const unsigned m = rusb->NRDYENB; unsigned s = rusb->NRDYSTS & m; rusb->NRDYSTS = ~s; while (s) { -#if defined(__CCRX__) - const unsigned num = Mod37BitPosition[(-s & s) % 37]; -#else const unsigned num = __builtin_ctz(s); -#endif process_pipe_nrdy(rhport, num); s &= ~TU_BIT(num); } @@ -846,11 +834,7 @@ void hcd_int_handler(uint8_t rhport) /* clear active bits (don't write 0 to already cleared bits according to the HW manual) */ rusb->BRDYSTS = ~s; while (s) { -#if defined(__CCRX__) - const unsigned num = Mod37BitPosition[(-s & s) % 37]; -#else const unsigned num = __builtin_ctz(s); -#endif process_pipe_brdy(rhport, num); s &= ~TU_BIT(num); } diff --git a/src/portable/sony/cxd56/dcd_cxd56.c b/src/portable/sony/cxd56/dcd_cxd56.c index 6677891a5..41814370e 100644 --- a/src/portable/sony/cxd56/dcd_cxd56.c +++ b/src/portable/sony/cxd56/dcd_cxd56.c @@ -102,17 +102,25 @@ static int _dcd_bind(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_ usbdev = dev; usbdcd_driver.ep[0] = dev->ep0; + #ifdef EP_ALLOCREQ + // SDK v2 usbdcd_driver.req[0] = EP_ALLOCREQ(usbdcd_driver.ep[0]); - if (usbdcd_driver.req[0] != NULL) - { + if (usbdcd_driver.req[0] != NULL) { usbdcd_driver.req[0]->len = 64; usbdcd_driver.req[0]->buf = EP_ALLOCBUFFER(usbdcd_driver.ep[0], 64); - if (!usbdcd_driver.req[0]->buf) - { + if (!usbdcd_driver.req[0]->buf) { EP_FREEREQ(usbdcd_driver.ep[0], usbdcd_driver.req[0]); usbdcd_driver.req[0] = NULL; + return ENOMEM; } } + #else + // SDK v3 + usbdcd_driver.req[0] = usbdev_allocreq(usbdcd_driver.ep[0], 64); + if (usbdcd_driver.req[0] == NULL) { + return ENOMEM; + } + #endif usbdcd_driver.req[0]->callback = usbdcd_ep0incomplete; @@ -295,13 +303,19 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoint_desc) } usbdcd_driver.req[epnum] = NULL; + + #ifdef EP_ALLOCREQ + // sdk v2 usbdcd_driver.req[epnum] = EP_ALLOCREQ(usbdcd_driver.ep[epnum]); - if (usbdcd_driver.req[epnum] != NULL) - { + if (usbdcd_driver.req[epnum] != NULL) { usbdcd_driver.req[epnum]->len = ep_mps; } - else - { + #else + // sdk v3 + usbdcd_driver.req[epnum] = usbdev_allocreq(usbdcd_driver.ep[epnum], ep_mps); + #endif + + if(usbdcd_driver.req[epnum] == NULL) { return false; } diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 14cabaf8d..a26c66892 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -107,9 +107,9 @@ #include "device/dcd.h" #ifdef TUP_USBIP_FSDEV_STM32 - // Undefine to reduce the dependence on HAL - #undef USE_HAL_DRIVER - #include "portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h" +// Undefine to reduce the dependence on HAL +#undef USE_HAL_DRIVER +#include "portable/st/stm32_fsdev/dcd_stm32_fsdev.h" #endif /***************************************************** @@ -119,17 +119,17 @@ // HW supports max of 8 bidirectional endpoints, but this can be reduced to save RAM // (8u here would mean 8 IN and 8 OUT) #ifndef MAX_EP_COUNT -# define MAX_EP_COUNT 8U +#define MAX_EP_COUNT 8U #endif // If sharing with CAN, one can set this to be non-zero to give CAN space where it wants it // Both of these MUST be a multiple of 2, and are in byte units. #ifndef DCD_STM32_BTABLE_BASE -# define DCD_STM32_BTABLE_BASE 0U +#define DCD_STM32_BTABLE_BASE 0U #endif -#ifndef DCD_STM32_BTABLE_LENGTH -# define DCD_STM32_BTABLE_LENGTH (PMA_LENGTH - DCD_STM32_BTABLE_BASE) +#ifndef DCD_STM32_BTABLE_SIZE +#define DCD_STM32_BTABLE_SIZE (FSDEV_PMA_SIZE - DCD_STM32_BTABLE_BASE) #endif /*************************************************** @@ -137,7 +137,7 @@ */ TU_VERIFY_STATIC((MAX_EP_COUNT) <= STFSDEV_EP_COUNT, "Only 8 endpoints supported on the hardware"); -TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) + (DCD_STM32_BTABLE_LENGTH))<=(PMA_LENGTH), "BTABLE does not fit in PMA RAM"); +TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) + (DCD_STM32_BTABLE_SIZE)) <= (FSDEV_PMA_SIZE), "BTABLE does not fit in PMA RAM"); TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) % 8) == 0, "BTABLE base must be aligned to 8 bytes"); //--------------------------------------------------------------------+ @@ -145,21 +145,18 @@ TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) % 8) == 0, "BTABLE base must be aligne //--------------------------------------------------------------------+ // One of these for every EP IN & OUT, uses a bit of RAM.... -typedef struct -{ - uint8_t * buffer; - tu_fifo_t * ff; +typedef struct { + uint8_t *buffer; + tu_fifo_t *ff; uint16_t total_len; uint16_t queued_len; - uint16_t pma_ptr; uint16_t max_packet_size; - uint16_t pma_alloc_size; - uint8_t ep_idx; // index for USB_EPnR register + uint8_t ep_idx; // index for USB_EPnR register + bool iso_in_sending; // Workaround for ISO IN EP doesn't have interrupt mask } xfer_ctl_t; // EP allocator -typedef struct -{ +typedef struct { uint8_t ep_num; uint8_t ep_type; bool allocated[2]; @@ -179,28 +176,25 @@ static uint8_t remoteWakeCountdown; // When wake is requested // into the stack. static void dcd_handle_bus_reset(void); -static void dcd_transmit_packet(xfer_ctl_t * xfer, uint16_t ep_ix); +static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix); +static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr); static void dcd_ep_ctr_handler(void); // PMA allocation/access -static uint8_t open_ep_count; static uint16_t ep_buf_ptr; ///< Points to first free memory location -static void dcd_pma_alloc_reset(void); -static uint16_t dcd_pma_alloc(uint8_t ep_addr, uint16_t length); -static void dcd_pma_free(uint8_t ep_addr); -static void dcd_ep_free(uint8_t ep_addr); +static uint32_t dcd_pma_alloc(uint16_t length, bool dbuf); static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type); static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t wNBytes); static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t wNBytes); -static bool dcd_write_packet_memory_ff(tu_fifo_t * ff, uint16_t dst, uint16_t wNBytes); -static bool dcd_read_packet_memory_ff(tu_fifo_t * ff, uint16_t src, uint16_t wNBytes); +static bool dcd_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNBytes); +static bool dcd_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBytes); //--------------------------------------------------------------------+ // Inline helper //--------------------------------------------------------------------+ -TU_ATTR_ALWAYS_INLINE static inline xfer_ctl_t* xfer_ctl_ptr(uint32_t ep_addr) +TU_ATTR_ALWAYS_INLINE static inline xfer_ctl_t *xfer_ctl_ptr(uint32_t ep_addr) { uint8_t epnum = tu_edpt_number(ep_addr); uint8_t dir = tu_edpt_dir(ep_addr); @@ -214,7 +208,7 @@ TU_ATTR_ALWAYS_INLINE static inline xfer_ctl_t* xfer_ctl_ptr(uint32_t ep_addr) // Controller API //--------------------------------------------------------------------+ -void dcd_init (uint8_t rhport) +void dcd_init(uint8_t rhport) { /* Clocks should already be enabled */ /* Use __HAL_RCC_USB_CLK_ENABLE(); to enable the clocks before calling this function */ @@ -222,43 +216,41 @@ void dcd_init (uint8_t rhport) /* The RM mentions to use a special ordering of PDWN and FRES, but this isn't done in HAL. * Here, the RM is followed. */ - for(uint32_t i = 0; i<200; i++) // should be a few us - { + for (uint32_t i = 0; i < 200; i++) { // should be a few us asm("NOP"); } // Perform USB peripheral reset USB->CNTR = USB_CNTR_FRES | USB_CNTR_PDWN; - for(uint32_t i = 0; i<200; i++) // should be a few us - { + for (uint32_t i = 0; i < 200; i++) { // should be a few us asm("NOP"); } USB->CNTR &= ~USB_CNTR_PDWN; // Wait startup time, for F042 and F070, this is <= 1 us. - for(uint32_t i = 0; i<200; i++) // should be a few us - { + for (uint32_t i = 0; i < 200; i++) { // should be a few us asm("NOP"); } USB->CNTR = 0; // Enable USB -#ifndef STM32G0 // BTABLE register does not exist any more on STM32G0, it is fixed to USB SRAM base address +#if !defined(STM32G0) && !defined(STM32H5) // BTABLE register does not exist any more on STM32G0, it is fixed to USB SRAM base address USB->BTABLE = DCD_STM32_BTABLE_BASE; #endif USB->ISTR = 0; // Clear pending interrupts // Reset endpoints to disabled - for(uint32_t i=0; iCNTR |= USB_CNTR_RESETM | USB_CNTR_ESOFM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; dcd_handle_bus_reset(); // Enable pull-up if supported - if ( dcd_connect ) dcd_connect(rhport); + if (dcd_connect) { + dcd_connect(rhport); + } } // Define only on MCU with internal pull-up. BSP can define on MCU without internal PU. @@ -267,14 +259,14 @@ void dcd_init (uint8_t rhport) // Disable internal D+ PU void dcd_disconnect(uint8_t rhport) { - (void) rhport; + (void)rhport; USB->BCDR &= ~(USB_BCDR_DPPU); } // Enable internal D+ PU void dcd_connect(uint8_t rhport) { - (void) rhport; + (void)rhport; USB->BCDR |= USB_BCDR_DPPU; } @@ -282,60 +274,54 @@ void dcd_connect(uint8_t rhport) // Disable internal D+ PU void dcd_disconnect(uint8_t rhport) { - (void) rhport; + (void)rhport; SYSCFG->PMC &= ~(SYSCFG_PMC_USB_PU); } // Enable internal D+ PU void dcd_connect(uint8_t rhport) { - (void) rhport; + (void)rhport; SYSCFG->PMC |= SYSCFG_PMC_USB_PU; } #endif void dcd_sof_enable(uint8_t rhport, bool en) { - (void) rhport; - (void) en; + (void)rhport; + (void)en; - if (en) - { + if (en) { USB->CNTR |= USB_CNTR_SOFM; - } - else - { + } else { USB->CNTR &= ~USB_CNTR_SOFM; } } // Enable device interrupt -void dcd_int_enable (uint8_t rhport) +void dcd_int_enable(uint8_t rhport) { (void)rhport; // Member here forces write to RAM before allowing ISR to execute __DSB(); __ISB(); -#if CFG_TUSB_MCU == OPT_MCU_STM32F0 || CFG_TUSB_MCU == OPT_MCU_STM32L0 || \ - CFG_TUSB_MCU == OPT_MCU_STM32L4 +#if CFG_TUSB_MCU == OPT_MCU_STM32F0 || CFG_TUSB_MCU == OPT_MCU_STM32L0 || CFG_TUSB_MCU == OPT_MCU_STM32L4 NVIC_EnableIRQ(USB_IRQn); #elif CFG_TUSB_MCU == OPT_MCU_STM32L1 NVIC_EnableIRQ(USB_LP_IRQn); #elif CFG_TUSB_MCU == OPT_MCU_STM32F3 - // Some STM32F302/F303 devices allow to remap the USB interrupt vectors from - // shared USB/CAN IRQs to separate CAN and USB IRQs. - // This dynamically checks if this remap is active to enable the right IRQs. - #ifdef SYSCFG_CFGR1_USB_IT_RMP - if (SYSCFG->CFGR1 & SYSCFG_CFGR1_USB_IT_RMP) - { +// Some STM32F302/F303 devices allow to remap the USB interrupt vectors from +// shared USB/CAN IRQs to separate CAN and USB IRQs. +// This dynamically checks if this remap is active to enable the right IRQs. +#ifdef SYSCFG_CFGR1_USB_IT_RMP + if (SYSCFG->CFGR1 & SYSCFG_CFGR1_USB_IT_RMP) { NVIC_EnableIRQ(USB_HP_IRQn); NVIC_EnableIRQ(USB_LP_IRQn); NVIC_EnableIRQ(USBWakeUp_RMP_IRQn); - } - else - #endif + } else +#endif { NVIC_EnableIRQ(USB_HP_CAN_TX_IRQn); NVIC_EnableIRQ(USB_LP_CAN_RX0_IRQn); @@ -352,11 +338,14 @@ void dcd_int_enable (uint8_t rhport) NVIC_EnableIRQ(USBWakeUp_IRQn); #elif CFG_TUSB_MCU == OPT_MCU_STM32G0 - #ifdef STM32G0B0xx - NVIC_EnableIRQ(USB_IRQn); - #else - NVIC_EnableIRQ(USB_UCPD1_2_IRQn); - #endif +#ifdef STM32G0B0xx + NVIC_EnableIRQ(USB_IRQn); +#else + NVIC_EnableIRQ(USB_UCPD1_2_IRQn); +#endif + +#elif CFG_TUSB_MCU == OPT_MCU_STM32H5 + NVIC_EnableIRQ(USB_DRD_FS_IRQn); #elif CFG_TUSB_MCU == OPT_MCU_STM32WB NVIC_EnableIRQ(USB_HP_IRQn); @@ -366,7 +355,7 @@ void dcd_int_enable (uint8_t rhport) NVIC_EnableIRQ(USB_FS_IRQn); #else - #error Unknown arch in USB driver +#error Unknown arch in USB driver #endif } @@ -375,24 +364,21 @@ void dcd_int_disable(uint8_t rhport) { (void)rhport; -#if CFG_TUSB_MCU == OPT_MCU_STM32F0 || CFG_TUSB_MCU == OPT_MCU_STM32L0 || \ - CFG_TUSB_MCU == OPT_MCU_STM32L4 +#if CFG_TUSB_MCU == OPT_MCU_STM32F0 || CFG_TUSB_MCU == OPT_MCU_STM32L0 || CFG_TUSB_MCU == OPT_MCU_STM32L4 NVIC_DisableIRQ(USB_IRQn); #elif CFG_TUSB_MCU == OPT_MCU_STM32L1 NVIC_DisableIRQ(USB_LP_IRQn); #elif CFG_TUSB_MCU == OPT_MCU_STM32F3 - // Some STM32F302/F303 devices allow to remap the USB interrupt vectors from - // shared USB/CAN IRQs to separate CAN and USB IRQs. - // This dynamically checks if this remap is active to disable the right IRQs. - #ifdef SYSCFG_CFGR1_USB_IT_RMP - if (SYSCFG->CFGR1 & SYSCFG_CFGR1_USB_IT_RMP) - { +// Some STM32F302/F303 devices allow to remap the USB interrupt vectors from +// shared USB/CAN IRQs to separate CAN and USB IRQs. +// This dynamically checks if this remap is active to disable the right IRQs. +#ifdef SYSCFG_CFGR1_USB_IT_RMP + if (SYSCFG->CFGR1 & SYSCFG_CFGR1_USB_IT_RMP) { NVIC_DisableIRQ(USB_HP_IRQn); NVIC_DisableIRQ(USB_LP_IRQn); NVIC_DisableIRQ(USBWakeUp_RMP_IRQn); - } - else - #endif + } else +#endif { NVIC_DisableIRQ(USB_HP_CAN_TX_IRQn); NVIC_DisableIRQ(USB_LP_CAN_RX0_IRQn); @@ -409,11 +395,14 @@ void dcd_int_disable(uint8_t rhport) NVIC_DisableIRQ(USBWakeUp_IRQn); #elif CFG_TUSB_MCU == OPT_MCU_STM32G0 - #ifdef STM32G0B0xx - NVIC_DisableIRQ(USB_IRQn); - #else - NVIC_DisableIRQ(USB_UCPD1_2_IRQn); - #endif +#ifdef STM32G0B0xx + NVIC_DisableIRQ(USB_IRQn); +#else + NVIC_DisableIRQ(USB_UCPD1_2_IRQn); +#endif + +#elif CFG_TUSB_MCU == OPT_MCU_STM32H5 + NVIC_DisableIRQ(USB_DRD_FS_IRQn); #elif CFG_TUSB_MCU == OPT_MCU_STM32WB NVIC_DisableIRQ(USB_HP_IRQn); @@ -423,7 +412,7 @@ void dcd_int_disable(uint8_t rhport) NVIC_DisableIRQ(USB_FS_IRQn); #else - #error Unknown arch in USB driver +#error Unknown arch in USB driver #endif // CMSIS has a membar after disabling interrupts @@ -432,8 +421,8 @@ void dcd_int_disable(uint8_t rhport) // Receive Set Address request, mcu port must also include status IN response void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { - (void) rhport; - (void) dev_addr; + (void)rhport; + (void)dev_addr; // Respond with status dcd_edpt_xfer(rhport, TUSB_DIR_IN_MASK | 0x00, NULL, 0); @@ -444,44 +433,35 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) void dcd_remote_wakeup(uint8_t rhport) { - (void) rhport; + (void)rhport; USB->CNTR |= USB_CNTR_RESUME; remoteWakeCountdown = 4u; // required to be 1 to 15 ms, ESOF should trigger every 1ms. } -static const tusb_desc_endpoint_t ep0OUT_desc = -{ - .bLength = sizeof(tusb_desc_endpoint_t), - .bDescriptorType = TUSB_DESC_ENDPOINT, - - .bEndpointAddress = 0x00, - .bmAttributes = { .xfer = TUSB_XFER_CONTROL }, - .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE, - .bInterval = 0 +static const tusb_desc_endpoint_t ep0OUT_desc = { + .bLength = sizeof(tusb_desc_endpoint_t), + .bDescriptorType = TUSB_DESC_ENDPOINT, + .bEndpointAddress = 0x00, + .bmAttributes = {.xfer = TUSB_XFER_CONTROL}, + .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE, + .bInterval = 0 }; -static const tusb_desc_endpoint_t ep0IN_desc = -{ - .bLength = sizeof(tusb_desc_endpoint_t), - .bDescriptorType = TUSB_DESC_ENDPOINT, - - .bEndpointAddress = 0x80, - .bmAttributes = { .xfer = TUSB_XFER_CONTROL }, - .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE, - .bInterval = 0 +static const tusb_desc_endpoint_t ep0IN_desc = { + .bLength = sizeof(tusb_desc_endpoint_t), + .bDescriptorType = TUSB_DESC_ENDPOINT, + .bEndpointAddress = 0x80, + .bmAttributes = {.xfer = TUSB_XFER_CONTROL}, + .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE, + .bInterval = 0 }; static void dcd_handle_bus_reset(void) { - //__IO uint16_t * const epreg = &(EPREG(0)); USB->DADDR = 0u; // disable USB peripheral by clearing the EF flag - for(uint32_t i=0; iDADDR = USB_DADDR_EF; // Set enable flag, and leaving the device address as zero. } @@ -507,30 +489,63 @@ static void dcd_ep_ctr_tx_handler(uint32_t wIstr) // Verify the CTR_TX bit is set. This was in the ST Micro code, // but I'm not sure it's actually necessary? - if((wEPRegVal & USB_EP_CTR_TX) == 0U) - { + if ((wEPRegVal & USB_EP_CTR_TX) == 0U) { return; } /* clear int flag */ pcd_clear_tx_ep_ctr(USB, EPindex); - xfer_ctl_t * xfer = xfer_ctl_ptr(ep_addr); - if((xfer->total_len != xfer->queued_len)) /* TX not complete */ - { - dcd_transmit_packet(xfer, EPindex); + xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); + + if ((wEPRegVal & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) { + // Ignore spurious interrupts that we don't schedule + // host can send IN token while there is no data to send, since ISO does not have NAK + // this will result to zero length packet --> trigger interrupt (which cannot be masked) + if (!xfer->iso_in_sending) { + return; + } + xfer->iso_in_sending = false; + + if (wEPRegVal & USB_EP_DTOG_TX) { + pcd_set_ep_tx_dbuf0_cnt(USB, EPindex, 0); + } else { + pcd_set_ep_tx_dbuf1_cnt(USB, EPindex, 0); + } } - else /* TX Complete */ - { + + if ((xfer->total_len != xfer->queued_len)) { + dcd_transmit_packet(xfer, EPindex); + } else { dcd_event_xfer_complete(0, ep_addr, xfer->total_len, XFER_RESULT_SUCCESS, true); } } // Handle CTR interrupt for the RX/OUT direction -// // Upon call, (wIstr & USB_ISTR_DIR) == 0U static void dcd_ep_ctr_rx_handler(uint32_t wIstr) { +#ifdef FSDEV_BUS_32BIT + /* https://www.st.com/resource/en/errata_sheet/es0561-stm32h503cbebkbrb-device-errata-stmicroelectronics.pdf + * From STM32H503 errata 2.15.1: Buffer description table update completes after CTR interrupt triggers + * Description: + * - During OUT transfers, the correct transfer interrupt (CTR) is triggered a little before the last USB SRAM accesses + * have completed. If the software responds quickly to the interrupt, the full buffer contents may not be correct. + * Workaround: + * - Software should ensure that a small delay is included before accessing the SRAM contents. This delay + * should be 800 ns in Full Speed mode and 6.4 Îŧs in Low Speed mode + * - Since H5 can run up to 250Mhz -> 1 cycle = 4ns. Per errata, we need to wait 200 cycles. Though executing code + * also takes time, so we'll wait 60 cycles (count = 20). + * - Since Low Speed mode is not supported/popular, we will ignore it for now. + * + * Note: this errata also seems to apply to G0, U5, H5 etc. + */ + volatile uint32_t cycle_count = 20; // defined as PCD_RX_PMA_CNT in stm32 hal_driver + while (cycle_count > 0U) { + cycle_count--; // each count take 3 cycles (1 for sub, jump, and compare) + } +#endif + uint32_t EPindex = wIstr & USB_ISTR_EP_ID; uint32_t wEPRegVal = pcd_get_endpoint(USB, EPindex); uint8_t ep_addr = wEPRegVal & USB_EPADDR_FIELD; @@ -539,96 +554,83 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) // Verify the CTR_RX bit is set. This was in the ST Micro code, // but I'm not sure it's actually necessary? - if((wEPRegVal & USB_EP_CTR_RX) == 0U) - { + if ((wEPRegVal & USB_EP_CTR_RX) == 0U) { return; } - if((ep_addr == 0U) && ((wEPRegVal & USB_EP_SETUP) != 0U)) /* Setup packet */ - { + if ((ep_addr == 0U) && ((wEPRegVal & USB_EP_SETUP) != 0U)) { + /* Setup packet */ uint32_t count = pcd_get_ep_rx_cnt(USB, EPindex); - /* Get SETUP Packet*/ - if(count == 8) // Setup packet should always be 8 bytes. If not, ignore it, and try again. - { + // Setup packet should always be 8 bytes. If not, ignore it, and try again. + if (count == 8) { // Must reset EP to NAK (in case it had been stalling) (though, maybe too late here) - pcd_set_ep_rx_status(USB,0u,USB_EP_RX_NAK); - pcd_set_ep_tx_status(USB,0u,USB_EP_TX_NAK); -#ifdef PMA_32BIT_ACCESS - dcd_event_setup_received(0, (uint8_t*)(USB_PMAADDR + pcd_get_ep_rx_address(USB, EPindex)), true); + pcd_set_ep_rx_status(USB, 0u, USB_EP_RX_NAK); + pcd_set_ep_tx_status(USB, 0u, USB_EP_TX_NAK); +#ifdef FSDEV_BUS_32BIT + dcd_event_setup_received(0, (uint8_t *)(USB_PMAADDR + pcd_get_ep_rx_address(USB, EPindex)), true); #else // The setup_received function uses memcpy, so this must first copy the setup data into // user memory, to allow for the 32-bit access that memcpy performs. uint8_t userMemBuf[8]; - dcd_read_packet_memory(userMemBuf, pcd_get_ep_rx_address(USB,EPindex), 8); - dcd_event_setup_received(0, (uint8_t*)userMemBuf, true); + dcd_read_packet_memory(userMemBuf, pcd_get_ep_rx_address(USB, EPindex), 8); + dcd_event_setup_received(0, (uint8_t *)userMemBuf, true); #endif } - } - else - { + } else { + // Clear RX CTR interrupt flag + if (ep_addr != 0u) { + pcd_clear_rx_ep_ctr(USB, EPindex); + } + uint32_t count; + uint16_t addr; /* Read from correct register when ISOCHRONOUS (double buffered) */ - if ( (wEPRegVal & USB_EP_DTOG_RX) && ( (wEPRegVal & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) ) { - count = pcd_get_ep_tx_cnt(USB, EPindex); + if ((wEPRegVal & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) { + if (wEPRegVal & USB_EP_DTOG_RX) { + count = pcd_get_ep_dbuf0_cnt(USB, EPindex); + addr = pcd_get_ep_dbuf0_address(USB, EPindex); + } else { + count = pcd_get_ep_dbuf1_cnt(USB, EPindex); + addr = pcd_get_ep_dbuf1_address(USB, EPindex); + } } else { count = pcd_get_ep_rx_cnt(USB, EPindex); + addr = pcd_get_ep_rx_address(USB, EPindex); } TU_ASSERT(count <= xfer->max_packet_size, /**/); - // Clear RX CTR interrupt flag - if(ep_addr != 0u) - { - pcd_clear_rx_ep_ctr(USB, EPindex); - } - - if (count != 0U) - { - uint16_t addr = pcd_get_ep_rx_address(USB, EPindex); - - if (xfer->ff) - { + if (count != 0U) { + if (xfer->ff) { dcd_read_packet_memory_ff(xfer->ff, addr, count); - } - else - { + } else { dcd_read_packet_memory(&(xfer->buffer[xfer->queued_len]), addr, count); } xfer->queued_len = (uint16_t)(xfer->queued_len + count); } - if ((count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) - { - /* RX COMPLETE */ + if ((count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) { + // all bytes received or short packet dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); - // Though the host could still send, we don't know. - // Does the bulk pipe need to be reset to valid to allow for a ZLP? - } - else - { - uint32_t remaining = (uint32_t)xfer->total_len - (uint32_t)xfer->queued_len; - if(remaining >= xfer->max_packet_size) { - pcd_set_ep_rx_bufsize(USB, EPindex,xfer->max_packet_size); - } else { - pcd_set_ep_rx_bufsize(USB, EPindex,remaining); - } - - if (!((wEPRegVal & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS)) { - /* Set endpoint active again for receiving more data. - * Note that isochronous endpoints stay active always */ - pcd_set_ep_rx_status(USB, EPindex, USB_EP_RX_VALID); + } else { + /* Set endpoint active again for receiving more data. + * Note that isochronous endpoints stay active always */ + if ((wEPRegVal & USB_EP_TYPE_MASK) != USB_EP_ISOCHRONOUS) { + uint16_t remaining = xfer->total_len - xfer->queued_len; + uint16_t cnt = tu_min16(remaining, xfer->max_packet_size); + pcd_set_ep_rx_cnt(USB, EPindex, cnt); } + pcd_set_ep_rx_status(USB, EPindex, USB_EP_RX_VALID); } } // For EP0, prepare to receive another SETUP packet. // Clear CTR last so that a new packet does not overwrite the packing being read. // (Based on the docs, it seems SETUP will always be accepted after CTR is cleared) - if(ep_addr == 0u) - { - // Always be prepared for a status packet... - pcd_set_ep_rx_bufsize(USB, EPindex, CFG_TUD_ENDPOINT0_SIZE); + if (ep_addr == 0u) { + // Always be prepared for a status packet... + pcd_set_ep_rx_cnt(USB, EPindex, CFG_TUD_ENDPOINT0_SIZE); pcd_clear_rx_ep_ctr(USB, EPindex); } } @@ -638,65 +640,60 @@ static void dcd_ep_ctr_handler(void) uint32_t wIstr; /* stay in loop while pending interrupts */ - while (((wIstr = USB->ISTR) & USB_ISTR_CTR) != 0U) - { - - if ((wIstr & USB_ISTR_DIR) == 0U) /* TX/IN */ - { + while (((wIstr = USB->ISTR) & USB_ISTR_CTR) != 0U) { + if ((wIstr & USB_ISTR_DIR) == 0U) { + /* TX/IN */ dcd_ep_ctr_tx_handler(wIstr); - } - else /* RX/OUT*/ - { + } else { + /* RX/OUT*/ dcd_ep_ctr_rx_handler(wIstr); } } } -void dcd_int_handler(uint8_t rhport) { +void dcd_int_handler(uint8_t rhport) +{ - (void) rhport; + (void)rhport; uint32_t int_status = USB->ISTR; - //const uint32_t handled_ints = USB_ISTR_CTR | USB_ISTR_RESET | USB_ISTR_WKUP - // | USB_ISTR_SUSP | USB_ISTR_SOF | USB_ISTR_ESOF; - // unused IRQs: (USB_ISTR_PMAOVR | USB_ISTR_ERR | USB_ISTR_L1REQ ) + // const uint32_t handled_ints = USB_ISTR_CTR | USB_ISTR_RESET | USB_ISTR_WKUP + // | USB_ISTR_SUSP | USB_ISTR_SOF | USB_ISTR_ESOF; + // unused IRQs: (USB_ISTR_PMAOVR | USB_ISTR_ERR | USB_ISTR_L1REQ ) // The ST driver loops here on the CTR bit, but that loop has been moved into the // dcd_ep_ctr_handler(), so less need to loop here. The other interrupts shouldn't // be triggered repeatedly. /* Put SOF flag at the beginning of ISR in case to get least amount of jitter if it is used for timing purposes */ - if(int_status & USB_ISTR_SOF) { - USB->ISTR &=~USB_ISTR_SOF; + if (int_status & USB_ISTR_SOF) { + USB->ISTR = (fsdev_bus_t)~USB_ISTR_SOF; dcd_event_sof(0, USB->FNR & USB_FNR_FN, true); } - if(int_status & USB_ISTR_RESET) { + if (int_status & USB_ISTR_RESET) { // USBRST is start of reset. - USB->ISTR &=~USB_ISTR_RESET; + USB->ISTR = (fsdev_bus_t)~USB_ISTR_RESET; dcd_handle_bus_reset(); dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); return; // Don't do the rest of the things here; perhaps they've been cleared? } - if (int_status & USB_ISTR_CTR) - { + if (int_status & USB_ISTR_CTR) { /* servicing of the endpoint correct transfer interrupt */ /* clear of the CTR flag into the sub */ dcd_ep_ctr_handler(); } - if (int_status & USB_ISTR_WKUP) - { + if (int_status & USB_ISTR_WKUP) { USB->CNTR &= ~USB_CNTR_LPMODE; USB->CNTR &= ~USB_CNTR_FSUSP; - USB->ISTR &=~USB_ISTR_WKUP; + USB->ISTR = (fsdev_bus_t)~USB_ISTR_WKUP; dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); } - if (int_status & USB_ISTR_SUSP) - { + if (int_status & USB_ISTR_SUSP) { /* Suspend is asserted for both suspend and unplug events. without Vbus monitoring, * these events cannot be differentiated, so we only trigger suspend. */ @@ -705,20 +702,18 @@ void dcd_int_handler(uint8_t rhport) { USB->CNTR |= USB_CNTR_LPMODE; /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ - USB->ISTR &=~USB_ISTR_SUSP; + USB->ISTR = (fsdev_bus_t)~USB_ISTR_SUSP; dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); } - if(int_status & USB_ISTR_ESOF) { - if(remoteWakeCountdown == 1u) - { + if (int_status & USB_ISTR_ESOF) { + if (remoteWakeCountdown == 1u) { USB->CNTR &= ~USB_CNTR_RESUME; } - if(remoteWakeCountdown > 0u) - { + if (remoteWakeCountdown > 0u) { remoteWakeCountdown--; } - USB->ISTR &=~USB_ISTR_ESOF; + USB->ISTR = (fsdev_bus_t)~USB_ISTR_ESOF; } } @@ -728,15 +723,14 @@ void dcd_int_handler(uint8_t rhport) { // Invoked when a control transfer's status stage is complete. // May help DCD to prepare for next control transfer, this API is optional. -void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) +void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request) { - (void) rhport; + (void)rhport; if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && - request->bRequest == TUSB_REQ_SET_ADDRESS ) - { - uint8_t const dev_addr = (uint8_t) request->wValue; + request->bRequest == TUSB_REQ_SET_ADDRESS) { + uint8_t const dev_addr = (uint8_t)request->wValue; // Setting new address after the whole request is complete USB->DADDR &= ~USB_DADDR_ADD; @@ -744,121 +738,58 @@ void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * re } } -static void dcd_pma_alloc_reset(void) -{ - open_ep_count = 0; - ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8*MAX_EP_COUNT; // 8 bytes per endpoint (two TX and two RX words, each) - //TU_LOG2("dcd_pma_alloc_reset()\r\n"); - for(uint32_t i=0; ipma_alloc_size = 0U; - xfer_ctl_ptr(tu_edpt_addr(i,TUSB_DIR_IN))->pma_alloc_size = 0U; - xfer_ctl_ptr(tu_edpt_addr(i,TUSB_DIR_OUT))->pma_ptr = 0U; - xfer_ctl_ptr(tu_edpt_addr(i,TUSB_DIR_IN))->pma_ptr = 0U; - } -} - /*** * Allocate a section of PMA - * - * If the EP number has already been allocated, and the new allocation - * is larger than the old allocation, then this will fail with a TU_ASSERT. - * (This is done to simplify the code. More complicated algorithms could be used) - * + * In case of double buffering, high 16bit is the address of 2nd buffer * During failure, TU_ASSERT is used. If this happens, rework/reallocate memory manually. */ -static uint16_t dcd_pma_alloc(uint8_t ep_addr, uint16_t length) +static uint32_t dcd_pma_alloc(uint16_t length, bool dbuf) { - xfer_ctl_t* epXferCtl = xfer_ctl_ptr(ep_addr); - - if(epXferCtl->pma_alloc_size != 0U) - { - //TU_LOG2("dcd_pma_alloc(%x,%x)=%x (cached)\r\n",ep_addr,length,epXferCtl->pma_ptr); - // Previously allocated - TU_ASSERT(length <= epXferCtl->pma_alloc_size, 0xFFFF); // Verify no larger than previous alloc - return epXferCtl->pma_ptr; - } - // Ensure allocated buffer is aligned -#ifdef PMA_32BIT_ACCESS +#ifdef FSDEV_BUS_32BIT length = (length + 3) & ~0x03; #else length = (length + 1) & ~0x01; #endif - open_ep_count++; - - uint16_t addr = ep_buf_ptr; + uint32_t addr = ep_buf_ptr; ep_buf_ptr = (uint16_t)(ep_buf_ptr + length); // increment buffer pointer - // Verify no overflow - TU_ASSERT(ep_buf_ptr <= PMA_LENGTH, 0xFFFF); + if (dbuf) { + addr |= ((uint32_t)ep_buf_ptr) << 16; + ep_buf_ptr = (uint16_t)(ep_buf_ptr + length); // increment buffer pointer + } - epXferCtl->pma_ptr = addr; - epXferCtl->pma_alloc_size = length; - //TU_LOG1("dcd_pma_alloc(%x,%x)=%x\r\n",ep_addr,length,addr); + // Verify packet buffer is not overflowed + TU_ASSERT(ep_buf_ptr <= FSDEV_PMA_SIZE, 0xFFFF); return addr; } -/*** - * Free a block of PMA space - */ -static void dcd_pma_free(uint8_t ep_addr) -{ - // Presently, this should never be called for EP0 IN/OUT - TU_ASSERT(open_ep_count > 2, /**/); - TU_ASSERT(xfer_ctl_ptr(ep_addr)->max_packet_size != 0, /**/); - open_ep_count--; - - // If count is 2, only EP0 should be open, so allocations can be mostly reset. - - if(open_ep_count == 2) - { - ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8*MAX_EP_COUNT + 2*CFG_TUD_ENDPOINT0_SIZE; // 8 bytes per endpoint (two TX and two RX words, each), and EP0 - - // Skip EP0 - for(uint32_t i=1; ipma_alloc_size = 0U; - xfer_ctl_ptr(tu_edpt_addr(i,TUSB_DIR_IN))->pma_alloc_size = 0U; - xfer_ctl_ptr(tu_edpt_addr(i,TUSB_DIR_OUT))->pma_ptr = 0U; - xfer_ctl_ptr(tu_edpt_addr(i,TUSB_DIR_IN))->pma_ptr = 0U; - } - } -} - /*** * Allocate hardware endpoint */ static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type) { uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); - for(uint8_t i = 0; i < STFSDEV_EP_COUNT; i++) - { + for (uint8_t i = 0; i < STFSDEV_EP_COUNT; i++) { // Check if already allocated - if(ep_alloc_status[i].allocated[dir] && - ep_alloc_status[i].ep_type == ep_type && - ep_alloc_status[i].ep_num == epnum) - { + if (ep_alloc_status[i].allocated[dir] && + ep_alloc_status[i].ep_type == ep_type && + ep_alloc_status[i].ep_num == epnum) { return i; } // If EP of current direction is not allocated // Except for ISO endpoint, both direction should be free - if(!ep_alloc_status[i].allocated[dir] && - (ep_type != TUSB_XFER_ISOCHRONOUS || !ep_alloc_status[i].allocated[dir ^ 1])) - { + if (!ep_alloc_status[i].allocated[dir] && + (ep_type != TUSB_XFER_ISOCHRONOUS || !ep_alloc_status[i].allocated[dir ^ 1])) { // Check if EP number is the same - if(ep_alloc_status[i].ep_num == 0xFF || - ep_alloc_status[i].ep_num == epnum) - { + if (ep_alloc_status[i].ep_num == 0xFF || ep_alloc_status[i].ep_num == epnum) { // One EP pair has to be the same type - if(ep_alloc_status[i].ep_type == 0xFF || - ep_alloc_status[i].ep_type == ep_type) - { + if (ep_alloc_status[i].ep_type == 0xFF || ep_alloc_status[i].ep_type == ep_type) { ep_alloc_status[i].ep_num = epnum; ep_alloc_status[i].ep_type = ep_type; ep_alloc_status[i].allocated[dir] = true; @@ -873,121 +804,79 @@ static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type) TU_ASSERT(0); } -/*** - * Free hardware endpoint - */ -static void dcd_ep_free(uint8_t ep_addr) -{ - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - for(uint8_t i = 0; i < STFSDEV_EP_COUNT; i++) - { - // Check if EP number & dir are the same - if(ep_alloc_status[i].ep_num == epnum && - ep_alloc_status[i].allocated[dir] == dir) - { - ep_alloc_status[i].allocated[dir] = false; - // Reset entry if ISO endpoint or both direction are free - if(ep_alloc_status[i].ep_type == TUSB_XFER_ISOCHRONOUS || - !ep_alloc_status[i].allocated[dir ^ 1]) - { - ep_alloc_status[i].ep_num = 0xFF; - ep_alloc_status[i].ep_type = 0xFF; - - return; - } - } - } -} - // The STM32F0 doesn't seem to like |= or &= to manipulate the EP#R registers, // so I'm using the #define from HAL here, instead. -bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoint_desc) { (void)rhport; - uint8_t const ep_idx = dcd_ep_alloc(p_endpoint_desc->bEndpointAddress, p_endpoint_desc->bmAttributes.xfer); - uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); + uint8_t const ep_addr = p_endpoint_desc->bEndpointAddress; + uint8_t const ep_idx = dcd_ep_alloc(ep_addr, p_endpoint_desc->bmAttributes.xfer); + uint8_t const dir = tu_edpt_dir(ep_addr); const uint16_t packet_size = tu_edpt_packet_size(p_endpoint_desc); const uint16_t buffer_size = pcd_aligned_buffer_size(packet_size); uint16_t pma_addr; uint32_t wType; TU_ASSERT(ep_idx < STFSDEV_EP_COUNT); - TU_ASSERT(buffer_size <= 1024); + TU_ASSERT(buffer_size <= 64); // Set type - switch(p_endpoint_desc->bmAttributes.xfer) { - case TUSB_XFER_CONTROL: - wType = USB_EP_CONTROL; - break; - case TUSB_XFER_ISOCHRONOUS: - wType = USB_EP_ISOCHRONOUS; - break; - case TUSB_XFER_BULK: - wType = USB_EP_CONTROL; - break; + switch (p_endpoint_desc->bmAttributes.xfer) { + case TUSB_XFER_CONTROL: + wType = USB_EP_CONTROL; + break; + case TUSB_XFER_BULK: + wType = USB_EP_CONTROL; + break; - case TUSB_XFER_INTERRUPT: - wType = USB_EP_INTERRUPT; - break; + case TUSB_XFER_INTERRUPT: + wType = USB_EP_INTERRUPT; + break; - default: - TU_ASSERT(false); + default: + // Note: ISO endpoint should use alloc / active functions + TU_ASSERT(false); } pcd_set_eptype(USB, ep_idx, wType); - pcd_set_ep_address(USB, ep_idx, tu_edpt_number(p_endpoint_desc->bEndpointAddress)); - // Be normal, for now, instead of only accepting zero-byte packets (on control endpoint) - // or being double-buffered (bulk endpoints) - pcd_clear_ep_kind(USB,0); + pcd_set_ep_address(USB, ep_idx, tu_edpt_number(ep_addr)); - /* Create a packet memory buffer area. For isochronous endpoints, - * use the same buffer as the double buffer, essentially disabling double buffering */ - pma_addr = dcd_pma_alloc(p_endpoint_desc->bEndpointAddress, buffer_size); + /* Create a packet memory buffer area. */ + pma_addr = dcd_pma_alloc(buffer_size, false); - if( (dir == TUSB_DIR_IN) || (wType == USB_EP_ISOCHRONOUS) ) - { + if (dir == TUSB_DIR_IN) { pcd_set_ep_tx_address(USB, ep_idx, pma_addr); - pcd_set_ep_tx_bufsize(USB, ep_idx, buffer_size); + pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_NAK); pcd_clear_tx_dtog(USB, ep_idx); - } - - if( (dir == TUSB_DIR_OUT) || (wType == USB_EP_ISOCHRONOUS) ) - { + } else { pcd_set_ep_rx_address(USB, ep_idx, pma_addr); - pcd_set_ep_rx_bufsize(USB, ep_idx, buffer_size); + pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_NAK); pcd_clear_rx_dtog(USB, ep_idx); } - /* Enable endpoint */ - if (dir == TUSB_DIR_IN) - { - if(wType == USB_EP_ISOCHRONOUS) { - pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_DIS); - } else { - pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_NAK); - } - } else - { - if(wType == USB_EP_ISOCHRONOUS) { - pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_DIS); - } else { - pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_NAK); - } - } - - xfer_ctl_ptr(p_endpoint_desc->bEndpointAddress)->max_packet_size = packet_size; - xfer_ctl_ptr(p_endpoint_desc->bEndpointAddress)->ep_idx = ep_idx; + xfer_ctl_ptr(ep_addr)->max_packet_size = packet_size; + xfer_ctl_ptr(ep_addr)->ep_idx = ep_idx; return true; } -void dcd_edpt_close_all (uint8_t rhport) +void dcd_edpt_close_all(uint8_t rhport) { - (void) rhport; - // TODO implement dcd_edpt_close_all() + (void)rhport; + + for (uint32_t i = 1; i < STFSDEV_EP_COUNT; i++) { + // Reset endpoint + pcd_set_endpoint(USB, i, 0); + // Clear EP allocation status + ep_alloc_status[i].ep_num = 0xFF; + ep_alloc_status[i].ep_type = 0xFF; + ep_alloc_status[i].allocated[0] = false; + ep_alloc_status[i].allocated[1] = false; + } + + // Reset PMA allocation + ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8 * MAX_EP_COUNT + 2 * CFG_TUD_ENDPOINT0_SIZE; } /** @@ -997,223 +886,203 @@ void dcd_edpt_close_all (uint8_t rhport) * * This also clears transfers in progress, should there be any. */ -void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { (void)rhport; - xfer_ctl_t * xfer = xfer_ctl_ptr(ep_addr); + xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); uint8_t const ep_idx = xfer->ep_idx; - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); - if(dir == TUSB_DIR_IN) - { + if (dir == TUSB_DIR_IN) { pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_DIS); - } - else - { + } else { pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_DIS); } - - dcd_ep_free(ep_addr); - - dcd_pma_free(ep_addr); } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void)rhport; - TU_ASSERT(largest_packet_size <= 1024); - uint8_t const ep_idx = dcd_ep_alloc(ep_addr, TUSB_XFER_ISOCHRONOUS); const uint16_t buffer_size = pcd_aligned_buffer_size(largest_packet_size); - /* Create a packet memory buffer area. For isochronous endpoints, - * use the same buffer as the double buffer, essentially disabling double buffering */ - uint16_t pma_addr = dcd_pma_alloc(ep_addr, buffer_size); - - xfer_ctl_ptr(ep_addr)->ep_idx = ep_idx; + /* Create a packet memory buffer area. Enable double buffering for devices with 2048 bytes PMA, + for smaller devices double buffering occupy too much space. */ +#if FSDEV_PMA_SIZE > 1024u + uint32_t pma_addr = dcd_pma_alloc(buffer_size, true); + uint16_t pma_addr2 = pma_addr >> 16; +#else + uint32_t pma_addr = dcd_pma_alloc(buffer_size, true); + uint16_t pma_addr2 = pma_addr; +#endif + pcd_set_ep_tx_address(USB, ep_idx, pma_addr); + pcd_set_ep_rx_address(USB, ep_idx, pma_addr2); pcd_set_eptype(USB, ep_idx, USB_EP_ISOCHRONOUS); - pcd_set_ep_tx_address(USB, ep_idx, pma_addr); - pcd_set_ep_rx_address(USB, ep_idx, pma_addr); + xfer_ctl_ptr(ep_addr)->ep_idx = ep_idx; return true; } -bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) +bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoint_desc) { (void)rhport; - uint8_t const ep_idx = xfer_ctl_ptr(p_endpoint_desc->bEndpointAddress)->ep_idx; - uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); + uint8_t const ep_addr = p_endpoint_desc->bEndpointAddress; + uint8_t const ep_idx = xfer_ctl_ptr(ep_addr)->ep_idx; + uint8_t const dir = tu_edpt_dir(ep_addr); const uint16_t packet_size = tu_edpt_packet_size(p_endpoint_desc); - const uint16_t buffer_size = pcd_aligned_buffer_size(packet_size); - /* Disable endpoint */ - if(dir == TUSB_DIR_IN) - { - pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_DIS); - } - else - { - pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_DIS); - } + pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_DIS); + pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_DIS); - pcd_set_ep_address(USB, ep_idx, tu_edpt_number(p_endpoint_desc->bEndpointAddress)); - // Be normal, for now, instead of only accepting zero-byte packets (on control endpoint) - // or being double-buffered (bulk endpoints) - pcd_clear_ep_kind(USB,0); + pcd_set_ep_address(USB, ep_idx, tu_edpt_number(ep_addr)); - pcd_set_ep_tx_bufsize(USB, ep_idx, buffer_size); - pcd_set_ep_rx_bufsize(USB, ep_idx, buffer_size); pcd_clear_tx_dtog(USB, ep_idx); pcd_clear_rx_dtog(USB, ep_idx); - xfer_ctl_ptr(p_endpoint_desc->bEndpointAddress)->max_packet_size = packet_size; + if (dir == TUSB_DIR_IN) { + pcd_rx_dtog(USB, ep_idx); + } else { + pcd_tx_dtog(USB, ep_idx); + } + + xfer_ctl_ptr(ep_addr)->max_packet_size = packet_size; return true; } // Currently, single-buffered, and only 64 bytes at a time (max) -static void dcd_transmit_packet(xfer_ctl_t * xfer, uint16_t ep_ix) +static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { uint16_t len = (uint16_t)(xfer->total_len - xfer->queued_len); - - if(len > xfer->max_packet_size) // max packet size for FS transfer - { + if (len > xfer->max_packet_size) { len = xfer->max_packet_size; } uint16_t ep_reg = pcd_get_endpoint(USB, ep_ix); - uint16_t addr_ptr = pcd_get_ep_tx_address(USB, ep_ix); + bool const is_iso = (ep_reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS; + uint16_t addr_ptr; - if (xfer->ff) - { - dcd_write_packet_memory_ff(xfer->ff, addr_ptr, len); + if (is_iso) { + if (ep_reg & USB_EP_DTOG_TX) { + addr_ptr = pcd_get_ep_dbuf1_address(USB, ep_ix); + pcd_set_ep_tx_dbuf1_cnt(USB, ep_ix, len); + } else { + addr_ptr = pcd_get_ep_dbuf0_address(USB, ep_ix); + pcd_set_ep_tx_dbuf0_cnt(USB, ep_ix, len); + } + } else { + addr_ptr = pcd_get_ep_tx_address(USB, ep_ix); + pcd_set_ep_tx_cnt(USB, ep_ix, len); } - else - { + + if (xfer->ff) { + dcd_write_packet_memory_ff(xfer->ff, addr_ptr, len); + } else { dcd_write_packet_memory(addr_ptr, &(xfer->buffer[xfer->queued_len]), len); } xfer->queued_len = (uint16_t)(xfer->queued_len + len); - /* Write into correct register when ISOCHRONOUS (double buffered) */ - if ( (ep_reg & USB_EP_DTOG_TX) && ( (ep_reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) ) { - pcd_set_ep_rx_cnt(USB, ep_ix, len); - } else { - pcd_set_ep_tx_cnt(USB, ep_ix, len); - } - + dcd_int_disable(0); pcd_set_ep_tx_status(USB, ep_ix, USB_EP_TX_VALID); + if (is_iso) { + xfer->iso_in_sending = true; + } + dcd_int_enable(0); } -bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) -{ - (void) rhport; - - xfer_ctl_t * xfer = xfer_ctl_ptr(ep_addr); - uint8_t const ep_idx = xfer->ep_idx; - uint8_t const dir = tu_edpt_dir(ep_addr); - - xfer->buffer = buffer; - xfer->ff = NULL; - xfer->total_len = total_bytes; - xfer->queued_len = 0; - - if ( dir == TUSB_DIR_OUT ) - { - // A setup token can occur immediately after an OUT STATUS packet so make sure we have a valid - // buffer for the control endpoint. - if (ep_idx == 0 && buffer == NULL) - { - xfer->buffer = (uint8_t*)_setup_packet; - } - - if(total_bytes > xfer->max_packet_size) - { - pcd_set_ep_rx_bufsize(USB,ep_idx,xfer->max_packet_size); - } else { - pcd_set_ep_rx_bufsize(USB,ep_idx,total_bytes); - } - pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_VALID); - } - else // IN - { - dcd_transmit_packet(xfer,ep_idx); - } - return true; -} - -bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) -{ - (void) rhport; - - xfer_ctl_t * xfer = xfer_ctl_ptr(ep_addr); - uint8_t const epnum = xfer->ep_idx; - uint8_t const dir = tu_edpt_dir(ep_addr); - - xfer->buffer = NULL; - xfer->ff = ff; - xfer->total_len = total_bytes; - xfer->queued_len = 0; - - if ( dir == TUSB_DIR_OUT ) - { - if(total_bytes > xfer->max_packet_size) - { - pcd_set_ep_rx_bufsize(USB,epnum,xfer->max_packet_size); - } else { - pcd_set_ep_rx_bufsize(USB,epnum,total_bytes); - } - pcd_set_ep_rx_status(USB, epnum, USB_EP_RX_VALID); - } - else // IN - { - dcd_transmit_packet(xfer,epnum); - } - return true; -} - -void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) +static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) { (void)rhport; - xfer_ctl_t * xfer = xfer_ctl_ptr(ep_addr); + xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); uint8_t const ep_idx = xfer->ep_idx; - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); - if (dir == TUSB_DIR_IN) - { // IN - pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_STALL); + if (dir == TUSB_DIR_IN) { + dcd_transmit_packet(xfer, ep_idx); + } else { + // A setup token can occur immediately after an OUT STATUS packet so make sure we have a valid + // buffer for the control endpoint. + if (ep_idx == 0 && xfer->buffer == NULL) { + xfer->buffer = (uint8_t *)_setup_packet; + } + + uint32_t cnt = (uint32_t ) tu_min16(xfer->total_len, xfer->max_packet_size); + uint16_t ep_reg = pcd_get_endpoint(USB, ep_idx); + + if ((ep_reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) { + pcd_set_ep_rx_dbuf0_cnt(USB, ep_idx, cnt); + pcd_set_ep_rx_dbuf1_cnt(USB, ep_idx, cnt); + } else { + pcd_set_ep_rx_cnt(USB, ep_idx, cnt); + } + + pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_VALID); } - else - { // OUT + + return true; +} + +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) +{ + xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); + + xfer->buffer = buffer; + xfer->ff = NULL; + xfer->total_len = total_bytes; + xfer->queued_len = 0; + + return edpt_xfer(rhport, ep_addr); +} + +bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes) +{ + xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); + xfer->buffer = NULL; + xfer->ff = ff; + xfer->total_len = total_bytes; + xfer->queued_len = 0; + + return edpt_xfer(rhport, ep_addr); +} + +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void)rhport; + + xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); + uint8_t const ep_idx = xfer->ep_idx; + uint8_t const dir = tu_edpt_dir(ep_addr); + + if (dir == TUSB_DIR_IN) { + pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_STALL); + } else { pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_STALL); } } -void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; - xfer_ctl_t * xfer = xfer_ctl_ptr(ep_addr); + xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); uint8_t const ep_idx = xfer->ep_idx; - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); - if (dir == TUSB_DIR_IN) - { // IN - if (pcd_get_eptype(USB, ep_idx) != USB_EP_ISOCHRONOUS) { + if (dir == TUSB_DIR_IN) { // IN + if (pcd_get_eptype(USB, ep_idx) != USB_EP_ISOCHRONOUS) { pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_NAK); } /* Reset to DATA0 if clearing stall condition. */ pcd_clear_tx_dtog(USB, ep_idx); - } - else - { // OUT - if (pcd_get_eptype(USB, ep_idx) != USB_EP_ISOCHRONOUS) { + } else { // OUT + if (pcd_get_eptype(USB, ep_idx) != USB_EP_ISOCHRONOUS) { pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_NAK); } /* Reset to DATA0 if clearing stall condition. */ @@ -1221,11 +1090,11 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) } } -#ifdef PMA_32BIT_ACCESS +#ifdef FSDEV_BUS_32BIT static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t wNBytes) { - const uint8_t* srcVal = src; - volatile uint32_t* dst32 = (volatile uint32_t*)(USB_PMAADDR + dst); + const uint8_t *srcVal = src; + volatile uint32_t *dst32 = (volatile uint32_t *)(USB_PMAADDR + dst); for (uint32_t n = wNBytes / 4; n > 0; --n) { *dst32++ = tu_unaligned_read32(srcVal); @@ -1233,18 +1102,15 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, ui } wNBytes = wNBytes & 0x03; - if (wNBytes) - { + if (wNBytes) { uint32_t wrVal = *srcVal; wNBytes--; - if (wNBytes) - { + if (wNBytes) { wrVal |= *++srcVal << 8; wNBytes--; - if (wNBytes) - { + if (wNBytes) { wrVal |= *++srcVal << 16; } } @@ -1257,40 +1123,38 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, ui #else // Packet buffer access can only be 8- or 16-bit. /** - * @brief Copy a buffer from user memory area to packet memory area (PMA). - * This uses byte-access for user memory (so support non-aligned buffers) - * and 16-bit access for packet memory. - * @param dst, byte address in PMA; must be 16-bit aligned - * @param src pointer to user memory area. - * @param wPMABufAddr address into PMA. - * @param wNBytes no. of bytes to be copied. - * @retval None - */ + * @brief Copy a buffer from user memory area to packet memory area (PMA). + * This uses byte-access for user memory (so support non-aligned buffers) + * and 16-bit access for packet memory. + * @param dst, byte address in PMA; must be 16-bit aligned + * @param src pointer to user memory area. + * @param wPMABufAddr address into PMA. + * @param wNBytes no. of bytes to be copied. + * @retval None + */ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t wNBytes) { uint32_t n = (uint32_t)wNBytes >> 1U; uint16_t temp1, temp2; - const uint8_t * srcVal; + const uint8_t *srcVal; // The GCC optimizer will combine access to 32-bit sizes if we let it. Force // it volatile so that it won't do that. __IO uint16_t *pdwVal; srcVal = src; - pdwVal = &pma[PMA_STRIDE*(dst>>1)]; + pdwVal = &pma[FSDEV_PMA_STRIDE * (dst >> 1)]; - while (n--) - { + while (n--) { temp1 = (uint16_t)*srcVal; srcVal++; - temp2 = temp1 | ((uint16_t)(((uint16_t)(*srcVal)) << 8U)) ; + temp2 = temp1 | ((uint16_t)(((uint16_t)(*srcVal)) << 8U)); *pdwVal = temp2; - pdwVal += PMA_STRIDE; + pdwVal += FSDEV_PMA_STRIDE; srcVal++; } - if (wNBytes) - { + if (wNBytes) { temp1 = *srcVal; *pdwVal = temp1; } @@ -1300,42 +1164,39 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, ui #endif /** - * @brief Copy from FIFO to packet memory area (PMA). - * Uses byte-access of system memory and 16-bit access of packet memory - * @param wNBytes no. of bytes to be copied. - * @retval None - */ -static bool dcd_write_packet_memory_ff(tu_fifo_t * ff, uint16_t dst, uint16_t wNBytes) + * @brief Copy from FIFO to packet memory area (PMA). + * Uses byte-access of system memory and 16-bit access of packet memory + * @param wNBytes no. of bytes to be copied. + * @retval None + */ +static bool dcd_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNBytes) { // Since we copy from a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies tu_fifo_buffer_info_t info; tu_fifo_get_read_info(ff, &info); - uint16_t cnt_lin = TU_MIN(wNBytes, info.len_lin); + uint16_t cnt_lin = TU_MIN(wNBytes, info.len_lin); uint16_t cnt_wrap = TU_MIN(wNBytes - cnt_lin, info.len_wrap); // We want to read from the FIFO and write it into the PMA, if LIN part is ODD and has WRAPPED part, // last lin byte will be combined with wrapped part // To ensure PMA is always access aligned (dst aligned to 16 or 32 bit) -#ifdef PMA_32BIT_ACCESS - if((cnt_lin & 0x03) && cnt_wrap) - { +#ifdef FSDEV_BUS_32BIT + if ((cnt_lin & 0x03) && cnt_wrap) { // Copy first linear part - dcd_write_packet_memory(dst, info.ptr_lin, cnt_lin &~0x03); - dst += cnt_lin &~0x03; + dcd_write_packet_memory(dst, info.ptr_lin, cnt_lin & ~0x03); + dst += cnt_lin & ~0x03; // Copy last linear bytes & first wrapped bytes to buffer uint32_t i; uint8_t tmp[4]; - for (i = 0; i < (cnt_lin & 0x03); i++) - { - tmp[i] = ((uint8_t*)info.ptr_lin)[(cnt_lin &~0x03) + i]; + for (i = 0; i < (cnt_lin & 0x03); i++) { + tmp[i] = ((uint8_t *)info.ptr_lin)[(cnt_lin & ~0x03) + i]; } uint32_t wCnt = cnt_wrap; - for (; i < 4 && wCnt > 0; i++, wCnt--) - { - tmp[i] = *(uint8_t*)info.ptr_wrap; - info.ptr_wrap = (uint8_t*)info.ptr_wrap + 1; + for (; i < 4 && wCnt > 0; i++, wCnt--) { + tmp[i] = *(uint8_t *)info.ptr_wrap; + info.ptr_wrap = (uint8_t *)info.ptr_wrap + 1; } // Write unaligned buffer @@ -1344,32 +1205,29 @@ static bool dcd_write_packet_memory_ff(tu_fifo_t * ff, uint16_t dst, uint16_t wN // Copy rest of wrapped byte if (wCnt) - dcd_write_packet_memory(dst, info.ptr_wrap, wCnt); + dcd_write_packet_memory(dst, info.ptr_wrap, wCnt); } #else - if((cnt_lin & 0x01) && cnt_wrap) - { + if ((cnt_lin & 0x01) && cnt_wrap) { // Copy first linear part - dcd_write_packet_memory(dst, info.ptr_lin, cnt_lin &~0x01); - dst += cnt_lin &~0x01; + dcd_write_packet_memory(dst, info.ptr_lin, cnt_lin & ~0x01); + dst += cnt_lin & ~0x01; // Copy last linear byte & first wrapped byte - uint16_t tmp = ((uint8_t*)info.ptr_lin)[cnt_lin - 1] | ((uint16_t)(((uint8_t*)info.ptr_wrap)[0]) << 8U); + uint16_t tmp = ((uint8_t *)info.ptr_lin)[cnt_lin - 1] | ((uint16_t)(((uint8_t *)info.ptr_wrap)[0]) << 8U); dcd_write_packet_memory(dst, &tmp, 2); dst += 2; // Copy rest of wrapped byte - dcd_write_packet_memory(dst, ((uint8_t*)info.ptr_wrap) + 1, cnt_wrap - 1); + dcd_write_packet_memory(dst, ((uint8_t *)info.ptr_wrap) + 1, cnt_wrap - 1); } #endif - else - { + else { // Copy linear part dcd_write_packet_memory(dst, info.ptr_lin, cnt_lin); dst += info.len_lin; - if(info.len_wrap) - { + if (info.len_wrap) { // Copy wrapped byte dcd_write_packet_memory(dst, info.ptr_wrap, cnt_wrap); } @@ -1380,11 +1238,11 @@ static bool dcd_write_packet_memory_ff(tu_fifo_t * ff, uint16_t dst, uint16_t wN return true; } -#ifdef PMA_32BIT_ACCESS +#ifdef FSDEV_BUS_32BIT static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t wNBytes) { - uint8_t* dstVal = dst; - volatile uint32_t* src32 = (volatile uint32_t*)(USB_PMAADDR + src); + uint8_t *dstVal = dst; + volatile uint32_t *src32 = (volatile uint32_t *)(USB_PMAADDR + src); for (uint32_t n = wNBytes / 4; n > 0; --n) { tu_unaligned_write32(dstVal, *src32++); @@ -1392,20 +1250,17 @@ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t } wNBytes = wNBytes & 0x03; - if (wNBytes) - { + if (wNBytes) { uint32_t rdVal = *src32; *dstVal = tu_u32_byte0(rdVal); wNBytes--; - if (wNBytes) - { + if (wNBytes) { *++dstVal = tu_u32_byte1(rdVal); wNBytes--; - if (wNBytes) - { + if (wNBytes) { *++dstVal = tu_u32_byte2(rdVal); } } @@ -1415,11 +1270,11 @@ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t } #else /** - * @brief Copy a buffer from packet memory area (PMA) to user memory area. - * Uses byte-access of system memory and 16-bit access of packet memory - * @param wNBytes no. of bytes to be copied. - * @retval None - */ + * @brief Copy a buffer from packet memory area (PMA) to user memory area. + * Uses byte-access of system memory and 16-bit access of packet memory + * @param wNBytes no. of bytes to be copied. + * @retval None + */ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t wNBytes) { uint32_t n = (uint32_t)wNBytes >> 1U; @@ -1428,21 +1283,19 @@ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t __IO const uint16_t *pdwVal; uint32_t temp; - pdwVal = &pma[PMA_STRIDE*(src>>1)]; - uint8_t *dstVal = (uint8_t*)dst; + pdwVal = &pma[FSDEV_PMA_STRIDE * (src >> 1)]; + uint8_t *dstVal = (uint8_t *)dst; - while (n--) - { + while (n--) { temp = *pdwVal; - pdwVal += PMA_STRIDE; + pdwVal += FSDEV_PMA_STRIDE; *dstVal++ = ((temp >> 0) & 0xFF); *dstVal++ = ((temp >> 8) & 0xFF); } - if (wNBytes & 0x01) - { + if (wNBytes & 0x01) { temp = *pdwVal; - pdwVal += PMA_STRIDE; + pdwVal += FSDEV_PMA_STRIDE; *dstVal++ = ((temp >> 0) & 0xFF); } return true; @@ -1450,31 +1303,29 @@ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t #endif /** - * @brief Copy a buffer from user packet memory area (PMA) to FIFO. - * Uses byte-access of system memory and 16-bit access of packet memory - * @param wNBytes no. of bytes to be copied. - * @retval None - */ -static bool dcd_read_packet_memory_ff(tu_fifo_t * ff, uint16_t src, uint16_t wNBytes) + * @brief Copy a buffer from user packet memory area (PMA) to FIFO. + * Uses byte-access of system memory and 16-bit access of packet memory + * @param wNBytes no. of bytes to be copied. + * @retval None + */ +static bool dcd_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBytes) { // Since we copy into a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies // Check for first linear part tu_fifo_buffer_info_t info; - tu_fifo_get_write_info(ff, &info); // We want to read from the FIFO + tu_fifo_get_write_info(ff, &info); // We want to read from the FIFO - uint16_t cnt_lin = TU_MIN(wNBytes, info.len_lin); + uint16_t cnt_lin = TU_MIN(wNBytes, info.len_lin); uint16_t cnt_wrap = TU_MIN(wNBytes - cnt_lin, info.len_wrap); - // We want to read from PMA and write it into the FIFO, if LIN part is ODD and has WRAPPED part, // last lin byte will be combined with wrapped part // To ensure PMA is always access aligned (src aligned to 16 or 32 bit) -#ifdef PMA_32BIT_ACCESS - if((cnt_lin & 0x03) && cnt_wrap) - { +#ifdef FSDEV_BUS_32BIT + if ((cnt_lin & 0x03) && cnt_wrap) { // Copy first linear part - dcd_read_packet_memory(info.ptr_lin, src, cnt_lin &~0x03); - src += cnt_lin &~0x03; + dcd_read_packet_memory(info.ptr_lin, src, cnt_lin & ~0x03); + src += cnt_lin & ~0x03; // Copy last linear bytes & first wrapped bytes uint8_t tmp[4]; @@ -1482,15 +1333,13 @@ static bool dcd_read_packet_memory_ff(tu_fifo_t * ff, uint16_t src, uint16_t wNB src += 4; uint32_t i; - for (i = 0; i < (cnt_lin & 0x03); i++) - { - ((uint8_t*)info.ptr_lin)[(cnt_lin &~0x03) + i] = tmp[i]; + for (i = 0; i < (cnt_lin & 0x03); i++) { + ((uint8_t *)info.ptr_lin)[(cnt_lin & ~0x03) + i] = tmp[i]; } uint32_t wCnt = cnt_wrap; - for (; i < 4 && wCnt > 0; i++, wCnt--) - { - *(uint8_t*)info.ptr_wrap = tmp[i]; - info.ptr_wrap = (uint8_t*)info.ptr_wrap + 1; + for (; i < 4 && wCnt > 0; i++, wCnt--) { + *(uint8_t *)info.ptr_wrap = tmp[i]; + info.ptr_wrap = (uint8_t *)info.ptr_wrap + 1; } // Copy rest of wrapped byte @@ -1498,32 +1347,29 @@ static bool dcd_read_packet_memory_ff(tu_fifo_t * ff, uint16_t src, uint16_t wNB dcd_read_packet_memory(info.ptr_wrap, src, wCnt); } #else - if((cnt_lin & 0x01) && cnt_wrap) - { + if ((cnt_lin & 0x01) && cnt_wrap) { // Copy first linear part - dcd_read_packet_memory(info.ptr_lin, src, cnt_lin &~0x01); - src += cnt_lin &~0x01; + dcd_read_packet_memory(info.ptr_lin, src, cnt_lin & ~0x01); + src += cnt_lin & ~0x01; // Copy last linear byte & first wrapped byte uint8_t tmp[2]; dcd_read_packet_memory(tmp, src, 2); src += 2; - ((uint8_t*)info.ptr_lin)[cnt_lin - 1] = tmp[0]; - ((uint8_t*)info.ptr_wrap)[0] = tmp[1]; + ((uint8_t *)info.ptr_lin)[cnt_lin - 1] = tmp[0]; + ((uint8_t *)info.ptr_wrap)[0] = tmp[1]; // Copy rest of wrapped byte - dcd_read_packet_memory(((uint8_t*)info.ptr_wrap) + 1, src, cnt_wrap - 1); + dcd_read_packet_memory(((uint8_t *)info.ptr_wrap) + 1, src, cnt_wrap - 1); } #endif - else - { + else { // Copy linear part dcd_read_packet_memory(info.ptr_lin, src, cnt_lin); src += cnt_lin; - if(info.len_wrap) - { + if (info.len_wrap) { // Copy wrapped byte dcd_read_packet_memory(info.ptr_wrap, src, cnt_wrap); } diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h similarity index 69% rename from src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h rename to src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h index e6649de5a..7992f34a1 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h @@ -1,34 +1,36 @@ -/** - * Copyright(c) 2016 STMicroelectronics - * Copyright(c) N Conrad - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ +/* + * Copyright(c) 2016 STMicroelectronics + * Copyright(c) N Conrad + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the TinyUSB stack. + */ // This file contains source copied from ST's HAL, and thus should have their copyright statement. -// PMA_LENGTH is PMA buffer size in bytes. +// FSDEV_PMA_SIZE is PMA buffer size in bytes. // On 512-byte devices, access with a stride of two words (use every other 16-bit address) // On 1024-byte devices, access with a stride of one word (use every 16-bit address) @@ -37,7 +39,7 @@ #if CFG_TUSB_MCU == OPT_MCU_STM32F0 #include "stm32f0xx.h" - #define PMA_LENGTH (1024u) + #define FSDEV_PMA_SIZE (1024u) // F0x2 models are crystal-less // All have internal D+ pull-up // 070RB: 2 x 16 bits/word memory LPM Support, BCD Support @@ -45,7 +47,7 @@ #elif CFG_TUSB_MCU == OPT_MCU_STM32F1 #include "stm32f1xx.h" - #define PMA_LENGTH (512u) + #define FSDEV_PMA_SIZE (512u) // NO internal Pull-ups // *B, and *C: 2 x 16 bits/word @@ -56,7 +58,7 @@ defined(STM32F303xB) || defined(STM32F303xC) || \ defined(STM32F373xC) #include "stm32f3xx.h" - #define PMA_LENGTH (512u) + #define FSDEV_PMA_SIZE (512u) // NO internal Pull-ups // *B, and *C: 1 x 16 bits/word // PMA dedicated to USB (no sharing with CAN) @@ -65,27 +67,60 @@ defined(STM32F302xD) || defined(STM32F302xE) || \ defined(STM32F303xD) || defined(STM32F303xE) #include "stm32f3xx.h" - #define PMA_LENGTH (1024u) + #define FSDEV_PMA_SIZE (1024u) // NO internal Pull-ups // *6, *8, *D, and *E: 2 x 16 bits/word LPM Support // When CAN clock is enabled, USB can use first 768 bytes ONLY. #elif CFG_TUSB_MCU == OPT_MCU_STM32L0 #include "stm32l0xx.h" - #define PMA_LENGTH (1024u) + #define FSDEV_PMA_SIZE (1024u) #elif CFG_TUSB_MCU == OPT_MCU_STM32L1 #include "stm32l1xx.h" - #define PMA_LENGTH (512u) + #define FSDEV_PMA_SIZE (512u) #elif CFG_TUSB_MCU == OPT_MCU_STM32G4 #include "stm32g4xx.h" - #define PMA_LENGTH (1024u) + #define FSDEV_PMA_SIZE (1024u) #elif CFG_TUSB_MCU == OPT_MCU_STM32G0 #include "stm32g0xx.h" - #define PMA_32BIT_ACCESS - #define PMA_LENGTH (2048u) + #define FSDEV_BUS_32BIT + #define FSDEV_PMA_SIZE (2048u) + #undef USB_PMAADDR + #define USB_PMAADDR USB_DRD_PMAADDR + #define USB_TypeDef USB_DRD_TypeDef + #define EP0R CHEP0R + #define USB_EP_CTR_RX USB_EP_VTRX + #define USB_EP_CTR_TX USB_EP_VTTX + #define USB_EP_T_FIELD USB_CHEP_UTYPE + #define USB_EPREG_MASK USB_CHEP_REG_MASK + #define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK + #define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK + #define USB_EPTX_DTOG1 USB_CHEP_TX_DTOG1 + #define USB_EPTX_DTOG2 USB_CHEP_TX_DTOG2 + #define USB_EPRX_DTOG1 USB_CHEP_RX_DTOG1 + #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2 + #define USB_EPRX_STAT USB_CH_RX_VALID + #define USB_EPKIND_MASK USB_EP_KIND_MASK + #define USB USB_DRD_FS + #define USB_CNTR_FRES USB_CNTR_USBRST + #define USB_CNTR_RESUME USB_CNTR_L2RES + #define USB_ISTR_EP_ID USB_ISTR_IDN + #define USB_EPADDR_FIELD USB_CHEP_ADDR + #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY + #define USB_CNTR_FSUSP USB_CNTR_SUSPEN + +#elif CFG_TUSB_MCU == OPT_MCU_STM32H5 + #include "stm32h5xx.h" + #define FSDEV_BUS_32BIT + + #if !defined(USB_DRD_BASE) && defined(USB_DRD_FS_BASE) + #define USB_DRD_BASE USB_DRD_FS_BASE + #endif + + #define FSDEV_PMA_SIZE (2048u) #undef USB_PMAADDR #define USB_PMAADDR USB_DRD_PMAADDR #define USB_TypeDef USB_DRD_TypeDef @@ -112,18 +147,18 @@ #elif CFG_TUSB_MCU == OPT_MCU_STM32WB #include "stm32wbxx.h" - #define PMA_LENGTH (1024u) + #define FSDEV_PMA_SIZE (1024u) /* ST provided header has incorrect value */ #undef USB_PMAADDR #define USB_PMAADDR USB1_PMAADDR #elif CFG_TUSB_MCU == OPT_MCU_STM32L4 #include "stm32l4xx.h" - #define PMA_LENGTH (1024u) + #define FSDEV_PMA_SIZE (1024u) #elif CFG_TUSB_MCU == OPT_MCU_STM32L5 #include "stm32l5xx.h" - #define PMA_LENGTH (1024u) + #define FSDEV_PMA_SIZE (1024u) #ifndef USB_PMAADDR #define USB_PMAADDR (USB_BASE + (USB_PMAADDR_NS - USB_BASE_NS)) @@ -135,41 +170,41 @@ #endif // For purposes of accessing the packet -#if ((PMA_LENGTH) == 512u) - #define PMA_STRIDE (2u) -#elif ((PMA_LENGTH) == 1024u) - #define PMA_STRIDE (1u) +#if ((FSDEV_PMA_SIZE) == 512u) + #define FSDEV_PMA_STRIDE (2u) +#elif ((FSDEV_PMA_SIZE) == 1024u) + #define FSDEV_PMA_STRIDE (1u) #endif +// The fsdev_bus_t type can be used for both register and PMA access necessities // For type-safety create a new macro for the volatile address of PMAADDR // The compiler should warn us if we cast it to a non-volatile type? -#ifdef PMA_32BIT_ACCESS +#ifdef FSDEV_BUS_32BIT +typedef uint32_t fsdev_bus_t; static __IO uint32_t * const pma32 = (__IO uint32_t*)USB_PMAADDR; + #else +typedef uint16_t fsdev_bus_t; // Volatile is also needed to prevent the optimizer from changing access to 32-bit (as 32-bit access is forbidden) static __IO uint16_t * const pma = (__IO uint16_t*)USB_PMAADDR; -TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t * pcd_btable_word_ptr(USB_TypeDef * USBx, size_t x) -{ +TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t * pcd_btable_word_ptr(USB_TypeDef * USBx, size_t x) { size_t total_word_offset = (((USBx)->BTABLE)>>1) + x; - total_word_offset *= PMA_STRIDE; + total_word_offset *= FSDEV_PMA_STRIDE; return &(pma[total_word_offset]); } -TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t* pcd_ep_tx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpIdx) -{ +TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t* pcd_ep_tx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpIdx) { return pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 1u); } -TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t* pcd_ep_rx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpIdx) -{ +TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t* pcd_ep_rx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpIdx) { return pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 3u); } #endif /* Aligned buffer size according to hardware */ -TU_ATTR_ALWAYS_INLINE static inline uint16_t pcd_aligned_buffer_size(uint16_t size) -{ +TU_ATTR_ALWAYS_INLINE static inline uint16_t pcd_aligned_buffer_size(uint16_t size) { /* The STM32 full speed USB peripheral supports only a limited set of * buffer sizes given by the RX buffer entry format in the USB_BTABLE. */ uint16_t blocksize = (size > 62) ? 32 : 2; @@ -180,10 +215,8 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t pcd_aligned_buffer_size(uint16_t si return numblocks * blocksize; } -/* SetENDPOINT */ -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wRegValue) -{ -#ifdef PMA_32BIT_ACCESS +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wRegValue) { +#ifdef FSDEV_BUS_32BIT (void) USBx; __O uint32_t *reg = (__O uint32_t *)(USB_DRD_BASE + bEpIdx*4); *reg = wRegValue; @@ -193,9 +226,8 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, ui #endif } -/* GetENDPOINT */ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx) { -#ifdef PMA_32BIT_ACCESS +#ifdef FSDEV_BUS_32BIT (void) USBx; __I uint32_t *reg = (__I uint32_t *)(USB_DRD_BASE + bEpIdx*4); #else @@ -204,8 +236,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_endpoint(USB_TypeDef * USBx return *reg; } -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_eptype(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wType) -{ +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_eptype(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wType) { uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); regVal &= (uint32_t)USB_EP_T_MASK; regVal |= wType; @@ -213,20 +244,19 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_eptype(USB_TypeDef * USBx, uint pcd_set_endpoint(USBx, bEpIdx, regVal); } -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_eptype(USB_TypeDef * USBx, uint32_t bEpIdx) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_eptype(USB_TypeDef * USBx, uint32_t bEpIdx) { uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); regVal &= USB_EP_T_FIELD; return regVal; } + /** * @brief Clears bit CTR_RX / CTR_TX in the endpoint register. * @param USBx USB peripheral instance register address. * @param bEpIdx Endpoint Number. * @retval None */ -TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_rx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpIdx) -{ +TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_rx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpIdx) { uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); regVal &= USB_EPREG_MASK; regVal &= ~USB_EP_CTR_RX; @@ -234,23 +264,22 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_rx_ep_ctr(USB_TypeDef * USBx, pcd_set_endpoint(USBx, bEpIdx, regVal); } -TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpIdx) -{ +TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpIdx) { uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); regVal &= USB_EPREG_MASK; regVal &= ~USB_EP_CTR_TX; regVal |= USB_EP_CTR_RX; // preserve CTR_RX (clears on writing 0) pcd_set_endpoint(USBx, bEpIdx,regVal); } + /** * @brief gets counter of the tx buffer. * @param USBx USB peripheral instance register address. * @param bEpIdx Endpoint Number. * @retval Counter value */ -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) -{ -#ifdef PMA_32BIT_ACCESS +TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) { +#ifdef FSDEV_BUS_32BIT (void) USBx; return (pma32[2*bEpIdx] & 0x03FF0000) >> 16; #else @@ -259,9 +288,8 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_cnt(USB_TypeDef * USB #endif } -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) -{ -#ifdef PMA_32BIT_ACCESS +TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) { +#ifdef FSDEV_BUS_32BIT (void) USBx; return (pma32[2*bEpIdx + 1] & 0x03FF0000) >> 16; #else @@ -270,6 +298,9 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USB #endif } +#define pcd_get_ep_dbuf0_cnt pcd_get_ep_tx_cnt +#define pcd_get_ep_dbuf1_cnt pcd_get_ep_rx_cnt + /** * @brief Sets address in an endpoint register. * @param USBx USB peripheral instance register address. @@ -277,8 +308,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USB * @param bAddr Address. * @retval None */ -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t bAddr) -{ +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t bAddr) { uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); regVal &= USB_EPREG_MASK; regVal |= bAddr; @@ -286,9 +316,8 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_address(USB_TypeDef * USBx, pcd_set_endpoint(USBx, bEpIdx,regVal); } -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx) -{ -#ifdef PMA_32BIT_ACCESS +TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx) { +#ifdef FSDEV_BUS_32BIT (void) USBx; return pma32[2*bEpIdx] & 0x0000FFFFu ; #else @@ -296,9 +325,8 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_address(USB_TypeDef * #endif } -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx) -{ -#ifdef PMA_32BIT_ACCESS +TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx) { +#ifdef FSDEV_BUS_32BIT (void) USBx; return pma32[2*bEpIdx + 1] & 0x0000FFFFu; #else @@ -306,9 +334,11 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_address(USB_TypeDef * #endif } -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) -{ -#ifdef PMA_32BIT_ACCESS +#define pcd_get_ep_dbuf0_address pcd_get_ep_tx_address +#define pcd_get_ep_dbuf1_address pcd_get_ep_rx_address + +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { +#ifdef FSDEV_BUS_32BIT (void) USBx; pma32[2*bEpIdx] = (pma32[2*bEpIdx] & 0xFFFF0000u) | (addr & 0x0000FFFCu); #else @@ -316,9 +346,8 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_address(USB_TypeDef * USB #endif } -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) -{ -#ifdef PMA_32BIT_ACCESS +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { +#ifdef FSDEV_BUS_32BIT (void) USBx; pma32[2*bEpIdx + 1] = (pma32[2*bEpIdx + 1] & 0xFFFF0000u) | (addr & 0x0000FFFCu); #else @@ -326,9 +355,11 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USB #endif } -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) -{ -#ifdef PMA_32BIT_ACCESS +#define pcd_set_ep_dbuf0_address pcd_set_ep_tx_address +#define pcd_set_ep_dbuf1_address pcd_set_ep_rx_address + +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { +#ifdef FSDEV_BUS_32BIT (void) USBx; pma32[2*bEpIdx] = (pma32[2*bEpIdx] & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16); #else @@ -337,9 +368,10 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, u #endif } -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) -{ -#ifdef PMA_32BIT_ACCESS +#define pcd_set_ep_tx_dbuf0_cnt pcd_set_ep_tx_cnt + +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_dbuf1_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { +#ifdef FSDEV_BUS_32BIT (void) USBx; pma32[2*bEpIdx + 1] = (pma32[2*bEpIdx + 1] & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16); #else @@ -348,10 +380,10 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_cnt(USB_TypeDef * USBx, u #endif } -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_blsize_num_blocks(USB_TypeDef * USBx, uint32_t rxtx_idx, uint32_t blocksize, uint32_t numblocks) -{ +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_blsize_num_blocks(USB_TypeDef * USBx, uint32_t rxtx_idx, + uint32_t blocksize, uint32_t numblocks) { /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ -#ifdef PMA_32BIT_ACCESS +#ifdef FSDEV_BUS_32BIT (void) USBx; pma32[rxtx_idx] = (pma32[rxtx_idx] & 0x0000FFFFu) | (blocksize << 31) | ((numblocks - blocksize) << 26); #else @@ -360,8 +392,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_blsize_num_blocks(USB_TypeDe #endif } -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_bufsize(USB_TypeDef * USBx, uint32_t rxtx_idx, uint32_t wCount) -{ +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_bufsize(USB_TypeDef * USBx, uint32_t rxtx_idx, uint32_t wCount) { wCount = pcd_aligned_buffer_size(wCount); /* We assume that the buffer size is already aligned to hardware requirements. */ @@ -375,16 +406,16 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_bufsize(USB_TypeDef * USBx, pcd_set_ep_blsize_num_blocks(USBx, rxtx_idx, blocksize, numblocks); } -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_bufsize(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) -{ +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_dbuf0_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { pcd_set_ep_bufsize(USBx, 2*bEpIdx, wCount); } -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_bufsize(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) -{ +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { pcd_set_ep_bufsize(USBx, 2*bEpIdx + 1, wCount); } +#define pcd_set_ep_rx_dbuf1_cnt pcd_set_ep_rx_cnt + /** * @brief sets the status for tx transfer (bits STAT_TX[1:0]). * @param USBx USB peripheral instance register address. @@ -392,8 +423,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_bufsize(USB_TypeDef * USB * @param wState new state * @retval None */ -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wState) -{ +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wState) { uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); regVal &= USB_EPTX_DTOGMASK; @@ -410,7 +440,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; pcd_set_endpoint(USBx, bEpIdx, regVal); -} /* pcd_set_ep_tx_status */ +} /** * @brief sets the status for rx transfer (bits STAT_TX[1:0]) @@ -420,31 +450,27 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx * @retval None */ -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wState) -{ +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wState) { uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); regVal &= USB_EPRX_DTOGMASK; /* toggle first bit ? */ - if((USB_EPRX_DTOG1 & wState)!= 0U) - { + if((USB_EPRX_DTOG1 & wState)!= 0U) { regVal ^= USB_EPRX_DTOG1; } /* toggle second bit ? */ - if((USB_EPRX_DTOG2 & wState)!= 0U) - { + if((USB_EPRX_DTOG2 & wState)!= 0U) { regVal ^= USB_EPRX_DTOG2; } regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; pcd_set_endpoint(USBx, bEpIdx, regVal); -} /* pcd_set_ep_rx_status */ +} -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx) { uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); return (regVal & USB_EPRX_STAT) >> (12u); -} /* pcd_get_ep_rx_status */ +} /** @@ -453,16 +479,14 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_status(USB_TypeDef * * @param bEpIdx Endpoint Number. * @retval None */ -TU_ATTR_ALWAYS_INLINE static inline void pcd_rx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) -{ +TU_ATTR_ALWAYS_INLINE static inline void pcd_rx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); regVal &= USB_EPREG_MASK; regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_RX; pcd_set_endpoint(USBx, bEpIdx, regVal); } -TU_ATTR_ALWAYS_INLINE static inline void pcd_tx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) -{ +TU_ATTR_ALWAYS_INLINE static inline void pcd_tx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); regVal &= USB_EPREG_MASK; regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_TX; @@ -475,21 +499,16 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_tx_dtog(USB_TypeDef * USBx, uint32 * @param bEpIdx Endpoint Number. * @retval None */ - -TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_rx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) -{ +TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_rx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - if((regVal & USB_EP_DTOG_RX) != 0) - { + if((regVal & USB_EP_DTOG_RX) != 0) { pcd_rx_dtog(USBx,bEpIdx); } } -TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) -{ +TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - if((regVal & USB_EP_DTOG_TX) != 0) - { + if((regVal & USB_EP_DTOG_TX) != 0) { pcd_tx_dtog(USBx,bEpIdx); } } @@ -500,17 +519,15 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_dtog(USB_TypeDef * USBx, * @param bEpIdx Endpoint Number. * @retval None */ - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) -{ +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) { uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); regVal |= USB_EP_KIND; regVal &= USB_EPREG_MASK; regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; pcd_set_endpoint(USBx, bEpIdx, regVal); } -TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) -{ + +TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) { uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); regVal &= USB_EPKIND_MASK; regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c deleted file mode 100644 index 2fc3adb4f..000000000 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ /dev/null @@ -1,1240 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2018 Scott Shawcroft, 2019 William D. Jones for Adafruit Industries - * Copyright (c) 2019 Ha Thach (tinyusb.org) - * Copyright (c) 2020 Jan Duempelmann - * Copyright (c) 2020 Reinhard Panhuber - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#include "tusb_option.h" - -// Since TinyUSB doesn't use SOF for now, and this interrupt too often (1ms interval) -// We disable SOF for now until needed later on -#define USE_SOF 0 - -#if defined (STM32F105x8) || defined (STM32F105xB) || defined (STM32F105xC) || \ - defined (STM32F107xB) || defined (STM32F107xC) -#define STM32F1_SYNOPSYS -#endif - -#if defined (STM32L475xx) || defined (STM32L476xx) || \ - defined (STM32L485xx) || defined (STM32L486xx) || defined (STM32L496xx) || \ - defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || \ - defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx) -#define STM32L4_SYNOPSYS -#endif - -#if CFG_TUD_ENABLED && \ - ( (CFG_TUSB_MCU == OPT_MCU_STM32F1 && defined(STM32F1_SYNOPSYS)) || \ - CFG_TUSB_MCU == OPT_MCU_STM32F2 || \ - CFG_TUSB_MCU == OPT_MCU_STM32F4 || \ - CFG_TUSB_MCU == OPT_MCU_STM32F7 || \ - CFG_TUSB_MCU == OPT_MCU_STM32H7 || \ - (CFG_TUSB_MCU == OPT_MCU_STM32L4 && defined(STM32L4_SYNOPSYS) || \ - CFG_TUSB_MCU == OPT_MCU_GD32VF103 ) \ - ) - -// EP_MAX : Max number of bi-directional endpoints including EP0 -// EP_FIFO_SIZE : Size of dedicated USB SRAM -#if CFG_TUSB_MCU == OPT_MCU_STM32F1 -#include "stm32f1xx.h" -#define EP_MAX_FS 4 -#define EP_FIFO_SIZE_FS 1280 - -#elif CFG_TUSB_MCU == OPT_MCU_STM32F2 -#include "stm32f2xx.h" -#define EP_MAX_FS USB_OTG_FS_MAX_IN_ENDPOINTS -#define EP_FIFO_SIZE_FS USB_OTG_FS_TOTAL_FIFO_SIZE - -#elif CFG_TUSB_MCU == OPT_MCU_STM32F4 -#include "stm32f4xx.h" -#define EP_MAX_FS USB_OTG_FS_MAX_IN_ENDPOINTS -#define EP_FIFO_SIZE_FS USB_OTG_FS_TOTAL_FIFO_SIZE -#define EP_MAX_HS USB_OTG_HS_MAX_IN_ENDPOINTS -#define EP_FIFO_SIZE_HS USB_OTG_HS_TOTAL_FIFO_SIZE - -#elif CFG_TUSB_MCU == OPT_MCU_STM32H7 -#include "stm32h7xx.h" -#define EP_MAX_FS 9 -#define EP_FIFO_SIZE_FS 4096 -#define EP_MAX_HS 9 -#define EP_FIFO_SIZE_HS 4096 - -#elif CFG_TUSB_MCU == OPT_MCU_STM32F7 -#include "stm32f7xx.h" -#define EP_MAX_FS 6 -#define EP_FIFO_SIZE_FS 1280 -#define EP_MAX_HS 9 -#define EP_FIFO_SIZE_HS 4096 - -#elif CFG_TUSB_MCU == OPT_MCU_STM32L4 -#include "stm32l4xx.h" -#define EP_MAX_FS 6 -#define EP_FIFO_SIZE_FS 1280 - -#elif CFG_TUSB_MCU == OPT_MCU_GD32VF103 -#include "synopsys_common.h" - -// for remote wakeup delay -#define __NOP() __asm volatile ("nop") - -// These numbers are the same for the whole GD32VF103 family. -#define OTG_FS_IRQn 86 -#define EP_MAX_FS 4 -#define EP_FIFO_SIZE_FS 1280 - -// The GD32VF103 is a RISC-V MCU, which implements the ECLIC Core-Local -// Interrupt Controller by Nuclei. It is nearly API compatible to the -// NVIC used by ARM MCUs. -#define ECLIC_INTERRUPT_ENABLE_BASE 0xD2001001UL - -#define NVIC_EnableIRQ __eclic_enable_interrupt -#define NVIC_DisableIRQ __eclic_disable_interrupt - -static inline void __eclic_enable_interrupt (uint32_t irq) { - *(volatile uint8_t*)(ECLIC_INTERRUPT_ENABLE_BASE + (irq * 4)) = 1; -} - -static inline void __eclic_disable_interrupt (uint32_t irq){ - *(volatile uint8_t*)(ECLIC_INTERRUPT_ENABLE_BASE + (irq * 4)) = 0; -} - -#else -#error "Unsupported MCUs" -#endif - -#include "device/dcd.h" - -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM -//--------------------------------------------------------------------+ - -// On STM32 we associate Port0 to OTG_FS, and Port1 to OTG_HS -#if TUD_OPT_RHPORT == 0 -#define EP_MAX EP_MAX_FS -#define EP_FIFO_SIZE EP_FIFO_SIZE_FS -#define RHPORT_REGS_BASE USB_OTG_FS_PERIPH_BASE -#define RHPORT_IRQn OTG_FS_IRQn - -#else -#define EP_MAX EP_MAX_HS -#define EP_FIFO_SIZE EP_FIFO_SIZE_HS -#define RHPORT_REGS_BASE USB_OTG_HS_PERIPH_BASE -#define RHPORT_IRQn OTG_HS_IRQn - -#endif - -#define GLOBAL_BASE(_port) ((USB_OTG_GlobalTypeDef*) RHPORT_REGS_BASE) -#define DEVICE_BASE(_port) (USB_OTG_DeviceTypeDef *) (RHPORT_REGS_BASE + USB_OTG_DEVICE_BASE) -#define OUT_EP_BASE(_port) (USB_OTG_OUTEndpointTypeDef *) (RHPORT_REGS_BASE + USB_OTG_OUT_ENDPOINT_BASE) -#define IN_EP_BASE(_port) (USB_OTG_INEndpointTypeDef *) (RHPORT_REGS_BASE + USB_OTG_IN_ENDPOINT_BASE) -#define FIFO_BASE(_port, _x) ((volatile uint32_t *) (RHPORT_REGS_BASE + USB_OTG_FIFO_BASE + (_x) * USB_OTG_FIFO_SIZE)) - -enum -{ - DCD_HIGH_SPEED = 0, // Highspeed mode - DCD_FULL_SPEED_USE_HS = 1, // Full speed in Highspeed port (probably with internal PHY) - DCD_FULL_SPEED = 3, // Full speed with internal PHY -}; - -static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[2]; - -typedef struct { - uint8_t * buffer; - tu_fifo_t * ff; - uint16_t total_len; - uint16_t max_size; - uint8_t interval; -} xfer_ctl_t; - -typedef volatile uint32_t * usb_fifo_t; - -xfer_ctl_t xfer_status[EP_MAX][2]; -#define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir] - -// EP0 transfers are limited to 1 packet - larger sizes has to be split -static uint16_t ep0_pending[2]; // Index determines direction as tusb_dir_t type - -// TX FIFO RAM allocation so far in words - RX FIFO size is readily available from usb_otg->GRXFSIZ -static uint16_t _allocated_fifo_words_tx; // TX FIFO size in words (IN EPs) -static bool _out_ep_closed; // Flag to check if RX FIFO size needs an update (reduce its size) - -// Calculate the RX FIFO size according to recommendations from reference manual -static inline uint16_t calc_rx_ff_size(uint16_t ep_size) -{ - return 15 + 2*(ep_size/4) + 2*EP_MAX; -} - -static void update_grxfsiz(uint8_t rhport) -{ - (void) rhport; - - USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); - - // Determine largest EP size for RX FIFO - uint16_t max_epsize = 0; - for (uint8_t epnum = 0; epnum < EP_MAX; epnum++) - { - max_epsize = tu_max16(max_epsize, xfer_status[epnum][TUSB_DIR_OUT].max_size); - } - - // Update size of RX FIFO - usb_otg->GRXFSIZ = calc_rx_ff_size(max_epsize); -} - -// Setup the control endpoint 0. -static void bus_reset(uint8_t rhport) -{ - (void) rhport; - - USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); - USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); - USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); - - tu_memclr(xfer_status, sizeof(xfer_status)); - _out_ep_closed = false; - - // clear device address - dev->DCFG &= ~USB_OTG_DCFG_DAD_Msk; - - // 1. NAK for all OUT endpoints - for(uint8_t n = 0; n < EP_MAX; n++) { - out_ep[n].DOEPCTL |= USB_OTG_DOEPCTL_SNAK; - } - - // 2. Un-mask interrupt bits - dev->DAINTMSK = (1 << USB_OTG_DAINTMSK_OEPM_Pos) | (1 << USB_OTG_DAINTMSK_IEPM_Pos); - dev->DOEPMSK = USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM; - dev->DIEPMSK = USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM; - - // "USB Data FIFOs" section in reference manual - // Peripheral FIFO architecture - // - // The FIFO is split up in a lower part where the RX FIFO is located and an upper part where the TX FIFOs start. - // We do this to allow the RX FIFO to grow dynamically which is possible since the free space is located - // between the RX and TX FIFOs. This is required by ISO OUT EPs which need a bigger FIFO than the standard - // configuration done below. - // - // Dynamically FIFO sizes are of interest only for ISO EPs since all others are usually not opened and closed. - // All EPs other than ISO are opened as soon as the driver starts up i.e. when the host sends a - // configure interface command. Hence, all IN EPs other the ISO will be located at the top. IN ISO EPs are usually - // opened when the host sends an additional command: setInterface. At this point in time - // the ISO EP will be located next to the free space and can change its size. In case more IN EPs change its size - // an additional memory - // - // --------------- 320 or 1024 ( 1280 or 4096 bytes ) - // | IN FIFO 0 | - // --------------- (320 or 1024) - 16 - // | IN FIFO 1 | - // --------------- (320 or 1024) - 16 - x - // | . . . . | - // --------------- (320 or 1024) - 16 - x - y - ... - z - // | IN FIFO MAX | - // --------------- - // | FREE | - // --------------- GRXFSIZ - // | OUT FIFO | - // | ( Shared ) | - // --------------- 0 - // - // According to "FIFO RAM allocation" section in RM, FIFO RAM are allocated as follows (each word 32-bits): - // - Each EP IN needs at least max packet size, 16 words is sufficient for EP0 IN - // - // - All EP OUT shared a unique OUT FIFO which uses - // - 13 for setup packets + control words (up to 3 setup packets). - // - 1 for global NAK (not required/used here). - // - Largest-EPsize / 4 + 1. ( FS: 64 bytes, HS: 512 bytes). Recommended is "2 x (Largest-EPsize/4) + 1" - // - 2 for each used OUT endpoint - // - // Therefore GRXFSIZ = 13 + 1 + 1 + 2 x (Largest-EPsize/4) + 2 x EPOUTnum - // - FullSpeed (64 Bytes ): GRXFSIZ = 15 + 2 x 16 + 2 x EP_MAX = 47 + 2 x EP_MAX - // - Highspeed (512 bytes): GRXFSIZ = 15 + 2 x 128 + 2 x EP_MAX = 271 + 2 x EP_MAX - // - // NOTE: Largest-EPsize & EPOUTnum is actual used endpoints in configuration. Since DCD has no knowledge - // of the overall picture yet. We will use the worst scenario: largest possible + EP_MAX - // - // For Isochronous, largest EP size can be 1023/1024 for FS/HS respectively. In addition if multiple ISO - // are enabled at least "2 x (Largest-EPsize/4) + 1" are recommended. Maybe provide a macro for application to - // overwrite this. - - usb_otg->GRXFSIZ = calc_rx_ff_size(TUD_OPT_HIGH_SPEED ? 512 : 64); - - _allocated_fifo_words_tx = 16; - - // Control IN uses FIFO 0 with 64 bytes ( 16 32-bit word ) - usb_otg->DIEPTXF0_HNPTXFSIZ = (16 << USB_OTG_TX0FD_Pos) | (EP_FIFO_SIZE/4 - _allocated_fifo_words_tx); - - // Fixed control EP0 size to 64 bytes - in_ep[0].DIEPCTL &= ~(0x03 << USB_OTG_DIEPCTL_MPSIZ_Pos); - xfer_status[0][TUSB_DIR_OUT].max_size = xfer_status[0][TUSB_DIR_IN].max_size = 64; - - out_ep[0].DOEPTSIZ |= (3 << USB_OTG_DOEPTSIZ_STUPCNT_Pos); - - usb_otg->GINTMSK |= USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IEPINT; -} - -// Set turn-around timeout according to link speed -extern uint32_t SystemCoreClock; -static void set_turnaround(USB_OTG_GlobalTypeDef * usb_otg, tusb_speed_t speed) -{ - usb_otg->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT; - - if ( speed == TUSB_SPEED_HIGH ) - { - // Use fixed 0x09 for Highspeed - usb_otg->GUSBCFG |= (0x09 << USB_OTG_GUSBCFG_TRDT_Pos); - } - else - { - // Turnaround timeout depends on the MCU clock - uint32_t turnaround; - - if ( SystemCoreClock >= 32000000U ) - turnaround = 0x6U; - else if ( SystemCoreClock >= 27500000U ) - turnaround = 0x7U; - else if ( SystemCoreClock >= 24000000U ) - turnaround = 0x8U; - else if ( SystemCoreClock >= 21800000U ) - turnaround = 0x9U; - else if ( SystemCoreClock >= 20000000U ) - turnaround = 0xAU; - else if ( SystemCoreClock >= 18500000U ) - turnaround = 0xBU; - else if ( SystemCoreClock >= 17200000U ) - turnaround = 0xCU; - else if ( SystemCoreClock >= 16000000U ) - turnaround = 0xDU; - else if ( SystemCoreClock >= 15000000U ) - turnaround = 0xEU; - else - turnaround = 0xFU; - - // Fullspeed depends on MCU clocks, but we will use 0x06 for 32+ Mhz - usb_otg->GUSBCFG |= (turnaround << USB_OTG_GUSBCFG_TRDT_Pos); - } -} - -static tusb_speed_t get_speed(uint8_t rhport) -{ - (void) rhport; - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); - uint32_t const enum_spd = (dev->DSTS & USB_OTG_DSTS_ENUMSPD_Msk) >> USB_OTG_DSTS_ENUMSPD_Pos; - return (enum_spd == DCD_HIGH_SPEED) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL; -} - -static void set_speed(uint8_t rhport, tusb_speed_t speed) -{ - uint32_t bitvalue; - - if ( rhport == 1 ) - { - bitvalue = ((TUSB_SPEED_HIGH == speed) ? DCD_HIGH_SPEED : DCD_FULL_SPEED_USE_HS); - } - else - { - bitvalue = DCD_FULL_SPEED; - } - - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); - - // Clear and set speed bits - dev->DCFG &= ~(3 << USB_OTG_DCFG_DSPD_Pos); - dev->DCFG |= (bitvalue << USB_OTG_DCFG_DSPD_Pos); -} - -#if defined(USB_HS_PHYC) -static bool USB_HS_PHYCInit(void) -{ - USB_HS_PHYC_GlobalTypeDef *usb_hs_phyc = (USB_HS_PHYC_GlobalTypeDef*) USB_HS_PHYC_CONTROLLER_BASE; - - // Enable LDO: Note STM32F72/3xx Reference Manual rev 3 June 2018 incorrectly defined this bit as Disabled !! - usb_hs_phyc->USB_HS_PHYC_LDO |= USB_HS_PHYC_LDO_ENABLE; - - // Wait until LDO ready - while ( 0 == (usb_hs_phyc->USB_HS_PHYC_LDO & USB_HS_PHYC_LDO_STATUS) ) {} - - uint32_t phyc_pll = 0; - - // TODO Try to get HSE_VALUE from registers instead of depending CFLAGS - switch ( HSE_VALUE ) - { - case 12000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_12MHZ ; break; - case 12500000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_12_5MHZ ; break; - case 16000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_16MHZ ; break; - case 24000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_24MHZ ; break; - case 25000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_25MHZ ; break; - case 32000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_Msk ; break; // Value not defined in header - default: - TU_ASSERT(0); - } - usb_hs_phyc->USB_HS_PHYC_PLL = phyc_pll; - - // Control the tuning interface of the High Speed PHY - // Use magic value (USB_HS_PHYC_TUNE_VALUE) from ST driver - usb_hs_phyc->USB_HS_PHYC_TUNE |= 0x00000F13U; - - // Enable PLL internal PHY - usb_hs_phyc->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL_PLLEN; - - // Original ST code has 2 ms delay for PLL stabilization. - // Primitive test shows that more than 10 USB un/replug cycle showed no error with enumeration - - return true; -} -#endif - -static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t const dir, uint16_t const num_packets, uint16_t total_bytes) -{ - (void) rhport; - - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); - USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); - USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); - - // EP0 is limited to one packet each xfer - // We use multiple transaction of xfer->max_size length to get a whole transfer done - if(epnum == 0) { - xfer_ctl_t * const xfer = XFER_CTL_BASE(epnum, dir); - total_bytes = tu_min16(ep0_pending[dir], xfer->max_size); - ep0_pending[dir] -= total_bytes; - } - - // IN and OUT endpoint xfers are interrupt-driven, we just schedule them here. - if(dir == TUSB_DIR_IN) { - // A full IN transfer (multiple packets, possibly) triggers XFRC. - in_ep[epnum].DIEPTSIZ = (num_packets << USB_OTG_DIEPTSIZ_PKTCNT_Pos) | - ((total_bytes << USB_OTG_DIEPTSIZ_XFRSIZ_Pos) & USB_OTG_DIEPTSIZ_XFRSIZ_Msk); - - in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_EPENA | USB_OTG_DIEPCTL_CNAK; - // For ISO endpoint set correct odd/even bit for next frame. - if ((in_ep[epnum].DIEPCTL & USB_OTG_DIEPCTL_EPTYP) == USB_OTG_DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) - { - // Take odd/even bit from frame counter. - uint32_t const odd_frame_now = (dev->DSTS & (1u << USB_OTG_DSTS_FNSOF_Pos)); - in_ep[epnum].DIEPCTL |= (odd_frame_now ? USB_OTG_DIEPCTL_SD0PID_SEVNFRM_Msk : USB_OTG_DIEPCTL_SODDFRM_Msk); - } - // Enable fifo empty interrupt only if there are something to put in the fifo. - if(total_bytes != 0) { - dev->DIEPEMPMSK |= (1 << epnum); - } - } else { - // A full OUT transfer (multiple packets, possibly) triggers XFRC. - out_ep[epnum].DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT_Msk | USB_OTG_DOEPTSIZ_XFRSIZ); - out_ep[epnum].DOEPTSIZ |= (num_packets << USB_OTG_DOEPTSIZ_PKTCNT_Pos) | - ((total_bytes << USB_OTG_DOEPTSIZ_XFRSIZ_Pos) & USB_OTG_DOEPTSIZ_XFRSIZ_Msk); - - out_ep[epnum].DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK; - if ((out_ep[epnum].DOEPCTL & USB_OTG_DOEPCTL_EPTYP) == USB_OTG_DOEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) - { - // Take odd/even bit from frame counter. - uint32_t const odd_frame_now = (dev->DSTS & (1u << USB_OTG_DSTS_FNSOF_Pos)); - out_ep[epnum].DOEPCTL |= (odd_frame_now ? USB_OTG_DOEPCTL_SD0PID_SEVNFRM_Msk : USB_OTG_DOEPCTL_SODDFRM_Msk); - } - } -} - -/*------------------------------------------------------------------*/ -/* Controller API - *------------------------------------------------------------------*/ -void dcd_init (uint8_t rhport) -{ - // Programming model begins in the last section of the chapter on the USB - // peripheral in each Reference Manual. - - USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); - - // No HNP/SRP (no OTG support), program timeout later. - if ( rhport == 1 ) - { - // On selected MCUs HS port1 can be used with external PHY via ULPI interface -#if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HIGH_SPEED - // deactivate internal PHY - usb_otg->GCCFG &= ~USB_OTG_GCCFG_PWRDWN; - - // Init The UTMI Interface - usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL); - - // Select default internal VBUS Indicator and Drive for ULPI - usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI); -#else - usb_otg->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL; -#endif - -#if defined(USB_HS_PHYC) - // Highspeed with embedded UTMI PHYC - - // Select UTMI Interface - usb_otg->GUSBCFG &= ~USB_OTG_GUSBCFG_ULPI_UTMI_SEL; - usb_otg->GCCFG |= USB_OTG_GCCFG_PHYHSEN; - - // Enables control of a High Speed USB PHY - USB_HS_PHYCInit(); -#endif - } else - { - // Enable internal PHY - usb_otg->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL; - } - - // Reset core after selecting PHY - // Wait AHB IDLE, reset then wait until it is cleared - while ((usb_otg->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U) {} - usb_otg->GRSTCTL |= USB_OTG_GRSTCTL_CSRST; - while ((usb_otg->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST) {} - - // Restart PHY clock - *((volatile uint32_t *)(RHPORT_REGS_BASE + USB_OTG_PCGCCTL_BASE)) = 0; - - // Clear all interrupts - usb_otg->GINTSTS |= usb_otg->GINTSTS; - - // Required as part of core initialization. - // TODO: How should mode mismatch be handled? It will cause - // the core to stop working/require reset. - usb_otg->GINTMSK |= USB_OTG_GINTMSK_OTGINT | USB_OTG_GINTMSK_MMISM; - - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); - - // If USB host misbehaves during status portion of control xfer - // (non zero-length packet), send STALL back and discard. - dev->DCFG |= USB_OTG_DCFG_NZLSOHSK; - - set_speed(rhport, TUD_OPT_HIGH_SPEED ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL); - - // Enable internal USB transceiver, unless using HS core (port 1) with external PHY. - if (!(rhport == 1 && (CFG_TUSB_RHPORT1_MODE & OPT_MODE_HIGH_SPEED))) usb_otg->GCCFG |= USB_OTG_GCCFG_PWRDWN; - - usb_otg->GINTMSK |= USB_OTG_GINTMSK_USBRST | USB_OTG_GINTMSK_ENUMDNEM | - USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_WUIM | - USB_OTG_GINTMSK_RXFLVLM | (USE_SOF ? USB_OTG_GINTMSK_SOFM : 0); - - // Enable global interrupt - usb_otg->GAHBCFG |= USB_OTG_GAHBCFG_GINT; - - dcd_connect(rhport); -} - -void dcd_int_enable (uint8_t rhport) -{ - (void) rhport; - NVIC_EnableIRQ(RHPORT_IRQn); -} - -void dcd_int_disable (uint8_t rhport) -{ - (void) rhport; - NVIC_DisableIRQ(RHPORT_IRQn); -} - -void dcd_set_address (uint8_t rhport, uint8_t dev_addr) -{ - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); - dev->DCFG = (dev->DCFG & ~USB_OTG_DCFG_DAD_Msk) | (dev_addr << USB_OTG_DCFG_DAD_Pos); - - // Response with status after changing device address - dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); -} - -static void remote_wakeup_delay(void) -{ - // try to delay for 1 ms - uint32_t count = SystemCoreClock / 1000; - while ( count-- ) - { - __NOP(); - } -} - -void dcd_remote_wakeup(uint8_t rhport) -{ - (void) rhport; - - USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); - - // set remote wakeup - dev->DCTL |= USB_OTG_DCTL_RWUSIG; - - // enable SOF to detect bus resume - usb_otg->GINTSTS = USB_OTG_GINTSTS_SOF; - usb_otg->GINTMSK |= USB_OTG_GINTMSK_SOFM; - - // Per specs: remote wakeup signal bit must be clear within 1-15ms - remote_wakeup_delay(); - - dev->DCTL &= ~USB_OTG_DCTL_RWUSIG; -} - -void dcd_connect(uint8_t rhport) -{ - (void) rhport; - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); - dev->DCTL &= ~USB_OTG_DCTL_SDIS; -} - -void dcd_disconnect(uint8_t rhport) -{ - (void) rhport; - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); - dev->DCTL |= USB_OTG_DCTL_SDIS; -} - -void dcd_sof_enable(uint8_t rhport, bool en) -{ - (void) rhport; - (void) en; - - // TODO implement later -} - -/*------------------------------------------------------------------*/ -/* DCD Endpoint port - *------------------------------------------------------------------*/ - -bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) -{ - (void) rhport; - - USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); - USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); - USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); - - uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); - uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); - - TU_ASSERT(epnum < EP_MAX); - - xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); - xfer->max_size = tu_edpt_packet_size(desc_edpt); - xfer->interval = desc_edpt->bInterval; - - uint16_t const fifo_size = (xfer->max_size + 3) / 4; // Round up to next full word - - if(dir == TUSB_DIR_OUT) - { - // Calculate required size of RX FIFO - uint16_t const sz = calc_rx_ff_size(4*fifo_size); - - // If size_rx needs to be extended check if possible and if so enlarge it - if (usb_otg->GRXFSIZ < sz) - { - TU_ASSERT(sz + _allocated_fifo_words_tx <= EP_FIFO_SIZE/4); - - // Enlarge RX FIFO - usb_otg->GRXFSIZ = sz; - } - - out_ep[epnum].DOEPCTL |= (1 << USB_OTG_DOEPCTL_USBAEP_Pos) | - (desc_edpt->bmAttributes.xfer << USB_OTG_DOEPCTL_EPTYP_Pos) | - (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? USB_OTG_DOEPCTL_SD0PID_SEVNFRM : 0) | - (xfer->max_size << USB_OTG_DOEPCTL_MPSIZ_Pos); - - dev->DAINTMSK |= (1 << (USB_OTG_DAINTMSK_OEPM_Pos + epnum)); - } - else - { - // "USB Data FIFOs" section in reference manual - // Peripheral FIFO architecture - // - // --------------- 320 or 1024 ( 1280 or 4096 bytes ) - // | IN FIFO 0 | - // --------------- (320 or 1024) - 16 - // | IN FIFO 1 | - // --------------- (320 or 1024) - 16 - x - // | . . . . | - // --------------- (320 or 1024) - 16 - x - y - ... - z - // | IN FIFO MAX | - // --------------- - // | FREE | - // --------------- GRXFSIZ - // | OUT FIFO | - // | ( Shared ) | - // --------------- 0 - // - // In FIFO is allocated by following rules: - // - IN EP 1 gets FIFO 1, IN EP "n" gets FIFO "n". - - // Check if free space is available - TU_ASSERT(_allocated_fifo_words_tx + fifo_size + usb_otg->GRXFSIZ <= EP_FIFO_SIZE/4); - - _allocated_fifo_words_tx += fifo_size; - - TU_LOG(2, " Allocated %u bytes at offset %u", fifo_size*4, EP_FIFO_SIZE-_allocated_fifo_words_tx*4); - - // DIEPTXF starts at FIFO #1. - // Both TXFD and TXSA are in unit of 32-bit words. - usb_otg->DIEPTXF[epnum - 1] = (fifo_size << USB_OTG_DIEPTXF_INEPTXFD_Pos) | (EP_FIFO_SIZE/4 - _allocated_fifo_words_tx); - - in_ep[epnum].DIEPCTL |= (1 << USB_OTG_DIEPCTL_USBAEP_Pos) | - (epnum << USB_OTG_DIEPCTL_TXFNUM_Pos) | - (desc_edpt->bmAttributes.xfer << USB_OTG_DIEPCTL_EPTYP_Pos) | - (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? USB_OTG_DIEPCTL_SD0PID_SEVNFRM : 0) | - (xfer->max_size << USB_OTG_DIEPCTL_MPSIZ_Pos); - - dev->DAINTMSK |= (1 << (USB_OTG_DAINTMSK_IEPM_Pos + epnum)); - } - - return true; -} - -// Close all non-control endpoints, cancel all pending transfers if any. -void dcd_edpt_close_all (uint8_t rhport) -{ - (void) rhport; - -// USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); - USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); - USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); - - // Disable non-control interrupt - dev->DAINTMSK = (1 << USB_OTG_DAINTMSK_OEPM_Pos) | (1 << USB_OTG_DAINTMSK_IEPM_Pos); - - for(uint8_t n = 1; n < EP_MAX; n++) - { - // disable OUT endpoint - out_ep[n].DOEPCTL = 0; - xfer_status[n][TUSB_DIR_OUT].max_size = 0; - - // disable IN endpoint - in_ep[n].DIEPCTL = 0; - xfer_status[n][TUSB_DIR_IN].max_size = 0; - } - - // reset allocated fifo IN - _allocated_fifo_words_tx = 16; -} - -bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) -{ - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); - xfer->buffer = buffer; - xfer->ff = NULL; - xfer->total_len = total_bytes; - - // EP0 can only handle one packet - if(epnum == 0) { - ep0_pending[dir] = total_bytes; - // Schedule the first transaction for EP0 transfer - edpt_schedule_packets(rhport, epnum, dir, 1, ep0_pending[dir]); - return true; - } - - uint16_t num_packets = (total_bytes / xfer->max_size); - uint16_t const short_packet_size = total_bytes % xfer->max_size; - - // Zero-size packet is special case. - if(short_packet_size > 0 || (total_bytes == 0)) { - num_packets++; - } - - // Schedule packets to be sent within interrupt - edpt_schedule_packets(rhport, epnum, dir, num_packets, total_bytes); - - return true; -} - -// The number of bytes has to be given explicitly to allow more flexible control of how many -// bytes should be written and second to keep the return value free to give back a boolean -// success message. If total_bytes is too big, the FIFO will copy only what is available -// into the USB buffer! -bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) -{ - // USB buffers always work in bytes so to avoid unnecessary divisions we demand item_size = 1 - TU_ASSERT(ff->item_size == 1); - - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); - xfer->buffer = NULL; - xfer->ff = ff; - xfer->total_len = total_bytes; - - uint16_t num_packets = (total_bytes / xfer->max_size); - uint16_t const short_packet_size = total_bytes % xfer->max_size; - - // Zero-size packet is special case. - if(short_packet_size > 0 || (total_bytes == 0)) num_packets++; - - // Schedule packets to be sent within interrupt - edpt_schedule_packets(rhport, epnum, dir, num_packets, total_bytes); - - return true; -} - -static void dcd_edpt_disable (uint8_t rhport, uint8_t ep_addr, bool stall) -{ - (void) rhport; - - USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); - USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); - USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); - - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - if(dir == TUSB_DIR_IN) { - // Only disable currently enabled non-control endpoint - if ( (epnum == 0) || !(in_ep[epnum].DIEPCTL & USB_OTG_DIEPCTL_EPENA) ){ - in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_SNAK | (stall ? USB_OTG_DIEPCTL_STALL : 0); - } else { - // Stop transmitting packets and NAK IN xfers. - in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_SNAK; - while((in_ep[epnum].DIEPINT & USB_OTG_DIEPINT_INEPNE) == 0); - - // Disable the endpoint. - in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_EPDIS | (stall ? USB_OTG_DIEPCTL_STALL : 0); - while((in_ep[epnum].DIEPINT & USB_OTG_DIEPINT_EPDISD_Msk) == 0); - in_ep[epnum].DIEPINT = USB_OTG_DIEPINT_EPDISD; - } - - // Flush the FIFO, and wait until we have confirmed it cleared. - usb_otg->GRSTCTL |= (epnum << USB_OTG_GRSTCTL_TXFNUM_Pos); - usb_otg->GRSTCTL |= USB_OTG_GRSTCTL_TXFFLSH; - while((usb_otg->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH_Msk) != 0); - } else { - // Only disable currently enabled non-control endpoint - if ( (epnum == 0) || !(out_ep[epnum].DOEPCTL & USB_OTG_DOEPCTL_EPENA) ){ - out_ep[epnum].DOEPCTL |= stall ? USB_OTG_DOEPCTL_STALL : 0; - } else { - // Asserting GONAK is required to STALL an OUT endpoint. - // Simpler to use polling here, we don't use the "B"OUTNAKEFF interrupt - // anyway, and it can't be cleared by user code. If this while loop never - // finishes, we have bigger problems than just the stack. - dev->DCTL |= USB_OTG_DCTL_SGONAK; - while((usb_otg->GINTSTS & USB_OTG_GINTSTS_BOUTNAKEFF_Msk) == 0); - - // Ditto here- disable the endpoint. - out_ep[epnum].DOEPCTL |= USB_OTG_DOEPCTL_EPDIS | (stall ? USB_OTG_DOEPCTL_STALL : 0); - while((out_ep[epnum].DOEPINT & USB_OTG_DOEPINT_EPDISD_Msk) == 0); - out_ep[epnum].DOEPINT = USB_OTG_DOEPINT_EPDISD; - - // Allow other OUT endpoints to keep receiving. - dev->DCTL |= USB_OTG_DCTL_CGONAK; - } - } -} - -/** - * Close an endpoint. - */ -void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) -{ - USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); - - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - dcd_edpt_disable(rhport, ep_addr, false); - - // Update max_size - xfer_status[epnum][dir].max_size = 0; // max_size = 0 marks a disabled EP - required for changing FIFO allocation - - if (dir == TUSB_DIR_IN) - { - uint16_t const fifo_size = (usb_otg->DIEPTXF[epnum - 1] & USB_OTG_DIEPTXF_INEPTXFD_Msk) >> USB_OTG_DIEPTXF_INEPTXFD_Pos; - uint16_t const fifo_start = (usb_otg->DIEPTXF[epnum - 1] & USB_OTG_DIEPTXF_INEPTXSA_Msk) >> USB_OTG_DIEPTXF_INEPTXSA_Pos; - // For now only the last opened endpoint can be closed without fuss. - TU_ASSERT(fifo_start == EP_FIFO_SIZE/4 - _allocated_fifo_words_tx,); - _allocated_fifo_words_tx -= fifo_size; - } - else - { - _out_ep_closed = true; // Set flag such that RX FIFO gets reduced in size once RX FIFO is empty - } -} - -void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) -{ - dcd_edpt_disable(rhport, ep_addr, true); -} - -void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) -{ - (void) rhport; - - USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); - USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); - - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - // Clear stall and reset data toggle - if(dir == TUSB_DIR_IN) { - in_ep[epnum].DIEPCTL &= ~USB_OTG_DIEPCTL_STALL; - in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; - } else { - out_ep[epnum].DOEPCTL &= ~USB_OTG_DOEPCTL_STALL; - out_ep[epnum].DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; - } -} - -/*------------------------------------------------------------------*/ - -// Read a single data packet from receive FIFO -static void read_fifo_packet(uint8_t rhport, uint8_t * dst, uint16_t len) -{ - (void) rhport; - - usb_fifo_t rx_fifo = FIFO_BASE(rhport, 0); - - // Reading full available 32 bit words from fifo - uint16_t full_words = len >> 2; - for(uint16_t i = 0; i < full_words; i++) { - uint32_t tmp = *rx_fifo; - dst[0] = tmp & 0x000000FF; - dst[1] = (tmp & 0x0000FF00) >> 8; - dst[2] = (tmp & 0x00FF0000) >> 16; - dst[3] = (tmp & 0xFF000000) >> 24; - dst += 4; - } - - // Read the remaining 1-3 bytes from fifo - uint8_t bytes_rem = len & 0x03; - if(bytes_rem != 0) { - uint32_t tmp = *rx_fifo; - dst[0] = tmp & 0x000000FF; - if(bytes_rem > 1) { - dst[1] = (tmp & 0x0000FF00) >> 8; - } - if(bytes_rem > 2) { - dst[2] = (tmp & 0x00FF0000) >> 16; - } - } -} - -// Write a single data packet to EPIN FIFO -static void write_fifo_packet(uint8_t rhport, uint8_t fifo_num, uint8_t * src, uint16_t len) -{ - (void) rhport; - - usb_fifo_t tx_fifo = FIFO_BASE(rhport, fifo_num); - - // Pushing full available 32 bit words to fifo - uint16_t full_words = len >> 2; - for(uint16_t i = 0; i < full_words; i++){ - *tx_fifo = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0]; - src += 4; - } - - // Write the remaining 1-3 bytes into fifo - uint8_t bytes_rem = len & 0x03; - if(bytes_rem){ - uint32_t tmp_word = 0; - tmp_word |= src[0]; - if(bytes_rem > 1){ - tmp_word |= src[1] << 8; - } - if(bytes_rem > 2){ - tmp_word |= src[2] << 16; - } - *tx_fifo = tmp_word; - } -} - -static void handle_rxflvl_ints(uint8_t rhport, USB_OTG_OUTEndpointTypeDef * out_ep) { - USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); - usb_fifo_t rx_fifo = FIFO_BASE(rhport, 0); - - // Pop control word off FIFO - uint32_t ctl_word = usb_otg->GRXSTSP; - uint8_t pktsts = (ctl_word & USB_OTG_GRXSTSP_PKTSTS_Msk) >> USB_OTG_GRXSTSP_PKTSTS_Pos; - uint8_t epnum = (ctl_word & USB_OTG_GRXSTSP_EPNUM_Msk) >> USB_OTG_GRXSTSP_EPNUM_Pos; - uint16_t bcnt = (ctl_word & USB_OTG_GRXSTSP_BCNT_Msk) >> USB_OTG_GRXSTSP_BCNT_Pos; - - switch(pktsts) { - case 0x01: // Global OUT NAK (Interrupt) - break; - - case 0x02: // Out packet recvd - { - xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); - - // Read packet off RxFIFO - if (xfer->ff) - { - // Ring buffer - tu_fifo_write_n_const_addr_full_words(xfer->ff, (const void *)(uintptr_t) rx_fifo, bcnt); - } - else - { - // Linear buffer - read_fifo_packet(rhport, xfer->buffer, bcnt); - - // Increment pointer to xfer data - xfer->buffer += bcnt; - } - - // Truncate transfer length in case of short packet - if(bcnt < xfer->max_size) { - xfer->total_len -= (out_ep[epnum].DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ_Msk) >> USB_OTG_DOEPTSIZ_XFRSIZ_Pos; - if(epnum == 0) { - xfer->total_len -= ep0_pending[TUSB_DIR_OUT]; - ep0_pending[TUSB_DIR_OUT] = 0; - } - } - } - break; - - case 0x03: // Out packet done (Interrupt) - break; - - case 0x04: // Setup packet done (Interrupt) - out_ep[epnum].DOEPTSIZ |= (3 << USB_OTG_DOEPTSIZ_STUPCNT_Pos); - break; - - case 0x06: // Setup packet recvd - // We can receive up to three setup packets in succession, but - // only the last one is valid. - _setup_packet[0] = (* rx_fifo); - _setup_packet[1] = (* rx_fifo); - break; - - default: // Invalid - TU_BREAKPOINT(); - break; - } -} - -static void handle_epout_ints(uint8_t rhport, USB_OTG_DeviceTypeDef * dev, USB_OTG_OUTEndpointTypeDef * out_ep) { - // DAINT for a given EP clears when DOEPINTx is cleared. - // OEPINT will be cleared when DAINT's out bits are cleared. - for(uint8_t n = 0; n < EP_MAX; n++) { - xfer_ctl_t * xfer = XFER_CTL_BASE(n, TUSB_DIR_OUT); - - if(dev->DAINT & (1 << (USB_OTG_DAINT_OEPINT_Pos + n))) { - // SETUP packet Setup Phase done. - if(out_ep[n].DOEPINT & USB_OTG_DOEPINT_STUP) { - out_ep[n].DOEPINT = USB_OTG_DOEPINT_STUP; - dcd_event_setup_received(rhport, (uint8_t*) &_setup_packet[0], true); - } - - // OUT XFER complete - if(out_ep[n].DOEPINT & USB_OTG_DOEPINT_XFRC) { - out_ep[n].DOEPINT = USB_OTG_DOEPINT_XFRC; - - // EP0 can only handle one packet - if((n == 0) && ep0_pending[TUSB_DIR_OUT]) { - // Schedule another packet to be received. - edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); - } else { - dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); - } - } - } - } -} - -static void handle_epin_ints(uint8_t rhport, USB_OTG_DeviceTypeDef * dev, USB_OTG_INEndpointTypeDef * in_ep) { - // DAINT for a given EP clears when DIEPINTx is cleared. - // IEPINT will be cleared when DAINT's out bits are cleared. - for ( uint8_t n = 0; n < EP_MAX; n++ ) - { - xfer_ctl_t *xfer = XFER_CTL_BASE(n, TUSB_DIR_IN); - - if ( dev->DAINT & (1 << (USB_OTG_DAINT_IEPINT_Pos + n)) ) - { - // IN XFER complete (entire xfer). - if ( in_ep[n].DIEPINT & USB_OTG_DIEPINT_XFRC ) - { - in_ep[n].DIEPINT = USB_OTG_DIEPINT_XFRC; - - // EP0 can only handle one packet - if((n == 0) && ep0_pending[TUSB_DIR_IN]) { - // Schedule another packet to be transmitted. - edpt_schedule_packets(rhport, n, TUSB_DIR_IN, 1, ep0_pending[TUSB_DIR_IN]); - } else { - dcd_event_xfer_complete(rhport, n | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true); - } - } - - // XFER FIFO empty - if ( (in_ep[n].DIEPINT & USB_OTG_DIEPINT_TXFE) && (dev->DIEPEMPMSK & (1 << n)) ) - { - // DIEPINT's TXFE bit is read-only, software cannot clear it. - // It will only be cleared by hardware when written bytes is more than - // - 64 bytes or - // - Half of TX FIFO size (configured by DIEPTXF) - - uint16_t remaining_packets = (in_ep[n].DIEPTSIZ & USB_OTG_DIEPTSIZ_PKTCNT_Msk) >> USB_OTG_DIEPTSIZ_PKTCNT_Pos; - - // Process every single packet (only whole packets can be written to fifo) - for(uint16_t i = 0; i < remaining_packets; i++) - { - uint16_t const remaining_bytes = (in_ep[n].DIEPTSIZ & USB_OTG_DIEPTSIZ_XFRSIZ_Msk) >> USB_OTG_DIEPTSIZ_XFRSIZ_Pos; - - // Packet can not be larger than ep max size - uint16_t const packet_size = tu_min16(remaining_bytes, xfer->max_size); - - // It's only possible to write full packets into FIFO. Therefore DTXFSTS register of current - // EP has to be checked if the buffer can take another WHOLE packet - if(packet_size > ((in_ep[n].DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV_Msk) << 2)) break; - - // Push packet to Tx-FIFO - if (xfer->ff) - { - usb_fifo_t tx_fifo = FIFO_BASE(rhport, n); - tu_fifo_read_n_const_addr_full_words(xfer->ff, (void *)(uintptr_t) tx_fifo, packet_size); - } - else - { - write_fifo_packet(rhport, n, xfer->buffer, packet_size); - - // Increment pointer to xfer data - xfer->buffer += packet_size; - } - } - - // Turn off TXFE if all bytes are written. - if (((in_ep[n].DIEPTSIZ & USB_OTG_DIEPTSIZ_XFRSIZ_Msk) >> USB_OTG_DIEPTSIZ_XFRSIZ_Pos) == 0) - { - dev->DIEPEMPMSK &= ~(1 << n); - } - } - } - } -} - -void dcd_int_handler(uint8_t rhport) -{ - USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); - USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); - USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); - - uint32_t const int_status = usb_otg->GINTSTS & usb_otg->GINTMSK; - - if(int_status & USB_OTG_GINTSTS_USBRST) - { - // USBRST is start of reset. - usb_otg->GINTSTS = USB_OTG_GINTSTS_USBRST; - bus_reset(rhport); - } - - if(int_status & USB_OTG_GINTSTS_ENUMDNE) - { - // ENUMDNE is the end of reset where speed of the link is detected - - usb_otg->GINTSTS = USB_OTG_GINTSTS_ENUMDNE; - - tusb_speed_t const speed = get_speed(rhport); - - set_turnaround(usb_otg, speed); - dcd_event_bus_reset(rhport, speed, true); - } - - if(int_status & USB_OTG_GINTSTS_USBSUSP) - { - usb_otg->GINTSTS = USB_OTG_GINTSTS_USBSUSP; - dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); - } - - if(int_status & USB_OTG_GINTSTS_WKUINT) - { - usb_otg->GINTSTS = USB_OTG_GINTSTS_WKUINT; - dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); - } - - // TODO check USB_OTG_GINTSTS_DISCINT for disconnect detection - // if(int_status & USB_OTG_GINTSTS_DISCINT) - - if(int_status & USB_OTG_GINTSTS_OTGINT) - { - // OTG INT bit is read-only - uint32_t const otg_int = usb_otg->GOTGINT; - - if (otg_int & USB_OTG_GOTGINT_SEDET) - { - dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); - } - - usb_otg->GOTGINT = otg_int; - } - - if(int_status & USB_OTG_GINTSTS_SOF) - { - usb_otg->GINTSTS = USB_OTG_GINTSTS_SOF; - - // Disable SOF interrupt since currently only used for remote wakeup detection - usb_otg->GINTMSK &= ~USB_OTG_GINTMSK_SOFM; - - dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); - } - - // RxFIFO non-empty interrupt handling. - if(int_status & USB_OTG_GINTSTS_RXFLVL) - { - // RXFLVL bit is read-only - - // Mask out RXFLVL while reading data from FIFO - usb_otg->GINTMSK &= ~USB_OTG_GINTMSK_RXFLVLM; - - // Loop until all available packets were handled - do - { - handle_rxflvl_ints(rhport, out_ep); - } while(usb_otg->GINTSTS & USB_OTG_GINTSTS_RXFLVL); - - // Manage RX FIFO size - if (_out_ep_closed) - { - update_grxfsiz(rhport); - - // Disable flag - _out_ep_closed = false; - } - - usb_otg->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM; - } - - // OUT endpoint interrupt handling. - if(int_status & USB_OTG_GINTSTS_OEPINT) - { - // OEPINT is read-only - handle_epout_ints(rhport, dev, out_ep); - } - - // IN endpoint interrupt handling. - if(int_status & USB_OTG_GINTSTS_IEPINT) - { - // IEPINT bit read-only - handle_epin_ints(rhport, dev, in_ep); - } - - // // Check for Incomplete isochronous IN transfer - // if(int_status & USB_OTG_GINTSTS_IISOIXFR) { - // printf(" IISOIXFR!\r\n"); - //// TU_LOG2(" IISOIXFR!\r\n"); - // } -} - -#endif diff --git a/src/portable/st/synopsys/synopsys_common.h b/src/portable/st/synopsys/synopsys_common.h deleted file mode 100644 index ce3195b23..000000000 --- a/src/portable/st/synopsys/synopsys_common.h +++ /dev/null @@ -1,1465 +0,0 @@ -/** - ****************************************************************************** - * @file synopsys_common.h - * @author MCD Application Team - * @brief CMSIS Cortex-M3 Device USB OTG peripheral Header File. - * This file contains the USB OTG peripheral register's definitions, bits - * definitions and memory mapping for STM32F1xx devices. - * - * This file contains: - * - Data structures and the address mapping for the USB OTG peripheral - * - The Peripheral's registers declarations and bits definition - * - Macros to access the peripheral's registers hardware - * - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under BSD 3-Clause license, - * the "License"; You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - * - ****************************************************************************** - */ - -#include "stdint.h" - -#pragma once - -#ifdef __cplusplus - #define __I volatile -#else - #define __I volatile const -#endif -#define __O volatile -#define __IO volatile -#define __IM volatile const -#define __OM volatile -#define __IOM volatile - -/** - * @brief __USB_OTG_Core_register - */ - -typedef struct -{ - __IO uint32_t GOTGCTL; /*!< USB_OTG Control and Status Register Address offset: 000h */ - __IO uint32_t GOTGINT; /*!< USB_OTG Interrupt Register Address offset: 004h */ - __IO uint32_t GAHBCFG; /*!< Core AHB Configuration Register Address offset: 008h */ - __IO uint32_t GUSBCFG; /*!< Core USB Configuration Register Address offset: 00Ch */ - __IO uint32_t GRSTCTL; /*!< Core Reset Register Address offset: 010h */ - __IO uint32_t GINTSTS; /*!< Core Interrupt Register Address offset: 014h */ - __IO uint32_t GINTMSK; /*!< Core Interrupt Mask Register Address offset: 018h */ - __IO uint32_t GRXSTSR; /*!< Receive Sts Q Read Register Address offset: 01Ch */ - __IO uint32_t GRXSTSP; /*!< Receive Sts Q Read & POP Register Address offset: 020h */ - __IO uint32_t GRXFSIZ; /*!< Receive FIFO Size Register Address offset: 024h */ - __IO uint32_t DIEPTXF0_HNPTXFSIZ; /*!< EP0 / Non Periodic Tx FIFO Size Register Address offset: 028h */ - __IO uint32_t HNPTXSTS; /*!< Non Periodic Tx FIFO/Queue Sts reg Address offset: 02Ch */ - uint32_t Reserved30[2]; /*!< Reserved 030h*/ - __IO uint32_t GCCFG; /*!< General Purpose IO Register Address offset: 038h */ - __IO uint32_t CID; /*!< User ID Register Address offset: 03Ch */ - uint32_t Reserved40[48]; /*!< Reserved 040h-0FFh */ - __IO uint32_t HPTXFSIZ; /*!< Host Periodic Tx FIFO Size Reg Address offset: 100h */ - __IO uint32_t DIEPTXF[0x0F]; /*!< dev Periodic Transmit FIFO Address offset: 0x104 */ -} USB_OTG_GlobalTypeDef; - -/** - * @brief __device_Registers - */ - -typedef struct -{ - __IO uint32_t DCFG; /*!< dev Configuration Register Address offset: 800h*/ - __IO uint32_t DCTL; /*!< dev Control Register Address offset: 804h*/ - __IO uint32_t DSTS; /*!< dev Status Register (RO) Address offset: 808h*/ - uint32_t Reserved0C; /*!< Reserved 80Ch*/ - __IO uint32_t DIEPMSK; /*!< dev IN Endpoint Mask Address offset: 810h*/ - __IO uint32_t DOEPMSK; /*!< dev OUT Endpoint Mask Address offset: 814h*/ - __IO uint32_t DAINT; /*!< dev All Endpoints Itr Reg Address offset: 818h*/ - __IO uint32_t DAINTMSK; /*!< dev All Endpoints Itr Mask Address offset: 81Ch*/ - uint32_t Reserved20; /*!< Reserved 820h*/ - uint32_t Reserved9; /*!< Reserved 824h*/ - __IO uint32_t DVBUSDIS; /*!< dev VBUS discharge Register Address offset: 828h*/ - __IO uint32_t DVBUSPULSE; /*!< dev VBUS Pulse Register Address offset: 82Ch*/ - __IO uint32_t DTHRCTL; /*!< dev thr Address offset: 830h*/ - __IO uint32_t DIEPEMPMSK; /*!< dev empty msk Address offset: 834h*/ - __IO uint32_t DEACHINT; /*!< dedicated EP interrupt Address offset: 838h*/ - __IO uint32_t DEACHMSK; /*!< dedicated EP msk Address offset: 83Ch*/ - uint32_t Reserved40; /*!< dedicated EP mask Address offset: 840h*/ - __IO uint32_t DINEP1MSK; /*!< dedicated EP mask Address offset: 844h*/ - uint32_t Reserved44[15]; /*!< Reserved 844-87Ch*/ - __IO uint32_t DOUTEP1MSK; /*!< dedicated EP msk Address offset: 884h*/ -} USB_OTG_DeviceTypeDef; - -/** - * @brief __IN_Endpoint-Specific_Register - */ - -typedef struct -{ - __IO uint32_t DIEPCTL; /*!< dev IN Endpoint Control Reg 900h + (ep_num * 20h) + 00h*/ - uint32_t Reserved04; /*!< Reserved 900h + (ep_num * 20h) + 04h*/ - __IO uint32_t DIEPINT; /*!< dev IN Endpoint Itr Reg 900h + (ep_num * 20h) + 08h*/ - uint32_t Reserved0C; /*!< Reserved 900h + (ep_num * 20h) + 0Ch*/ - __IO uint32_t DIEPTSIZ; /*!< IN Endpoint Txfer Size 900h + (ep_num * 20h) + 10h*/ - __IO uint32_t DIEPDMA; /*!< IN Endpoint DMA Address Reg 900h + (ep_num * 20h) + 14h*/ - __IO uint32_t DTXFSTS; /*!< IN Endpoint Tx FIFO Status Reg 900h + (ep_num * 20h) + 18h*/ - uint32_t Reserved18; /*!< Reserved 900h+(ep_num*20h)+1Ch-900h+ (ep_num * 20h) + 1Ch*/ -} USB_OTG_INEndpointTypeDef; - -/** - * @brief __OUT_Endpoint-Specific_Registers - */ - -typedef struct -{ - __IO uint32_t DOEPCTL; /*!< dev OUT Endpoint Control Reg B00h + (ep_num * 20h) + 00h*/ - uint32_t Reserved04; /*!< Reserved B00h + (ep_num * 20h) + 04h*/ - __IO uint32_t DOEPINT; /*!< dev OUT Endpoint Itr Reg B00h + (ep_num * 20h) + 08h*/ - uint32_t Reserved0C; /*!< Reserved B00h + (ep_num * 20h) + 0Ch*/ - __IO uint32_t DOEPTSIZ; /*!< dev OUT Endpoint Txfer Size B00h + (ep_num * 20h) + 10h*/ - __IO uint32_t DOEPDMA; /*!< dev OUT Endpoint DMA Address B00h + (ep_num * 20h) + 14h*/ - uint32_t Reserved18[2]; /*!< Reserved B00h + (ep_num * 20h) + 18h - B00h + (ep_num * 20h) + 1Ch*/ -} USB_OTG_OUTEndpointTypeDef; - -/** - * @brief __Host_Mode_Register_Structures - */ - -typedef struct -{ - __IO uint32_t HCFG; /*!< Host Configuration Register 400h*/ - __IO uint32_t HFIR; /*!< Host Frame Interval Register 404h*/ - __IO uint32_t HFNUM; /*!< Host Frame Nbr/Frame Remaining 408h*/ - uint32_t Reserved40C; /*!< Reserved 40Ch*/ - __IO uint32_t HPTXSTS; /*!< Host Periodic Tx FIFO/ Queue Status 410h*/ - __IO uint32_t HAINT; /*!< Host All Channels Interrupt Register 414h*/ - __IO uint32_t HAINTMSK; /*!< Host All Channels Interrupt Mask 418h*/ -} USB_OTG_HostTypeDef; - -/** - * @brief __Host_Channel_Specific_Registers - */ - -typedef struct -{ - __IO uint32_t HCCHAR; - __IO uint32_t HCSPLT; - __IO uint32_t HCINT; - __IO uint32_t HCINTMSK; - __IO uint32_t HCTSIZ; - __IO uint32_t HCDMA; - uint32_t Reserved[2]; -} USB_OTG_HostChannelTypeDef; - -/*!< USB registers base address */ -#define USB_OTG_FS_PERIPH_BASE 0x50000000UL - -#define USB_OTG_GLOBAL_BASE 0x00000000UL -#define USB_OTG_DEVICE_BASE 0x00000800UL -#define USB_OTG_IN_ENDPOINT_BASE 0x00000900UL -#define USB_OTG_OUT_ENDPOINT_BASE 0x00000B00UL -#define USB_OTG_EP_REG_SIZE 0x00000020UL -#define USB_OTG_HOST_BASE 0x00000400UL -#define USB_OTG_HOST_PORT_BASE 0x00000440UL -#define USB_OTG_HOST_CHANNEL_BASE 0x00000500UL -#define USB_OTG_HOST_CHANNEL_SIZE 0x00000020UL -#define USB_OTG_PCGCCTL_BASE 0x00000E00UL -#define USB_OTG_FIFO_BASE 0x00001000UL -#define USB_OTG_FIFO_SIZE 0x00001000UL - -/******************************************************************************/ -/* */ -/* USB_OTG */ -/* */ -/******************************************************************************/ -/******************** Bit definition for USB_OTG_GOTGCTL register ***********/ -#define USB_OTG_GOTGCTL_SRQSCS_Pos (0U) -#define USB_OTG_GOTGCTL_SRQSCS_Msk (0x1UL << USB_OTG_GOTGCTL_SRQSCS_Pos) /*!< 0x00000001 */ -#define USB_OTG_GOTGCTL_SRQSCS USB_OTG_GOTGCTL_SRQSCS_Msk /*!< Session request success */ -#define USB_OTG_GOTGCTL_SRQ_Pos (1U) -#define USB_OTG_GOTGCTL_SRQ_Msk (0x1UL << USB_OTG_GOTGCTL_SRQ_Pos) /*!< 0x00000002 */ -#define USB_OTG_GOTGCTL_SRQ USB_OTG_GOTGCTL_SRQ_Msk /*!< Session request */ -#define USB_OTG_GOTGCTL_HNGSCS_Pos (8U) -#define USB_OTG_GOTGCTL_HNGSCS_Msk (0x1UL << USB_OTG_GOTGCTL_HNGSCS_Pos) /*!< 0x00000100 */ -#define USB_OTG_GOTGCTL_HNGSCS USB_OTG_GOTGCTL_HNGSCS_Msk /*!< Host set HNP enable */ -#define USB_OTG_GOTGCTL_HNPRQ_Pos (9U) -#define USB_OTG_GOTGCTL_HNPRQ_Msk (0x1UL << USB_OTG_GOTGCTL_HNPRQ_Pos) /*!< 0x00000200 */ -#define USB_OTG_GOTGCTL_HNPRQ USB_OTG_GOTGCTL_HNPRQ_Msk /*!< HNP request */ -#define USB_OTG_GOTGCTL_HSHNPEN_Pos (10U) -#define USB_OTG_GOTGCTL_HSHNPEN_Msk (0x1UL << USB_OTG_GOTGCTL_HSHNPEN_Pos) /*!< 0x00000400 */ -#define USB_OTG_GOTGCTL_HSHNPEN USB_OTG_GOTGCTL_HSHNPEN_Msk /*!< Host set HNP enable */ -#define USB_OTG_GOTGCTL_DHNPEN_Pos (11U) -#define USB_OTG_GOTGCTL_DHNPEN_Msk (0x1UL << USB_OTG_GOTGCTL_DHNPEN_Pos) /*!< 0x00000800 */ -#define USB_OTG_GOTGCTL_DHNPEN USB_OTG_GOTGCTL_DHNPEN_Msk /*!< Device HNP enabled */ -#define USB_OTG_GOTGCTL_CIDSTS_Pos (16U) -#define USB_OTG_GOTGCTL_CIDSTS_Msk (0x1UL << USB_OTG_GOTGCTL_CIDSTS_Pos) /*!< 0x00010000 */ -#define USB_OTG_GOTGCTL_CIDSTS USB_OTG_GOTGCTL_CIDSTS_Msk /*!< Connector ID status */ -#define USB_OTG_GOTGCTL_DBCT_Pos (17U) -#define USB_OTG_GOTGCTL_DBCT_Msk (0x1UL << USB_OTG_GOTGCTL_DBCT_Pos) /*!< 0x00020000 */ -#define USB_OTG_GOTGCTL_DBCT USB_OTG_GOTGCTL_DBCT_Msk /*!< Long/short debounce time */ -#define USB_OTG_GOTGCTL_ASVLD_Pos (18U) -#define USB_OTG_GOTGCTL_ASVLD_Msk (0x1UL << USB_OTG_GOTGCTL_ASVLD_Pos) /*!< 0x00040000 */ -#define USB_OTG_GOTGCTL_ASVLD USB_OTG_GOTGCTL_ASVLD_Msk /*!< A-session valid */ -#define USB_OTG_GOTGCTL_BSVLD_Pos (19U) -#define USB_OTG_GOTGCTL_BSVLD_Msk (0x1UL << USB_OTG_GOTGCTL_BSVLD_Pos) /*!< 0x00080000 */ -#define USB_OTG_GOTGCTL_BSVLD USB_OTG_GOTGCTL_BSVLD_Msk /*!< B-session valid */ - -/******************** Bit definition for USB_OTG_HCFG register ********************/ - -#define USB_OTG_HCFG_FSLSPCS_Pos (0U) -#define USB_OTG_HCFG_FSLSPCS_Msk (0x3UL << USB_OTG_HCFG_FSLSPCS_Pos) /*!< 0x00000003 */ -#define USB_OTG_HCFG_FSLSPCS USB_OTG_HCFG_FSLSPCS_Msk /*!< FS/LS PHY clock select */ -#define USB_OTG_HCFG_FSLSPCS_0 (0x1UL << USB_OTG_HCFG_FSLSPCS_Pos) /*!< 0x00000001 */ -#define USB_OTG_HCFG_FSLSPCS_1 (0x2UL << USB_OTG_HCFG_FSLSPCS_Pos) /*!< 0x00000002 */ -#define USB_OTG_HCFG_FSLSS_Pos (2U) -#define USB_OTG_HCFG_FSLSS_Msk (0x1UL << USB_OTG_HCFG_FSLSS_Pos) /*!< 0x00000004 */ -#define USB_OTG_HCFG_FSLSS USB_OTG_HCFG_FSLSS_Msk /*!< FS- and LS-only support */ - -/******************** Bit definition for USB_OTG_DCFG register ********************/ - -#define USB_OTG_DCFG_DSPD_Pos (0U) -#define USB_OTG_DCFG_DSPD_Msk (0x3UL << USB_OTG_DCFG_DSPD_Pos) /*!< 0x00000003 */ -#define USB_OTG_DCFG_DSPD USB_OTG_DCFG_DSPD_Msk /*!< Device speed */ -#define USB_OTG_DCFG_DSPD_0 (0x1UL << USB_OTG_DCFG_DSPD_Pos) /*!< 0x00000001 */ -#define USB_OTG_DCFG_DSPD_1 (0x2UL << USB_OTG_DCFG_DSPD_Pos) /*!< 0x00000002 */ -#define USB_OTG_DCFG_NZLSOHSK_Pos (2U) -#define USB_OTG_DCFG_NZLSOHSK_Msk (0x1UL << USB_OTG_DCFG_NZLSOHSK_Pos) /*!< 0x00000004 */ -#define USB_OTG_DCFG_NZLSOHSK USB_OTG_DCFG_NZLSOHSK_Msk /*!< Nonzero-length status OUT handshake */ - -#define USB_OTG_DCFG_DAD_Pos (4U) -#define USB_OTG_DCFG_DAD_Msk (0x7FUL << USB_OTG_DCFG_DAD_Pos) /*!< 0x000007F0 */ -#define USB_OTG_DCFG_DAD USB_OTG_DCFG_DAD_Msk /*!< Device address */ -#define USB_OTG_DCFG_DAD_0 (0x01UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000010 */ -#define USB_OTG_DCFG_DAD_1 (0x02UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000020 */ -#define USB_OTG_DCFG_DAD_2 (0x04UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000040 */ -#define USB_OTG_DCFG_DAD_3 (0x08UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000080 */ -#define USB_OTG_DCFG_DAD_4 (0x10UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000100 */ -#define USB_OTG_DCFG_DAD_5 (0x20UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000200 */ -#define USB_OTG_DCFG_DAD_6 (0x40UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000400 */ - -#define USB_OTG_DCFG_PFIVL_Pos (11U) -#define USB_OTG_DCFG_PFIVL_Msk (0x3UL << USB_OTG_DCFG_PFIVL_Pos) /*!< 0x00001800 */ -#define USB_OTG_DCFG_PFIVL USB_OTG_DCFG_PFIVL_Msk /*!< Periodic (micro)frame interval */ -#define USB_OTG_DCFG_PFIVL_0 (0x1UL << USB_OTG_DCFG_PFIVL_Pos) /*!< 0x00000800 */ -#define USB_OTG_DCFG_PFIVL_1 (0x2UL << USB_OTG_DCFG_PFIVL_Pos) /*!< 0x00001000 */ - -#define USB_OTG_DCFG_PERSCHIVL_Pos (24U) -#define USB_OTG_DCFG_PERSCHIVL_Msk (0x3UL << USB_OTG_DCFG_PERSCHIVL_Pos) /*!< 0x03000000 */ -#define USB_OTG_DCFG_PERSCHIVL USB_OTG_DCFG_PERSCHIVL_Msk /*!< Periodic scheduling interval */ -#define USB_OTG_DCFG_PERSCHIVL_0 (0x1UL << USB_OTG_DCFG_PERSCHIVL_Pos) /*!< 0x01000000 */ -#define USB_OTG_DCFG_PERSCHIVL_1 (0x2UL << USB_OTG_DCFG_PERSCHIVL_Pos) /*!< 0x02000000 */ - -/******************** Bit definition for USB_OTG_PCGCR register ********************/ -#define USB_OTG_PCGCR_STPPCLK_Pos (0U) -#define USB_OTG_PCGCR_STPPCLK_Msk (0x1UL << USB_OTG_PCGCR_STPPCLK_Pos) /*!< 0x00000001 */ -#define USB_OTG_PCGCR_STPPCLK USB_OTG_PCGCR_STPPCLK_Msk /*!< Stop PHY clock */ -#define USB_OTG_PCGCR_GATEHCLK_Pos (1U) -#define USB_OTG_PCGCR_GATEHCLK_Msk (0x1UL << USB_OTG_PCGCR_GATEHCLK_Pos) /*!< 0x00000002 */ -#define USB_OTG_PCGCR_GATEHCLK USB_OTG_PCGCR_GATEHCLK_Msk /*!< Gate HCLK */ -#define USB_OTG_PCGCR_PHYSUSP_Pos (4U) -#define USB_OTG_PCGCR_PHYSUSP_Msk (0x1UL << USB_OTG_PCGCR_PHYSUSP_Pos) /*!< 0x00000010 */ -#define USB_OTG_PCGCR_PHYSUSP USB_OTG_PCGCR_PHYSUSP_Msk /*!< PHY suspended */ - -/******************** Bit definition for USB_OTG_GOTGINT register ********************/ -#define USB_OTG_GOTGINT_SEDET_Pos (2U) -#define USB_OTG_GOTGINT_SEDET_Msk (0x1UL << USB_OTG_GOTGINT_SEDET_Pos) /*!< 0x00000004 */ -#define USB_OTG_GOTGINT_SEDET USB_OTG_GOTGINT_SEDET_Msk /*!< Session end detected */ -#define USB_OTG_GOTGINT_SRSSCHG_Pos (8U) -#define USB_OTG_GOTGINT_SRSSCHG_Msk (0x1UL << USB_OTG_GOTGINT_SRSSCHG_Pos) /*!< 0x00000100 */ -#define USB_OTG_GOTGINT_SRSSCHG USB_OTG_GOTGINT_SRSSCHG_Msk /*!< Session request success status change */ -#define USB_OTG_GOTGINT_HNSSCHG_Pos (9U) -#define USB_OTG_GOTGINT_HNSSCHG_Msk (0x1UL << USB_OTG_GOTGINT_HNSSCHG_Pos) /*!< 0x00000200 */ -#define USB_OTG_GOTGINT_HNSSCHG USB_OTG_GOTGINT_HNSSCHG_Msk /*!< Host negotiation success status change */ -#define USB_OTG_GOTGINT_HNGDET_Pos (17U) -#define USB_OTG_GOTGINT_HNGDET_Msk (0x1UL << USB_OTG_GOTGINT_HNGDET_Pos) /*!< 0x00020000 */ -#define USB_OTG_GOTGINT_HNGDET USB_OTG_GOTGINT_HNGDET_Msk /*!< Host negotiation detected */ -#define USB_OTG_GOTGINT_ADTOCHG_Pos (18U) -#define USB_OTG_GOTGINT_ADTOCHG_Msk (0x1UL << USB_OTG_GOTGINT_ADTOCHG_Pos) /*!< 0x00040000 */ -#define USB_OTG_GOTGINT_ADTOCHG USB_OTG_GOTGINT_ADTOCHG_Msk /*!< A-device timeout change */ -#define USB_OTG_GOTGINT_DBCDNE_Pos (19U) -#define USB_OTG_GOTGINT_DBCDNE_Msk (0x1UL << USB_OTG_GOTGINT_DBCDNE_Pos) /*!< 0x00080000 */ -#define USB_OTG_GOTGINT_DBCDNE USB_OTG_GOTGINT_DBCDNE_Msk /*!< Debounce done */ - -/******************** Bit definition for USB_OTG_DCTL register ********************/ -#define USB_OTG_DCTL_RWUSIG_Pos (0U) -#define USB_OTG_DCTL_RWUSIG_Msk (0x1UL << USB_OTG_DCTL_RWUSIG_Pos) /*!< 0x00000001 */ -#define USB_OTG_DCTL_RWUSIG USB_OTG_DCTL_RWUSIG_Msk /*!< Remote wakeup signaling */ -#define USB_OTG_DCTL_SDIS_Pos (1U) -#define USB_OTG_DCTL_SDIS_Msk (0x1UL << USB_OTG_DCTL_SDIS_Pos) /*!< 0x00000002 */ -#define USB_OTG_DCTL_SDIS USB_OTG_DCTL_SDIS_Msk /*!< Soft disconnect */ -#define USB_OTG_DCTL_GINSTS_Pos (2U) -#define USB_OTG_DCTL_GINSTS_Msk (0x1UL << USB_OTG_DCTL_GINSTS_Pos) /*!< 0x00000004 */ -#define USB_OTG_DCTL_GINSTS USB_OTG_DCTL_GINSTS_Msk /*!< Global IN NAK status */ -#define USB_OTG_DCTL_GONSTS_Pos (3U) -#define USB_OTG_DCTL_GONSTS_Msk (0x1UL << USB_OTG_DCTL_GONSTS_Pos) /*!< 0x00000008 */ -#define USB_OTG_DCTL_GONSTS USB_OTG_DCTL_GONSTS_Msk /*!< Global OUT NAK status */ - -#define USB_OTG_DCTL_TCTL_Pos (4U) -#define USB_OTG_DCTL_TCTL_Msk (0x7UL << USB_OTG_DCTL_TCTL_Pos) /*!< 0x00000070 */ -#define USB_OTG_DCTL_TCTL USB_OTG_DCTL_TCTL_Msk /*!< Test control */ -#define USB_OTG_DCTL_TCTL_0 (0x1UL << USB_OTG_DCTL_TCTL_Pos) /*!< 0x00000010 */ -#define USB_OTG_DCTL_TCTL_1 (0x2UL << USB_OTG_DCTL_TCTL_Pos) /*!< 0x00000020 */ -#define USB_OTG_DCTL_TCTL_2 (0x4UL << USB_OTG_DCTL_TCTL_Pos) /*!< 0x00000040 */ -#define USB_OTG_DCTL_SGINAK_Pos (7U) -#define USB_OTG_DCTL_SGINAK_Msk (0x1UL << USB_OTG_DCTL_SGINAK_Pos) /*!< 0x00000080 */ -#define USB_OTG_DCTL_SGINAK USB_OTG_DCTL_SGINAK_Msk /*!< Set global IN NAK */ -#define USB_OTG_DCTL_CGINAK_Pos (8U) -#define USB_OTG_DCTL_CGINAK_Msk (0x1UL << USB_OTG_DCTL_CGINAK_Pos) /*!< 0x00000100 */ -#define USB_OTG_DCTL_CGINAK USB_OTG_DCTL_CGINAK_Msk /*!< Clear global IN NAK */ -#define USB_OTG_DCTL_SGONAK_Pos (9U) -#define USB_OTG_DCTL_SGONAK_Msk (0x1UL << USB_OTG_DCTL_SGONAK_Pos) /*!< 0x00000200 */ -#define USB_OTG_DCTL_SGONAK USB_OTG_DCTL_SGONAK_Msk /*!< Set global OUT NAK */ -#define USB_OTG_DCTL_CGONAK_Pos (10U) -#define USB_OTG_DCTL_CGONAK_Msk (0x1UL << USB_OTG_DCTL_CGONAK_Pos) /*!< 0x00000400 */ -#define USB_OTG_DCTL_CGONAK USB_OTG_DCTL_CGONAK_Msk /*!< Clear global OUT NAK */ -#define USB_OTG_DCTL_POPRGDNE_Pos (11U) -#define USB_OTG_DCTL_POPRGDNE_Msk (0x1UL << USB_OTG_DCTL_POPRGDNE_Pos) /*!< 0x00000800 */ -#define USB_OTG_DCTL_POPRGDNE USB_OTG_DCTL_POPRGDNE_Msk /*!< Power-on programming done */ - -/******************** Bit definition for USB_OTG_HFIR register ********************/ -#define USB_OTG_HFIR_FRIVL_Pos (0U) -#define USB_OTG_HFIR_FRIVL_Msk (0xFFFFUL << USB_OTG_HFIR_FRIVL_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_HFIR_FRIVL USB_OTG_HFIR_FRIVL_Msk /*!< Frame interval */ - -/******************** Bit definition for USB_OTG_HFNUM register ********************/ -#define USB_OTG_HFNUM_FRNUM_Pos (0U) -#define USB_OTG_HFNUM_FRNUM_Msk (0xFFFFUL << USB_OTG_HFNUM_FRNUM_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_HFNUM_FRNUM USB_OTG_HFNUM_FRNUM_Msk /*!< Frame number */ -#define USB_OTG_HFNUM_FTREM_Pos (16U) -#define USB_OTG_HFNUM_FTREM_Msk (0xFFFFUL << USB_OTG_HFNUM_FTREM_Pos) /*!< 0xFFFF0000 */ -#define USB_OTG_HFNUM_FTREM USB_OTG_HFNUM_FTREM_Msk /*!< Frame time remaining */ - -/******************** Bit definition for USB_OTG_DSTS register ********************/ -#define USB_OTG_DSTS_SUSPSTS_Pos (0U) -#define USB_OTG_DSTS_SUSPSTS_Msk (0x1UL << USB_OTG_DSTS_SUSPSTS_Pos) /*!< 0x00000001 */ -#define USB_OTG_DSTS_SUSPSTS USB_OTG_DSTS_SUSPSTS_Msk /*!< Suspend status */ - -#define USB_OTG_DSTS_ENUMSPD_Pos (1U) -#define USB_OTG_DSTS_ENUMSPD_Msk (0x3UL << USB_OTG_DSTS_ENUMSPD_Pos) /*!< 0x00000006 */ -#define USB_OTG_DSTS_ENUMSPD USB_OTG_DSTS_ENUMSPD_Msk /*!< Enumerated speed */ -#define USB_OTG_DSTS_ENUMSPD_0 (0x1UL << USB_OTG_DSTS_ENUMSPD_Pos) /*!< 0x00000002 */ -#define USB_OTG_DSTS_ENUMSPD_1 (0x2UL << USB_OTG_DSTS_ENUMSPD_Pos) /*!< 0x00000004 */ -#define USB_OTG_DSTS_EERR_Pos (3U) -#define USB_OTG_DSTS_EERR_Msk (0x1UL << USB_OTG_DSTS_EERR_Pos) /*!< 0x00000008 */ -#define USB_OTG_DSTS_EERR USB_OTG_DSTS_EERR_Msk /*!< Erratic error */ -#define USB_OTG_DSTS_FNSOF_Pos (8U) -#define USB_OTG_DSTS_FNSOF_Msk (0x3FFFUL << USB_OTG_DSTS_FNSOF_Pos) /*!< 0x003FFF00 */ -#define USB_OTG_DSTS_FNSOF USB_OTG_DSTS_FNSOF_Msk /*!< Frame number of the received SOF */ - -/******************** Bit definition for USB_OTG_GAHBCFG register ********************/ -#define USB_OTG_GAHBCFG_GINT_Pos (0U) -#define USB_OTG_GAHBCFG_GINT_Msk (0x1UL << USB_OTG_GAHBCFG_GINT_Pos) /*!< 0x00000001 */ -#define USB_OTG_GAHBCFG_GINT USB_OTG_GAHBCFG_GINT_Msk /*!< Global interrupt mask */ -#define USB_OTG_GAHBCFG_HBSTLEN_Pos (1U) -#define USB_OTG_GAHBCFG_HBSTLEN_Msk (0xFUL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< 0x0000001E */ -#define USB_OTG_GAHBCFG_HBSTLEN USB_OTG_GAHBCFG_HBSTLEN_Msk /*!< Burst length/type */ -#define USB_OTG_GAHBCFG_HBSTLEN_0 (0x0UL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< Single */ -#define USB_OTG_GAHBCFG_HBSTLEN_1 (0x1UL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< INCR */ -#define USB_OTG_GAHBCFG_HBSTLEN_2 (0x3UL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< INCR4 */ -#define USB_OTG_GAHBCFG_HBSTLEN_3 (0x5UL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< INCR8 */ -#define USB_OTG_GAHBCFG_HBSTLEN_4 (0x7UL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< INCR16 */ -#define USB_OTG_GAHBCFG_DMAEN_Pos (5U) -#define USB_OTG_GAHBCFG_DMAEN_Msk (0x1UL << USB_OTG_GAHBCFG_DMAEN_Pos) /*!< 0x00000020 */ -#define USB_OTG_GAHBCFG_DMAEN USB_OTG_GAHBCFG_DMAEN_Msk /*!< DMA enable */ -#define USB_OTG_GAHBCFG_TXFELVL_Pos (7U) -#define USB_OTG_GAHBCFG_TXFELVL_Msk (0x1UL << USB_OTG_GAHBCFG_TXFELVL_Pos) /*!< 0x00000080 */ -#define USB_OTG_GAHBCFG_TXFELVL USB_OTG_GAHBCFG_TXFELVL_Msk /*!< TxFIFO empty level */ -#define USB_OTG_GAHBCFG_PTXFELVL_Pos (8U) -#define USB_OTG_GAHBCFG_PTXFELVL_Msk (0x1UL << USB_OTG_GAHBCFG_PTXFELVL_Pos) /*!< 0x00000100 */ -#define USB_OTG_GAHBCFG_PTXFELVL USB_OTG_GAHBCFG_PTXFELVL_Msk /*!< Periodic TxFIFO empty level */ - -/******************** Bit definition for USB_OTG_GUSBCFG register ********************/ - -#define USB_OTG_GUSBCFG_TOCAL_Pos (0U) -#define USB_OTG_GUSBCFG_TOCAL_Msk (0x7UL << USB_OTG_GUSBCFG_TOCAL_Pos) /*!< 0x00000007 */ -#define USB_OTG_GUSBCFG_TOCAL USB_OTG_GUSBCFG_TOCAL_Msk /*!< FS timeout calibration */ -#define USB_OTG_GUSBCFG_TOCAL_0 (0x1UL << USB_OTG_GUSBCFG_TOCAL_Pos) /*!< 0x00000001 */ -#define USB_OTG_GUSBCFG_TOCAL_1 (0x2UL << USB_OTG_GUSBCFG_TOCAL_Pos) /*!< 0x00000002 */ -#define USB_OTG_GUSBCFG_TOCAL_2 (0x4UL << USB_OTG_GUSBCFG_TOCAL_Pos) /*!< 0x00000004 */ -#define USB_OTG_GUSBCFG_PHYSEL_Pos (6U) -#define USB_OTG_GUSBCFG_PHYSEL_Msk (0x1UL << USB_OTG_GUSBCFG_PHYSEL_Pos) /*!< 0x00000040 */ -#define USB_OTG_GUSBCFG_PHYSEL USB_OTG_GUSBCFG_PHYSEL_Msk /*!< USB 2.0 high-speed ULPI PHY or USB 1.1 full-speed serial transceiver select */ -#define USB_OTG_GUSBCFG_SRPCAP_Pos (8U) -#define USB_OTG_GUSBCFG_SRPCAP_Msk (0x1UL << USB_OTG_GUSBCFG_SRPCAP_Pos) /*!< 0x00000100 */ -#define USB_OTG_GUSBCFG_SRPCAP USB_OTG_GUSBCFG_SRPCAP_Msk /*!< SRP-capable */ -#define USB_OTG_GUSBCFG_HNPCAP_Pos (9U) -#define USB_OTG_GUSBCFG_HNPCAP_Msk (0x1UL << USB_OTG_GUSBCFG_HNPCAP_Pos) /*!< 0x00000200 */ -#define USB_OTG_GUSBCFG_HNPCAP USB_OTG_GUSBCFG_HNPCAP_Msk /*!< HNP-capable */ -#define USB_OTG_GUSBCFG_TRDT_Pos (10U) -#define USB_OTG_GUSBCFG_TRDT_Msk (0xFUL << USB_OTG_GUSBCFG_TRDT_Pos) /*!< 0x00003C00 */ -#define USB_OTG_GUSBCFG_TRDT USB_OTG_GUSBCFG_TRDT_Msk /*!< USB turnaround time */ -#define USB_OTG_GUSBCFG_TRDT_0 (0x1UL << USB_OTG_GUSBCFG_TRDT_Pos) /*!< 0x00000400 */ -#define USB_OTG_GUSBCFG_TRDT_1 (0x2UL << USB_OTG_GUSBCFG_TRDT_Pos) /*!< 0x00000800 */ -#define USB_OTG_GUSBCFG_TRDT_2 (0x4UL << USB_OTG_GUSBCFG_TRDT_Pos) /*!< 0x00001000 */ -#define USB_OTG_GUSBCFG_TRDT_3 (0x8UL << USB_OTG_GUSBCFG_TRDT_Pos) /*!< 0x00002000 */ -#define USB_OTG_GUSBCFG_PHYLPCS_Pos (15U) -#define USB_OTG_GUSBCFG_PHYLPCS_Msk (0x1UL << USB_OTG_GUSBCFG_PHYLPCS_Pos) /*!< 0x00008000 */ -#define USB_OTG_GUSBCFG_PHYLPCS USB_OTG_GUSBCFG_PHYLPCS_Msk /*!< PHY Low-power clock select */ -#define USB_OTG_GUSBCFG_ULPIFSLS_Pos (17U) -#define USB_OTG_GUSBCFG_ULPIFSLS_Msk (0x1UL << USB_OTG_GUSBCFG_ULPIFSLS_Pos) /*!< 0x00020000 */ -#define USB_OTG_GUSBCFG_ULPIFSLS USB_OTG_GUSBCFG_ULPIFSLS_Msk /*!< ULPI FS/LS select */ -#define USB_OTG_GUSBCFG_ULPIAR_Pos (18U) -#define USB_OTG_GUSBCFG_ULPIAR_Msk (0x1UL << USB_OTG_GUSBCFG_ULPIAR_Pos) /*!< 0x00040000 */ -#define USB_OTG_GUSBCFG_ULPIAR USB_OTG_GUSBCFG_ULPIAR_Msk /*!< ULPI Auto-resume */ -#define USB_OTG_GUSBCFG_ULPICSM_Pos (19U) -#define USB_OTG_GUSBCFG_ULPICSM_Msk (0x1UL << USB_OTG_GUSBCFG_ULPICSM_Pos) /*!< 0x00080000 */ -#define USB_OTG_GUSBCFG_ULPICSM USB_OTG_GUSBCFG_ULPICSM_Msk /*!< ULPI Clock SuspendM */ -#define USB_OTG_GUSBCFG_ULPIEVBUSD_Pos (20U) -#define USB_OTG_GUSBCFG_ULPIEVBUSD_Msk (0x1UL << USB_OTG_GUSBCFG_ULPIEVBUSD_Pos) /*!< 0x00100000 */ -#define USB_OTG_GUSBCFG_ULPIEVBUSD USB_OTG_GUSBCFG_ULPIEVBUSD_Msk /*!< ULPI External VBUS Drive */ -#define USB_OTG_GUSBCFG_ULPIEVBUSI_Pos (21U) -#define USB_OTG_GUSBCFG_ULPIEVBUSI_Msk (0x1UL << USB_OTG_GUSBCFG_ULPIEVBUSI_Pos) /*!< 0x00200000 */ -#define USB_OTG_GUSBCFG_ULPIEVBUSI USB_OTG_GUSBCFG_ULPIEVBUSI_Msk /*!< ULPI external VBUS indicator */ -#define USB_OTG_GUSBCFG_TSDPS_Pos (22U) -#define USB_OTG_GUSBCFG_TSDPS_Msk (0x1UL << USB_OTG_GUSBCFG_TSDPS_Pos) /*!< 0x00400000 */ -#define USB_OTG_GUSBCFG_TSDPS USB_OTG_GUSBCFG_TSDPS_Msk /*!< TermSel DLine pulsing selection */ -#define USB_OTG_GUSBCFG_PCCI_Pos (23U) -#define USB_OTG_GUSBCFG_PCCI_Msk (0x1UL << USB_OTG_GUSBCFG_PCCI_Pos) /*!< 0x00800000 */ -#define USB_OTG_GUSBCFG_PCCI USB_OTG_GUSBCFG_PCCI_Msk /*!< Indicator complement */ -#define USB_OTG_GUSBCFG_PTCI_Pos (24U) -#define USB_OTG_GUSBCFG_PTCI_Msk (0x1UL << USB_OTG_GUSBCFG_PTCI_Pos) /*!< 0x01000000 */ -#define USB_OTG_GUSBCFG_PTCI USB_OTG_GUSBCFG_PTCI_Msk /*!< Indicator pass through */ -#define USB_OTG_GUSBCFG_ULPIIPD_Pos (25U) -#define USB_OTG_GUSBCFG_ULPIIPD_Msk (0x1UL << USB_OTG_GUSBCFG_ULPIIPD_Pos) /*!< 0x02000000 */ -#define USB_OTG_GUSBCFG_ULPIIPD USB_OTG_GUSBCFG_ULPIIPD_Msk /*!< ULPI interface protect disable */ -#define USB_OTG_GUSBCFG_FHMOD_Pos (29U) -#define USB_OTG_GUSBCFG_FHMOD_Msk (0x1UL << USB_OTG_GUSBCFG_FHMOD_Pos) /*!< 0x20000000 */ -#define USB_OTG_GUSBCFG_FHMOD USB_OTG_GUSBCFG_FHMOD_Msk /*!< Forced host mode */ -#define USB_OTG_GUSBCFG_FDMOD_Pos (30U) -#define USB_OTG_GUSBCFG_FDMOD_Msk (0x1UL << USB_OTG_GUSBCFG_FDMOD_Pos) /*!< 0x40000000 */ -#define USB_OTG_GUSBCFG_FDMOD USB_OTG_GUSBCFG_FDMOD_Msk /*!< Forced peripheral mode */ -#define USB_OTG_GUSBCFG_CTXPKT_Pos (31U) -#define USB_OTG_GUSBCFG_CTXPKT_Msk (0x1UL << USB_OTG_GUSBCFG_CTXPKT_Pos) /*!< 0x80000000 */ -#define USB_OTG_GUSBCFG_CTXPKT USB_OTG_GUSBCFG_CTXPKT_Msk /*!< Corrupt Tx packet */ - -/******************** Bit definition for USB_OTG_GRSTCTL register ********************/ -#define USB_OTG_GRSTCTL_CSRST_Pos (0U) -#define USB_OTG_GRSTCTL_CSRST_Msk (0x1UL << USB_OTG_GRSTCTL_CSRST_Pos) /*!< 0x00000001 */ -#define USB_OTG_GRSTCTL_CSRST USB_OTG_GRSTCTL_CSRST_Msk /*!< Core soft reset */ -#define USB_OTG_GRSTCTL_HSRST_Pos (1U) -#define USB_OTG_GRSTCTL_HSRST_Msk (0x1UL << USB_OTG_GRSTCTL_HSRST_Pos) /*!< 0x00000002 */ -#define USB_OTG_GRSTCTL_HSRST USB_OTG_GRSTCTL_HSRST_Msk /*!< HCLK soft reset */ -#define USB_OTG_GRSTCTL_FCRST_Pos (2U) -#define USB_OTG_GRSTCTL_FCRST_Msk (0x1UL << USB_OTG_GRSTCTL_FCRST_Pos) /*!< 0x00000004 */ -#define USB_OTG_GRSTCTL_FCRST USB_OTG_GRSTCTL_FCRST_Msk /*!< Host frame counter reset */ -#define USB_OTG_GRSTCTL_RXFFLSH_Pos (4U) -#define USB_OTG_GRSTCTL_RXFFLSH_Msk (0x1UL << USB_OTG_GRSTCTL_RXFFLSH_Pos) /*!< 0x00000010 */ -#define USB_OTG_GRSTCTL_RXFFLSH USB_OTG_GRSTCTL_RXFFLSH_Msk /*!< RxFIFO flush */ -#define USB_OTG_GRSTCTL_TXFFLSH_Pos (5U) -#define USB_OTG_GRSTCTL_TXFFLSH_Msk (0x1UL << USB_OTG_GRSTCTL_TXFFLSH_Pos) /*!< 0x00000020 */ -#define USB_OTG_GRSTCTL_TXFFLSH USB_OTG_GRSTCTL_TXFFLSH_Msk /*!< TxFIFO flush */ - - -#define USB_OTG_GRSTCTL_TXFNUM_Pos (6U) -#define USB_OTG_GRSTCTL_TXFNUM_Msk (0x1FUL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x000007C0 */ -#define USB_OTG_GRSTCTL_TXFNUM USB_OTG_GRSTCTL_TXFNUM_Msk /*!< TxFIFO number */ -#define USB_OTG_GRSTCTL_TXFNUM_0 (0x01UL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x00000040 */ -#define USB_OTG_GRSTCTL_TXFNUM_1 (0x02UL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x00000080 */ -#define USB_OTG_GRSTCTL_TXFNUM_2 (0x04UL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x00000100 */ -#define USB_OTG_GRSTCTL_TXFNUM_3 (0x08UL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x00000200 */ -#define USB_OTG_GRSTCTL_TXFNUM_4 (0x10UL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x00000400 */ -#define USB_OTG_GRSTCTL_DMAREQ_Pos (30U) -#define USB_OTG_GRSTCTL_DMAREQ_Msk (0x1UL << USB_OTG_GRSTCTL_DMAREQ_Pos) /*!< 0x40000000 */ -#define USB_OTG_GRSTCTL_DMAREQ USB_OTG_GRSTCTL_DMAREQ_Msk /*!< DMA request signal */ -#define USB_OTG_GRSTCTL_AHBIDL_Pos (31U) -#define USB_OTG_GRSTCTL_AHBIDL_Msk (0x1UL << USB_OTG_GRSTCTL_AHBIDL_Pos) /*!< 0x80000000 */ -#define USB_OTG_GRSTCTL_AHBIDL USB_OTG_GRSTCTL_AHBIDL_Msk /*!< AHB master idle */ - -/******************** Bit definition for USB_OTG_DIEPMSK register ********************/ -#define USB_OTG_DIEPMSK_XFRCM_Pos (0U) -#define USB_OTG_DIEPMSK_XFRCM_Msk (0x1UL << USB_OTG_DIEPMSK_XFRCM_Pos) /*!< 0x00000001 */ -#define USB_OTG_DIEPMSK_XFRCM USB_OTG_DIEPMSK_XFRCM_Msk /*!< Transfer completed interrupt mask */ -#define USB_OTG_DIEPMSK_EPDM_Pos (1U) -#define USB_OTG_DIEPMSK_EPDM_Msk (0x1UL << USB_OTG_DIEPMSK_EPDM_Pos) /*!< 0x00000002 */ -#define USB_OTG_DIEPMSK_EPDM USB_OTG_DIEPMSK_EPDM_Msk /*!< Endpoint disabled interrupt mask */ -#define USB_OTG_DIEPMSK_TOM_Pos (3U) -#define USB_OTG_DIEPMSK_TOM_Msk (0x1UL << USB_OTG_DIEPMSK_TOM_Pos) /*!< 0x00000008 */ -#define USB_OTG_DIEPMSK_TOM USB_OTG_DIEPMSK_TOM_Msk /*!< Timeout condition mask (nonisochronous endpoints) */ -#define USB_OTG_DIEPMSK_ITTXFEMSK_Pos (4U) -#define USB_OTG_DIEPMSK_ITTXFEMSK_Msk (0x1UL << USB_OTG_DIEPMSK_ITTXFEMSK_Pos) /*!< 0x00000010 */ -#define USB_OTG_DIEPMSK_ITTXFEMSK USB_OTG_DIEPMSK_ITTXFEMSK_Msk /*!< IN token received when TxFIFO empty mask */ -#define USB_OTG_DIEPMSK_INEPNMM_Pos (5U) -#define USB_OTG_DIEPMSK_INEPNMM_Msk (0x1UL << USB_OTG_DIEPMSK_INEPNMM_Pos) /*!< 0x00000020 */ -#define USB_OTG_DIEPMSK_INEPNMM USB_OTG_DIEPMSK_INEPNMM_Msk /*!< IN token received with EP mismatch mask */ -#define USB_OTG_DIEPMSK_INEPNEM_Pos (6U) -#define USB_OTG_DIEPMSK_INEPNEM_Msk (0x1UL << USB_OTG_DIEPMSK_INEPNEM_Pos) /*!< 0x00000040 */ -#define USB_OTG_DIEPMSK_INEPNEM USB_OTG_DIEPMSK_INEPNEM_Msk /*!< IN endpoint NAK effective mask */ -#define USB_OTG_DIEPMSK_TXFURM_Pos (8U) -#define USB_OTG_DIEPMSK_TXFURM_Msk (0x1UL << USB_OTG_DIEPMSK_TXFURM_Pos) /*!< 0x00000100 */ -#define USB_OTG_DIEPMSK_TXFURM USB_OTG_DIEPMSK_TXFURM_Msk /*!< FIFO underrun mask */ -#define USB_OTG_DIEPMSK_BIM_Pos (9U) -#define USB_OTG_DIEPMSK_BIM_Msk (0x1UL << USB_OTG_DIEPMSK_BIM_Pos) /*!< 0x00000200 */ -#define USB_OTG_DIEPMSK_BIM USB_OTG_DIEPMSK_BIM_Msk /*!< BNA interrupt mask */ - -/******************** Bit definition for USB_OTG_HPTXSTS register ********************/ -#define USB_OTG_HPTXSTS_PTXFSAVL_Pos (0U) -#define USB_OTG_HPTXSTS_PTXFSAVL_Msk (0xFFFFUL << USB_OTG_HPTXSTS_PTXFSAVL_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_HPTXSTS_PTXFSAVL USB_OTG_HPTXSTS_PTXFSAVL_Msk /*!< Periodic transmit data FIFO space available */ -#define USB_OTG_HPTXSTS_PTXQSAV_Pos (16U) -#define USB_OTG_HPTXSTS_PTXQSAV_Msk (0xFFUL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00FF0000 */ -#define USB_OTG_HPTXSTS_PTXQSAV USB_OTG_HPTXSTS_PTXQSAV_Msk /*!< Periodic transmit request queue space available */ -#define USB_OTG_HPTXSTS_PTXQSAV_0 (0x01UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00010000 */ -#define USB_OTG_HPTXSTS_PTXQSAV_1 (0x02UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00020000 */ -#define USB_OTG_HPTXSTS_PTXQSAV_2 (0x04UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00040000 */ -#define USB_OTG_HPTXSTS_PTXQSAV_3 (0x08UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00080000 */ -#define USB_OTG_HPTXSTS_PTXQSAV_4 (0x10UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00100000 */ -#define USB_OTG_HPTXSTS_PTXQSAV_5 (0x20UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00200000 */ -#define USB_OTG_HPTXSTS_PTXQSAV_6 (0x40UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00400000 */ -#define USB_OTG_HPTXSTS_PTXQSAV_7 (0x80UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00800000 */ - -#define USB_OTG_HPTXSTS_PTXQTOP_Pos (24U) -#define USB_OTG_HPTXSTS_PTXQTOP_Msk (0xFFUL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0xFF000000 */ -#define USB_OTG_HPTXSTS_PTXQTOP USB_OTG_HPTXSTS_PTXQTOP_Msk /*!< Top of the periodic transmit request queue */ -#define USB_OTG_HPTXSTS_PTXQTOP_0 (0x01UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x01000000 */ -#define USB_OTG_HPTXSTS_PTXQTOP_1 (0x02UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x02000000 */ -#define USB_OTG_HPTXSTS_PTXQTOP_2 (0x04UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x04000000 */ -#define USB_OTG_HPTXSTS_PTXQTOP_3 (0x08UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x08000000 */ -#define USB_OTG_HPTXSTS_PTXQTOP_4 (0x10UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x10000000 */ -#define USB_OTG_HPTXSTS_PTXQTOP_5 (0x20UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x20000000 */ -#define USB_OTG_HPTXSTS_PTXQTOP_6 (0x40UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x40000000 */ -#define USB_OTG_HPTXSTS_PTXQTOP_7 (0x80UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x80000000 */ - -/******************** Bit definition for USB_OTG_HAINT register ********************/ -#define USB_OTG_HAINT_HAINT_Pos (0U) -#define USB_OTG_HAINT_HAINT_Msk (0xFFFFUL << USB_OTG_HAINT_HAINT_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_HAINT_HAINT USB_OTG_HAINT_HAINT_Msk /*!< Channel interrupts */ - -/******************** Bit definition for USB_OTG_DOEPMSK register ********************/ -#define USB_OTG_DOEPMSK_XFRCM_Pos (0U) -#define USB_OTG_DOEPMSK_XFRCM_Msk (0x1UL << USB_OTG_DOEPMSK_XFRCM_Pos) /*!< 0x00000001 */ -#define USB_OTG_DOEPMSK_XFRCM USB_OTG_DOEPMSK_XFRCM_Msk /*!< Transfer completed interrupt mask */ -#define USB_OTG_DOEPMSK_EPDM_Pos (1U) -#define USB_OTG_DOEPMSK_EPDM_Msk (0x1UL << USB_OTG_DOEPMSK_EPDM_Pos) /*!< 0x00000002 */ -#define USB_OTG_DOEPMSK_EPDM USB_OTG_DOEPMSK_EPDM_Msk /*!< Endpoint disabled interrupt mask */ -#define USB_OTG_DOEPMSK_AHBERRM_Pos (2U) -#define USB_OTG_DOEPMSK_AHBERRM_Msk (0x1UL << USB_OTG_DOEPMSK_AHBERRM_Pos) /*!< 0x00000004 */ -#define USB_OTG_DOEPMSK_AHBERRM USB_OTG_DOEPMSK_AHBERRM_Msk /*!< OUT transaction AHB Error interrupt mask */ -#define USB_OTG_DOEPMSK_STUPM_Pos (3U) -#define USB_OTG_DOEPMSK_STUPM_Msk (0x1UL << USB_OTG_DOEPMSK_STUPM_Pos) /*!< 0x00000008 */ -#define USB_OTG_DOEPMSK_STUPM USB_OTG_DOEPMSK_STUPM_Msk /*!< SETUP phase done mask */ -#define USB_OTG_DOEPMSK_OTEPDM_Pos (4U) -#define USB_OTG_DOEPMSK_OTEPDM_Msk (0x1UL << USB_OTG_DOEPMSK_OTEPDM_Pos) /*!< 0x00000010 */ -#define USB_OTG_DOEPMSK_OTEPDM USB_OTG_DOEPMSK_OTEPDM_Msk /*!< OUT token received when endpoint disabled mask */ -#define USB_OTG_DOEPMSK_OTEPSPRM_Pos (5U) -#define USB_OTG_DOEPMSK_OTEPSPRM_Msk (0x1UL << USB_OTG_DOEPMSK_OTEPSPRM_Pos) /*!< 0x00000020 */ -#define USB_OTG_DOEPMSK_OTEPSPRM USB_OTG_DOEPMSK_OTEPSPRM_Msk /*!< Status Phase Received mask */ -#define USB_OTG_DOEPMSK_B2BSTUP_Pos (6U) -#define USB_OTG_DOEPMSK_B2BSTUP_Msk (0x1UL << USB_OTG_DOEPMSK_B2BSTUP_Pos) /*!< 0x00000040 */ -#define USB_OTG_DOEPMSK_B2BSTUP USB_OTG_DOEPMSK_B2BSTUP_Msk /*!< Back-to-back SETUP packets received mask */ -#define USB_OTG_DOEPMSK_OPEM_Pos (8U) -#define USB_OTG_DOEPMSK_OPEM_Msk (0x1UL << USB_OTG_DOEPMSK_OPEM_Pos) /*!< 0x00000100 */ -#define USB_OTG_DOEPMSK_OPEM USB_OTG_DOEPMSK_OPEM_Msk /*!< OUT packet error mask */ -#define USB_OTG_DOEPMSK_BOIM_Pos (9U) -#define USB_OTG_DOEPMSK_BOIM_Msk (0x1UL << USB_OTG_DOEPMSK_BOIM_Pos) /*!< 0x00000200 */ -#define USB_OTG_DOEPMSK_BOIM USB_OTG_DOEPMSK_BOIM_Msk /*!< BNA interrupt mask */ -#define USB_OTG_DOEPMSK_BERRM_Pos (12U) -#define USB_OTG_DOEPMSK_BERRM_Msk (0x1UL << USB_OTG_DOEPMSK_BERRM_Pos) /*!< 0x00001000 */ -#define USB_OTG_DOEPMSK_BERRM USB_OTG_DOEPMSK_BERRM_Msk /*!< Babble error interrupt mask */ -#define USB_OTG_DOEPMSK_NAKM_Pos (13U) -#define USB_OTG_DOEPMSK_NAKM_Msk (0x1UL << USB_OTG_DOEPMSK_NAKM_Pos) /*!< 0x00002000 */ -#define USB_OTG_DOEPMSK_NAKM USB_OTG_DOEPMSK_NAKM_Msk /*!< OUT Packet NAK interrupt mask */ -#define USB_OTG_DOEPMSK_NYETM_Pos (14U) -#define USB_OTG_DOEPMSK_NYETM_Msk (0x1UL << USB_OTG_DOEPMSK_NYETM_Pos) /*!< 0x00004000 */ -#define USB_OTG_DOEPMSK_NYETM USB_OTG_DOEPMSK_NYETM_Msk /*!< NYET interrupt mask */ -/******************** Bit definition for USB_OTG_GINTSTS register ********************/ -#define USB_OTG_GINTSTS_CMOD_Pos (0U) -#define USB_OTG_GINTSTS_CMOD_Msk (0x1UL << USB_OTG_GINTSTS_CMOD_Pos) /*!< 0x00000001 */ -#define USB_OTG_GINTSTS_CMOD USB_OTG_GINTSTS_CMOD_Msk /*!< Current mode of operation */ -#define USB_OTG_GINTSTS_MMIS_Pos (1U) -#define USB_OTG_GINTSTS_MMIS_Msk (0x1UL << USB_OTG_GINTSTS_MMIS_Pos) /*!< 0x00000002 */ -#define USB_OTG_GINTSTS_MMIS USB_OTG_GINTSTS_MMIS_Msk /*!< Mode mismatch interrupt */ -#define USB_OTG_GINTSTS_OTGINT_Pos (2U) -#define USB_OTG_GINTSTS_OTGINT_Msk (0x1UL << USB_OTG_GINTSTS_OTGINT_Pos) /*!< 0x00000004 */ -#define USB_OTG_GINTSTS_OTGINT USB_OTG_GINTSTS_OTGINT_Msk /*!< OTG interrupt */ -#define USB_OTG_GINTSTS_SOF_Pos (3U) -#define USB_OTG_GINTSTS_SOF_Msk (0x1UL << USB_OTG_GINTSTS_SOF_Pos) /*!< 0x00000008 */ -#define USB_OTG_GINTSTS_SOF USB_OTG_GINTSTS_SOF_Msk /*!< Start of frame */ -#define USB_OTG_GINTSTS_RXFLVL_Pos (4U) -#define USB_OTG_GINTSTS_RXFLVL_Msk (0x1UL << USB_OTG_GINTSTS_RXFLVL_Pos) /*!< 0x00000010 */ -#define USB_OTG_GINTSTS_RXFLVL USB_OTG_GINTSTS_RXFLVL_Msk /*!< RxFIFO nonempty */ -#define USB_OTG_GINTSTS_NPTXFE_Pos (5U) -#define USB_OTG_GINTSTS_NPTXFE_Msk (0x1UL << USB_OTG_GINTSTS_NPTXFE_Pos) /*!< 0x00000020 */ -#define USB_OTG_GINTSTS_NPTXFE USB_OTG_GINTSTS_NPTXFE_Msk /*!< Nonperiodic TxFIFO empty */ -#define USB_OTG_GINTSTS_GINAKEFF_Pos (6U) -#define USB_OTG_GINTSTS_GINAKEFF_Msk (0x1UL << USB_OTG_GINTSTS_GINAKEFF_Pos) /*!< 0x00000040 */ -#define USB_OTG_GINTSTS_GINAKEFF USB_OTG_GINTSTS_GINAKEFF_Msk /*!< Global IN nonperiodic NAK effective */ -#define USB_OTG_GINTSTS_BOUTNAKEFF_Pos (7U) -#define USB_OTG_GINTSTS_BOUTNAKEFF_Msk (0x1UL << USB_OTG_GINTSTS_BOUTNAKEFF_Pos) /*!< 0x00000080 */ -#define USB_OTG_GINTSTS_BOUTNAKEFF USB_OTG_GINTSTS_BOUTNAKEFF_Msk /*!< Global OUT NAK effective */ -#define USB_OTG_GINTSTS_ESUSP_Pos (10U) -#define USB_OTG_GINTSTS_ESUSP_Msk (0x1UL << USB_OTG_GINTSTS_ESUSP_Pos) /*!< 0x00000400 */ -#define USB_OTG_GINTSTS_ESUSP USB_OTG_GINTSTS_ESUSP_Msk /*!< Early suspend */ -#define USB_OTG_GINTSTS_USBSUSP_Pos (11U) -#define USB_OTG_GINTSTS_USBSUSP_Msk (0x1UL << USB_OTG_GINTSTS_USBSUSP_Pos) /*!< 0x00000800 */ -#define USB_OTG_GINTSTS_USBSUSP USB_OTG_GINTSTS_USBSUSP_Msk /*!< USB suspend */ -#define USB_OTG_GINTSTS_USBRST_Pos (12U) -#define USB_OTG_GINTSTS_USBRST_Msk (0x1UL << USB_OTG_GINTSTS_USBRST_Pos) /*!< 0x00001000 */ -#define USB_OTG_GINTSTS_USBRST USB_OTG_GINTSTS_USBRST_Msk /*!< USB reset */ -#define USB_OTG_GINTSTS_ENUMDNE_Pos (13U) -#define USB_OTG_GINTSTS_ENUMDNE_Msk (0x1UL << USB_OTG_GINTSTS_ENUMDNE_Pos) /*!< 0x00002000 */ -#define USB_OTG_GINTSTS_ENUMDNE USB_OTG_GINTSTS_ENUMDNE_Msk /*!< Enumeration done */ -#define USB_OTG_GINTSTS_ISOODRP_Pos (14U) -#define USB_OTG_GINTSTS_ISOODRP_Msk (0x1UL << USB_OTG_GINTSTS_ISOODRP_Pos) /*!< 0x00004000 */ -#define USB_OTG_GINTSTS_ISOODRP USB_OTG_GINTSTS_ISOODRP_Msk /*!< Isochronous OUT packet dropped interrupt */ -#define USB_OTG_GINTSTS_EOPF_Pos (15U) -#define USB_OTG_GINTSTS_EOPF_Msk (0x1UL << USB_OTG_GINTSTS_EOPF_Pos) /*!< 0x00008000 */ -#define USB_OTG_GINTSTS_EOPF USB_OTG_GINTSTS_EOPF_Msk /*!< End of periodic frame interrupt */ -#define USB_OTG_GINTSTS_IEPINT_Pos (18U) -#define USB_OTG_GINTSTS_IEPINT_Msk (0x1UL << USB_OTG_GINTSTS_IEPINT_Pos) /*!< 0x00040000 */ -#define USB_OTG_GINTSTS_IEPINT USB_OTG_GINTSTS_IEPINT_Msk /*!< IN endpoint interrupt */ -#define USB_OTG_GINTSTS_OEPINT_Pos (19U) -#define USB_OTG_GINTSTS_OEPINT_Msk (0x1UL << USB_OTG_GINTSTS_OEPINT_Pos) /*!< 0x00080000 */ -#define USB_OTG_GINTSTS_OEPINT USB_OTG_GINTSTS_OEPINT_Msk /*!< OUT endpoint interrupt */ -#define USB_OTG_GINTSTS_IISOIXFR_Pos (20U) -#define USB_OTG_GINTSTS_IISOIXFR_Msk (0x1UL << USB_OTG_GINTSTS_IISOIXFR_Pos) /*!< 0x00100000 */ -#define USB_OTG_GINTSTS_IISOIXFR USB_OTG_GINTSTS_IISOIXFR_Msk /*!< Incomplete isochronous IN transfer */ -#define USB_OTG_GINTSTS_PXFR_INCOMPISOOUT_Pos (21U) -#define USB_OTG_GINTSTS_PXFR_INCOMPISOOUT_Msk (0x1UL << USB_OTG_GINTSTS_PXFR_INCOMPISOOUT_Pos) /*!< 0x00200000 */ -#define USB_OTG_GINTSTS_PXFR_INCOMPISOOUT USB_OTG_GINTSTS_PXFR_INCOMPISOOUT_Msk /*!< Incomplete periodic transfer */ -#define USB_OTG_GINTSTS_DATAFSUSP_Pos (22U) -#define USB_OTG_GINTSTS_DATAFSUSP_Msk (0x1UL << USB_OTG_GINTSTS_DATAFSUSP_Pos) /*!< 0x00400000 */ -#define USB_OTG_GINTSTS_DATAFSUSP USB_OTG_GINTSTS_DATAFSUSP_Msk /*!< Data fetch suspended */ -#define USB_OTG_GINTSTS_HPRTINT_Pos (24U) -#define USB_OTG_GINTSTS_HPRTINT_Msk (0x1UL << USB_OTG_GINTSTS_HPRTINT_Pos) /*!< 0x01000000 */ -#define USB_OTG_GINTSTS_HPRTINT USB_OTG_GINTSTS_HPRTINT_Msk /*!< Host port interrupt */ -#define USB_OTG_GINTSTS_HCINT_Pos (25U) -#define USB_OTG_GINTSTS_HCINT_Msk (0x1UL << USB_OTG_GINTSTS_HCINT_Pos) /*!< 0x02000000 */ -#define USB_OTG_GINTSTS_HCINT USB_OTG_GINTSTS_HCINT_Msk /*!< Host channels interrupt */ -#define USB_OTG_GINTSTS_PTXFE_Pos (26U) -#define USB_OTG_GINTSTS_PTXFE_Msk (0x1UL << USB_OTG_GINTSTS_PTXFE_Pos) /*!< 0x04000000 */ -#define USB_OTG_GINTSTS_PTXFE USB_OTG_GINTSTS_PTXFE_Msk /*!< Periodic TxFIFO empty */ -#define USB_OTG_GINTSTS_CIDSCHG_Pos (28U) -#define USB_OTG_GINTSTS_CIDSCHG_Msk (0x1UL << USB_OTG_GINTSTS_CIDSCHG_Pos) /*!< 0x10000000 */ -#define USB_OTG_GINTSTS_CIDSCHG USB_OTG_GINTSTS_CIDSCHG_Msk /*!< Connector ID status change */ -#define USB_OTG_GINTSTS_DISCINT_Pos (29U) -#define USB_OTG_GINTSTS_DISCINT_Msk (0x1UL << USB_OTG_GINTSTS_DISCINT_Pos) /*!< 0x20000000 */ -#define USB_OTG_GINTSTS_DISCINT USB_OTG_GINTSTS_DISCINT_Msk /*!< Disconnect detected interrupt */ -#define USB_OTG_GINTSTS_SRQINT_Pos (30U) -#define USB_OTG_GINTSTS_SRQINT_Msk (0x1UL << USB_OTG_GINTSTS_SRQINT_Pos) /*!< 0x40000000 */ -#define USB_OTG_GINTSTS_SRQINT USB_OTG_GINTSTS_SRQINT_Msk /*!< Session request/new session detected interrupt */ -#define USB_OTG_GINTSTS_WKUINT_Pos (31U) -#define USB_OTG_GINTSTS_WKUINT_Msk (0x1UL << USB_OTG_GINTSTS_WKUINT_Pos) /*!< 0x80000000 */ -#define USB_OTG_GINTSTS_WKUINT USB_OTG_GINTSTS_WKUINT_Msk /*!< Resume/remote wakeup detected interrupt */ - -/******************** Bit definition for USB_OTG_GINTMSK register ********************/ -#define USB_OTG_GINTMSK_MMISM_Pos (1U) -#define USB_OTG_GINTMSK_MMISM_Msk (0x1UL << USB_OTG_GINTMSK_MMISM_Pos) /*!< 0x00000002 */ -#define USB_OTG_GINTMSK_MMISM USB_OTG_GINTMSK_MMISM_Msk /*!< Mode mismatch interrupt mask */ -#define USB_OTG_GINTMSK_OTGINT_Pos (2U) -#define USB_OTG_GINTMSK_OTGINT_Msk (0x1UL << USB_OTG_GINTMSK_OTGINT_Pos) /*!< 0x00000004 */ -#define USB_OTG_GINTMSK_OTGINT USB_OTG_GINTMSK_OTGINT_Msk /*!< OTG interrupt mask */ -#define USB_OTG_GINTMSK_SOFM_Pos (3U) -#define USB_OTG_GINTMSK_SOFM_Msk (0x1UL << USB_OTG_GINTMSK_SOFM_Pos) /*!< 0x00000008 */ -#define USB_OTG_GINTMSK_SOFM USB_OTG_GINTMSK_SOFM_Msk /*!< Start of frame mask */ -#define USB_OTG_GINTMSK_RXFLVLM_Pos (4U) -#define USB_OTG_GINTMSK_RXFLVLM_Msk (0x1UL << USB_OTG_GINTMSK_RXFLVLM_Pos) /*!< 0x00000010 */ -#define USB_OTG_GINTMSK_RXFLVLM USB_OTG_GINTMSK_RXFLVLM_Msk /*!< Receive FIFO nonempty mask */ -#define USB_OTG_GINTMSK_NPTXFEM_Pos (5U) -#define USB_OTG_GINTMSK_NPTXFEM_Msk (0x1UL << USB_OTG_GINTMSK_NPTXFEM_Pos) /*!< 0x00000020 */ -#define USB_OTG_GINTMSK_NPTXFEM USB_OTG_GINTMSK_NPTXFEM_Msk /*!< Nonperiodic TxFIFO empty mask */ -#define USB_OTG_GINTMSK_GINAKEFFM_Pos (6U) -#define USB_OTG_GINTMSK_GINAKEFFM_Msk (0x1UL << USB_OTG_GINTMSK_GINAKEFFM_Pos) /*!< 0x00000040 */ -#define USB_OTG_GINTMSK_GINAKEFFM USB_OTG_GINTMSK_GINAKEFFM_Msk /*!< Global nonperiodic IN NAK effective mask */ -#define USB_OTG_GINTMSK_GONAKEFFM_Pos (7U) -#define USB_OTG_GINTMSK_GONAKEFFM_Msk (0x1UL << USB_OTG_GINTMSK_GONAKEFFM_Pos) /*!< 0x00000080 */ -#define USB_OTG_GINTMSK_GONAKEFFM USB_OTG_GINTMSK_GONAKEFFM_Msk /*!< Global OUT NAK effective mask */ -#define USB_OTG_GINTMSK_ESUSPM_Pos (10U) -#define USB_OTG_GINTMSK_ESUSPM_Msk (0x1UL << USB_OTG_GINTMSK_ESUSPM_Pos) /*!< 0x00000400 */ -#define USB_OTG_GINTMSK_ESUSPM USB_OTG_GINTMSK_ESUSPM_Msk /*!< Early suspend mask */ -#define USB_OTG_GINTMSK_USBSUSPM_Pos (11U) -#define USB_OTG_GINTMSK_USBSUSPM_Msk (0x1UL << USB_OTG_GINTMSK_USBSUSPM_Pos) /*!< 0x00000800 */ -#define USB_OTG_GINTMSK_USBSUSPM USB_OTG_GINTMSK_USBSUSPM_Msk /*!< USB suspend mask */ -#define USB_OTG_GINTMSK_USBRST_Pos (12U) -#define USB_OTG_GINTMSK_USBRST_Msk (0x1UL << USB_OTG_GINTMSK_USBRST_Pos) /*!< 0x00001000 */ -#define USB_OTG_GINTMSK_USBRST USB_OTG_GINTMSK_USBRST_Msk /*!< USB reset mask */ -#define USB_OTG_GINTMSK_ENUMDNEM_Pos (13U) -#define USB_OTG_GINTMSK_ENUMDNEM_Msk (0x1UL << USB_OTG_GINTMSK_ENUMDNEM_Pos) /*!< 0x00002000 */ -#define USB_OTG_GINTMSK_ENUMDNEM USB_OTG_GINTMSK_ENUMDNEM_Msk /*!< Enumeration done mask */ -#define USB_OTG_GINTMSK_ISOODRPM_Pos (14U) -#define USB_OTG_GINTMSK_ISOODRPM_Msk (0x1UL << USB_OTG_GINTMSK_ISOODRPM_Pos) /*!< 0x00004000 */ -#define USB_OTG_GINTMSK_ISOODRPM USB_OTG_GINTMSK_ISOODRPM_Msk /*!< Isochronous OUT packet dropped interrupt mask */ -#define USB_OTG_GINTMSK_EOPFM_Pos (15U) -#define USB_OTG_GINTMSK_EOPFM_Msk (0x1UL << USB_OTG_GINTMSK_EOPFM_Pos) /*!< 0x00008000 */ -#define USB_OTG_GINTMSK_EOPFM USB_OTG_GINTMSK_EOPFM_Msk /*!< End of periodic frame interrupt mask */ -#define USB_OTG_GINTMSK_EPMISM_Pos (17U) -#define USB_OTG_GINTMSK_EPMISM_Msk (0x1UL << USB_OTG_GINTMSK_EPMISM_Pos) /*!< 0x00020000 */ -#define USB_OTG_GINTMSK_EPMISM USB_OTG_GINTMSK_EPMISM_Msk /*!< Endpoint mismatch interrupt mask */ -#define USB_OTG_GINTMSK_IEPINT_Pos (18U) -#define USB_OTG_GINTMSK_IEPINT_Msk (0x1UL << USB_OTG_GINTMSK_IEPINT_Pos) /*!< 0x00040000 */ -#define USB_OTG_GINTMSK_IEPINT USB_OTG_GINTMSK_IEPINT_Msk /*!< IN endpoints interrupt mask */ -#define USB_OTG_GINTMSK_OEPINT_Pos (19U) -#define USB_OTG_GINTMSK_OEPINT_Msk (0x1UL << USB_OTG_GINTMSK_OEPINT_Pos) /*!< 0x00080000 */ -#define USB_OTG_GINTMSK_OEPINT USB_OTG_GINTMSK_OEPINT_Msk /*!< OUT endpoints interrupt mask */ -#define USB_OTG_GINTMSK_IISOIXFRM_Pos (20U) -#define USB_OTG_GINTMSK_IISOIXFRM_Msk (0x1UL << USB_OTG_GINTMSK_IISOIXFRM_Pos) /*!< 0x00100000 */ -#define USB_OTG_GINTMSK_IISOIXFRM USB_OTG_GINTMSK_IISOIXFRM_Msk /*!< Incomplete isochronous IN transfer mask */ -#define USB_OTG_GINTMSK_PXFRM_IISOOXFRM_Pos (21U) -#define USB_OTG_GINTMSK_PXFRM_IISOOXFRM_Msk (0x1UL << USB_OTG_GINTMSK_PXFRM_IISOOXFRM_Pos) /*!< 0x00200000 */ -#define USB_OTG_GINTMSK_PXFRM_IISOOXFRM USB_OTG_GINTMSK_PXFRM_IISOOXFRM_Msk /*!< Incomplete periodic transfer mask */ -#define USB_OTG_GINTMSK_FSUSPM_Pos (22U) -#define USB_OTG_GINTMSK_FSUSPM_Msk (0x1UL << USB_OTG_GINTMSK_FSUSPM_Pos) /*!< 0x00400000 */ -#define USB_OTG_GINTMSK_FSUSPM USB_OTG_GINTMSK_FSUSPM_Msk /*!< Data fetch suspended mask */ -#define USB_OTG_GINTMSK_PRTIM_Pos (24U) -#define USB_OTG_GINTMSK_PRTIM_Msk (0x1UL << USB_OTG_GINTMSK_PRTIM_Pos) /*!< 0x01000000 */ -#define USB_OTG_GINTMSK_PRTIM USB_OTG_GINTMSK_PRTIM_Msk /*!< Host port interrupt mask */ -#define USB_OTG_GINTMSK_HCIM_Pos (25U) -#define USB_OTG_GINTMSK_HCIM_Msk (0x1UL << USB_OTG_GINTMSK_HCIM_Pos) /*!< 0x02000000 */ -#define USB_OTG_GINTMSK_HCIM USB_OTG_GINTMSK_HCIM_Msk /*!< Host channels interrupt mask */ -#define USB_OTG_GINTMSK_PTXFEM_Pos (26U) -#define USB_OTG_GINTMSK_PTXFEM_Msk (0x1UL << USB_OTG_GINTMSK_PTXFEM_Pos) /*!< 0x04000000 */ -#define USB_OTG_GINTMSK_PTXFEM USB_OTG_GINTMSK_PTXFEM_Msk /*!< Periodic TxFIFO empty mask */ -#define USB_OTG_GINTMSK_CIDSCHGM_Pos (28U) -#define USB_OTG_GINTMSK_CIDSCHGM_Msk (0x1UL << USB_OTG_GINTMSK_CIDSCHGM_Pos) /*!< 0x10000000 */ -#define USB_OTG_GINTMSK_CIDSCHGM USB_OTG_GINTMSK_CIDSCHGM_Msk /*!< Connector ID status change mask */ -#define USB_OTG_GINTMSK_DISCINT_Pos (29U) -#define USB_OTG_GINTMSK_DISCINT_Msk (0x1UL << USB_OTG_GINTMSK_DISCINT_Pos) /*!< 0x20000000 */ -#define USB_OTG_GINTMSK_DISCINT USB_OTG_GINTMSK_DISCINT_Msk /*!< Disconnect detected interrupt mask */ -#define USB_OTG_GINTMSK_SRQIM_Pos (30U) -#define USB_OTG_GINTMSK_SRQIM_Msk (0x1UL << USB_OTG_GINTMSK_SRQIM_Pos) /*!< 0x40000000 */ -#define USB_OTG_GINTMSK_SRQIM USB_OTG_GINTMSK_SRQIM_Msk /*!< Session request/new session detected interrupt mask */ -#define USB_OTG_GINTMSK_WUIM_Pos (31U) -#define USB_OTG_GINTMSK_WUIM_Msk (0x1UL << USB_OTG_GINTMSK_WUIM_Pos) /*!< 0x80000000 */ -#define USB_OTG_GINTMSK_WUIM USB_OTG_GINTMSK_WUIM_Msk /*!< Resume/remote wakeup detected interrupt mask */ - -/******************** Bit definition for USB_OTG_DAINT register ********************/ -#define USB_OTG_DAINT_IEPINT_Pos (0U) -#define USB_OTG_DAINT_IEPINT_Msk (0xFFFFUL << USB_OTG_DAINT_IEPINT_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_DAINT_IEPINT USB_OTG_DAINT_IEPINT_Msk /*!< IN endpoint interrupt bits */ -#define USB_OTG_DAINT_OEPINT_Pos (16U) -#define USB_OTG_DAINT_OEPINT_Msk (0xFFFFUL << USB_OTG_DAINT_OEPINT_Pos) /*!< 0xFFFF0000 */ -#define USB_OTG_DAINT_OEPINT USB_OTG_DAINT_OEPINT_Msk /*!< OUT endpoint interrupt bits */ - -/******************** Bit definition for USB_OTG_HAINTMSK register ********************/ -#define USB_OTG_HAINTMSK_HAINTM_Pos (0U) -#define USB_OTG_HAINTMSK_HAINTM_Msk (0xFFFFUL << USB_OTG_HAINTMSK_HAINTM_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_HAINTMSK_HAINTM USB_OTG_HAINTMSK_HAINTM_Msk /*!< Channel interrupt mask */ - -/******************** Bit definition for USB_OTG_GRXSTSP register ********************/ -#define USB_OTG_GRXSTSP_EPNUM_Pos (0U) -#define USB_OTG_GRXSTSP_EPNUM_Msk (0xFUL << USB_OTG_GRXSTSP_EPNUM_Pos) /*!< 0x0000000F */ -#define USB_OTG_GRXSTSP_EPNUM USB_OTG_GRXSTSP_EPNUM_Msk /*!< IN EP interrupt mask bits */ -#define USB_OTG_GRXSTSP_BCNT_Pos (4U) -#define USB_OTG_GRXSTSP_BCNT_Msk (0x7FFUL << USB_OTG_GRXSTSP_BCNT_Pos) /*!< 0x00007FF0 */ -#define USB_OTG_GRXSTSP_BCNT USB_OTG_GRXSTSP_BCNT_Msk /*!< OUT EP interrupt mask bits */ -#define USB_OTG_GRXSTSP_DPID_Pos (15U) -#define USB_OTG_GRXSTSP_DPID_Msk (0x3UL << USB_OTG_GRXSTSP_DPID_Pos) /*!< 0x00018000 */ -#define USB_OTG_GRXSTSP_DPID USB_OTG_GRXSTSP_DPID_Msk /*!< OUT EP interrupt mask bits */ -#define USB_OTG_GRXSTSP_PKTSTS_Pos (17U) -#define USB_OTG_GRXSTSP_PKTSTS_Msk (0xFUL << USB_OTG_GRXSTSP_PKTSTS_Pos) /*!< 0x001E0000 */ -#define USB_OTG_GRXSTSP_PKTSTS USB_OTG_GRXSTSP_PKTSTS_Msk /*!< OUT EP interrupt mask bits */ - -/******************** Bit definition for USB_OTG_DAINTMSK register ********************/ -#define USB_OTG_DAINTMSK_IEPM_Pos (0U) -#define USB_OTG_DAINTMSK_IEPM_Msk (0xFFFFUL << USB_OTG_DAINTMSK_IEPM_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_DAINTMSK_IEPM USB_OTG_DAINTMSK_IEPM_Msk /*!< IN EP interrupt mask bits */ -#define USB_OTG_DAINTMSK_OEPM_Pos (16U) -#define USB_OTG_DAINTMSK_OEPM_Msk (0xFFFFUL << USB_OTG_DAINTMSK_OEPM_Pos) /*!< 0xFFFF0000 */ -#define USB_OTG_DAINTMSK_OEPM USB_OTG_DAINTMSK_OEPM_Msk /*!< OUT EP interrupt mask bits */ - -/******************** Bit definition for USB_OTG_GRXFSIZ register ********************/ -#define USB_OTG_GRXFSIZ_RXFD_Pos (0U) -#define USB_OTG_GRXFSIZ_RXFD_Msk (0xFFFFUL << USB_OTG_GRXFSIZ_RXFD_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_GRXFSIZ_RXFD USB_OTG_GRXFSIZ_RXFD_Msk /*!< RxFIFO depth */ - -/******************** Bit definition for USB_OTG_DVBUSDIS register ********************/ -#define USB_OTG_DVBUSDIS_VBUSDT_Pos (0U) -#define USB_OTG_DVBUSDIS_VBUSDT_Msk (0xFFFFUL << USB_OTG_DVBUSDIS_VBUSDT_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_DVBUSDIS_VBUSDT USB_OTG_DVBUSDIS_VBUSDT_Msk /*!< Device VBUS discharge time */ - -/******************** Bit definition for OTG register ********************/ -#define USB_OTG_NPTXFSA_Pos (0U) -#define USB_OTG_NPTXFSA_Msk (0xFFFFUL << USB_OTG_NPTXFSA_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_NPTXFSA USB_OTG_NPTXFSA_Msk /*!< Nonperiodic transmit RAM start address */ -#define USB_OTG_NPTXFD_Pos (16U) -#define USB_OTG_NPTXFD_Msk (0xFFFFUL << USB_OTG_NPTXFD_Pos) /*!< 0xFFFF0000 */ -#define USB_OTG_NPTXFD USB_OTG_NPTXFD_Msk /*!< Nonperiodic TxFIFO depth */ -#define USB_OTG_TX0FSA_Pos (0U) -#define USB_OTG_TX0FSA_Msk (0xFFFFUL << USB_OTG_TX0FSA_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_TX0FSA USB_OTG_TX0FSA_Msk /*!< Endpoint 0 transmit RAM start address */ -#define USB_OTG_TX0FD_Pos (16U) -#define USB_OTG_TX0FD_Msk (0xFFFFUL << USB_OTG_TX0FD_Pos) /*!< 0xFFFF0000 */ -#define USB_OTG_TX0FD USB_OTG_TX0FD_Msk /*!< Endpoint 0 TxFIFO depth */ - -/******************** Bit definition for USB_OTG_DVBUSPULSE register ********************/ -#define USB_OTG_DVBUSPULSE_DVBUSP_Pos (0U) -#define USB_OTG_DVBUSPULSE_DVBUSP_Msk (0xFFFUL << USB_OTG_DVBUSPULSE_DVBUSP_Pos) /*!< 0x00000FFF */ -#define USB_OTG_DVBUSPULSE_DVBUSP USB_OTG_DVBUSPULSE_DVBUSP_Msk /*!< Device VBUS pulsing time */ - -/******************** Bit definition for USB_OTG_GNPTXSTS register ********************/ -#define USB_OTG_GNPTXSTS_NPTXFSAV_Pos (0U) -#define USB_OTG_GNPTXSTS_NPTXFSAV_Msk (0xFFFFUL << USB_OTG_GNPTXSTS_NPTXFSAV_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_GNPTXSTS_NPTXFSAV USB_OTG_GNPTXSTS_NPTXFSAV_Msk /*!< Nonperiodic TxFIFO space available */ - -#define USB_OTG_GNPTXSTS_NPTQXSAV_Pos (16U) -#define USB_OTG_GNPTXSTS_NPTQXSAV_Msk (0xFFUL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00FF0000 */ -#define USB_OTG_GNPTXSTS_NPTQXSAV USB_OTG_GNPTXSTS_NPTQXSAV_Msk /*!< Nonperiodic transmit request queue space available */ -#define USB_OTG_GNPTXSTS_NPTQXSAV_0 (0x01UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00010000 */ -#define USB_OTG_GNPTXSTS_NPTQXSAV_1 (0x02UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00020000 */ -#define USB_OTG_GNPTXSTS_NPTQXSAV_2 (0x04UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00040000 */ -#define USB_OTG_GNPTXSTS_NPTQXSAV_3 (0x08UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00080000 */ -#define USB_OTG_GNPTXSTS_NPTQXSAV_4 (0x10UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00100000 */ -#define USB_OTG_GNPTXSTS_NPTQXSAV_5 (0x20UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00200000 */ -#define USB_OTG_GNPTXSTS_NPTQXSAV_6 (0x40UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00400000 */ -#define USB_OTG_GNPTXSTS_NPTQXSAV_7 (0x80UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00800000 */ - -#define USB_OTG_GNPTXSTS_NPTXQTOP_Pos (24U) -#define USB_OTG_GNPTXSTS_NPTXQTOP_Msk (0x7FUL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x7F000000 */ -#define USB_OTG_GNPTXSTS_NPTXQTOP USB_OTG_GNPTXSTS_NPTXQTOP_Msk /*!< Top of the nonperiodic transmit request queue */ -#define USB_OTG_GNPTXSTS_NPTXQTOP_0 (0x01UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x01000000 */ -#define USB_OTG_GNPTXSTS_NPTXQTOP_1 (0x02UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x02000000 */ -#define USB_OTG_GNPTXSTS_NPTXQTOP_2 (0x04UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x04000000 */ -#define USB_OTG_GNPTXSTS_NPTXQTOP_3 (0x08UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x08000000 */ -#define USB_OTG_GNPTXSTS_NPTXQTOP_4 (0x10UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x10000000 */ -#define USB_OTG_GNPTXSTS_NPTXQTOP_5 (0x20UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x20000000 */ -#define USB_OTG_GNPTXSTS_NPTXQTOP_6 (0x40UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x40000000 */ - -/******************** Bit definition for USB_OTG_DTHRCTL register ********************/ -#define USB_OTG_DTHRCTL_NONISOTHREN_Pos (0U) -#define USB_OTG_DTHRCTL_NONISOTHREN_Msk (0x1UL << USB_OTG_DTHRCTL_NONISOTHREN_Pos) /*!< 0x00000001 */ -#define USB_OTG_DTHRCTL_NONISOTHREN USB_OTG_DTHRCTL_NONISOTHREN_Msk /*!< Nonisochronous IN endpoints threshold enable */ -#define USB_OTG_DTHRCTL_ISOTHREN_Pos (1U) -#define USB_OTG_DTHRCTL_ISOTHREN_Msk (0x1UL << USB_OTG_DTHRCTL_ISOTHREN_Pos) /*!< 0x00000002 */ -#define USB_OTG_DTHRCTL_ISOTHREN USB_OTG_DTHRCTL_ISOTHREN_Msk /*!< ISO IN endpoint threshold enable */ - -#define USB_OTG_DTHRCTL_TXTHRLEN_Pos (2U) -#define USB_OTG_DTHRCTL_TXTHRLEN_Msk (0x1FFUL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x000007FC */ -#define USB_OTG_DTHRCTL_TXTHRLEN USB_OTG_DTHRCTL_TXTHRLEN_Msk /*!< Transmit threshold length */ -#define USB_OTG_DTHRCTL_TXTHRLEN_0 (0x001UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000004 */ -#define USB_OTG_DTHRCTL_TXTHRLEN_1 (0x002UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000008 */ -#define USB_OTG_DTHRCTL_TXTHRLEN_2 (0x004UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000010 */ -#define USB_OTG_DTHRCTL_TXTHRLEN_3 (0x008UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000020 */ -#define USB_OTG_DTHRCTL_TXTHRLEN_4 (0x010UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000040 */ -#define USB_OTG_DTHRCTL_TXTHRLEN_5 (0x020UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000080 */ -#define USB_OTG_DTHRCTL_TXTHRLEN_6 (0x040UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000100 */ -#define USB_OTG_DTHRCTL_TXTHRLEN_7 (0x080UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000200 */ -#define USB_OTG_DTHRCTL_TXTHRLEN_8 (0x100UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000400 */ -#define USB_OTG_DTHRCTL_RXTHREN_Pos (16U) -#define USB_OTG_DTHRCTL_RXTHREN_Msk (0x1UL << USB_OTG_DTHRCTL_RXTHREN_Pos) /*!< 0x00010000 */ -#define USB_OTG_DTHRCTL_RXTHREN USB_OTG_DTHRCTL_RXTHREN_Msk /*!< Receive threshold enable */ - -#define USB_OTG_DTHRCTL_RXTHRLEN_Pos (17U) -#define USB_OTG_DTHRCTL_RXTHRLEN_Msk (0x1FFUL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x03FE0000 */ -#define USB_OTG_DTHRCTL_RXTHRLEN USB_OTG_DTHRCTL_RXTHRLEN_Msk /*!< Receive threshold length */ -#define USB_OTG_DTHRCTL_RXTHRLEN_0 (0x001UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00020000 */ -#define USB_OTG_DTHRCTL_RXTHRLEN_1 (0x002UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00040000 */ -#define USB_OTG_DTHRCTL_RXTHRLEN_2 (0x004UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00080000 */ -#define USB_OTG_DTHRCTL_RXTHRLEN_3 (0x008UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00100000 */ -#define USB_OTG_DTHRCTL_RXTHRLEN_4 (0x010UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00200000 */ -#define USB_OTG_DTHRCTL_RXTHRLEN_5 (0x020UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00400000 */ -#define USB_OTG_DTHRCTL_RXTHRLEN_6 (0x040UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00800000 */ -#define USB_OTG_DTHRCTL_RXTHRLEN_7 (0x080UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x01000000 */ -#define USB_OTG_DTHRCTL_RXTHRLEN_8 (0x100UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x02000000 */ -#define USB_OTG_DTHRCTL_ARPEN_Pos (27U) -#define USB_OTG_DTHRCTL_ARPEN_Msk (0x1UL << USB_OTG_DTHRCTL_ARPEN_Pos) /*!< 0x08000000 */ -#define USB_OTG_DTHRCTL_ARPEN USB_OTG_DTHRCTL_ARPEN_Msk /*!< Arbiter parking enable */ - -/******************** Bit definition for USB_OTG_DIEPEMPMSK register ********************/ -#define USB_OTG_DIEPEMPMSK_INEPTXFEM_Pos (0U) -#define USB_OTG_DIEPEMPMSK_INEPTXFEM_Msk (0xFFFFUL << USB_OTG_DIEPEMPMSK_INEPTXFEM_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_DIEPEMPMSK_INEPTXFEM USB_OTG_DIEPEMPMSK_INEPTXFEM_Msk /*!< IN EP Tx FIFO empty interrupt mask bits */ - -/******************** Bit definition for USB_OTG_DEACHINT register ********************/ -#define USB_OTG_DEACHINT_IEP1INT_Pos (1U) -#define USB_OTG_DEACHINT_IEP1INT_Msk (0x1UL << USB_OTG_DEACHINT_IEP1INT_Pos) /*!< 0x00000002 */ -#define USB_OTG_DEACHINT_IEP1INT USB_OTG_DEACHINT_IEP1INT_Msk /*!< IN endpoint 1interrupt bit */ -#define USB_OTG_DEACHINT_OEP1INT_Pos (17U) -#define USB_OTG_DEACHINT_OEP1INT_Msk (0x1UL << USB_OTG_DEACHINT_OEP1INT_Pos) /*!< 0x00020000 */ -#define USB_OTG_DEACHINT_OEP1INT USB_OTG_DEACHINT_OEP1INT_Msk /*!< OUT endpoint 1 interrupt bit */ - -/******************** Bit definition for USB_OTG_GCCFG register ********************/ -#define USB_OTG_GCCFG_PWRDWN_Pos (16U) -#define USB_OTG_GCCFG_PWRDWN_Msk (0x1UL << USB_OTG_GCCFG_PWRDWN_Pos) /*!< 0x00010000 */ -#define USB_OTG_GCCFG_PWRDWN USB_OTG_GCCFG_PWRDWN_Msk /*!< Power down */ -#define USB_OTG_GCCFG_VBUSASEN_Pos (18U) -#define USB_OTG_GCCFG_VBUSASEN_Msk (0x1UL << USB_OTG_GCCFG_VBUSASEN_Pos) /*!< 0x00040000 */ -#define USB_OTG_GCCFG_VBUSASEN USB_OTG_GCCFG_VBUSASEN_Msk /*!< Enable the VBUS sensing device */ -#define USB_OTG_GCCFG_VBUSBSEN_Pos (19U) -#define USB_OTG_GCCFG_VBUSBSEN_Msk (0x1UL << USB_OTG_GCCFG_VBUSBSEN_Pos) /*!< 0x00080000 */ -#define USB_OTG_GCCFG_VBUSBSEN USB_OTG_GCCFG_VBUSBSEN_Msk /*!< Enable the VBUS sensing device */ -#define USB_OTG_GCCFG_SOFOUTEN_Pos (20U) -#define USB_OTG_GCCFG_SOFOUTEN_Msk (0x1UL << USB_OTG_GCCFG_SOFOUTEN_Pos) /*!< 0x00100000 */ -#define USB_OTG_GCCFG_SOFOUTEN USB_OTG_GCCFG_SOFOUTEN_Msk /*!< SOF output enable */ - -/******************** Bit definition for USB_OTG_DEACHINTMSK register ********************/ -#define USB_OTG_DEACHINTMSK_IEP1INTM_Pos (1U) -#define USB_OTG_DEACHINTMSK_IEP1INTM_Msk (0x1UL << USB_OTG_DEACHINTMSK_IEP1INTM_Pos) /*!< 0x00000002 */ -#define USB_OTG_DEACHINTMSK_IEP1INTM USB_OTG_DEACHINTMSK_IEP1INTM_Msk /*!< IN Endpoint 1 interrupt mask bit */ -#define USB_OTG_DEACHINTMSK_OEP1INTM_Pos (17U) -#define USB_OTG_DEACHINTMSK_OEP1INTM_Msk (0x1UL << USB_OTG_DEACHINTMSK_OEP1INTM_Pos) /*!< 0x00020000 */ -#define USB_OTG_DEACHINTMSK_OEP1INTM USB_OTG_DEACHINTMSK_OEP1INTM_Msk /*!< OUT Endpoint 1 interrupt mask bit */ - -/******************** Bit definition for USB_OTG_CID register ********************/ -#define USB_OTG_CID_PRODUCT_ID_Pos (0U) -#define USB_OTG_CID_PRODUCT_ID_Msk (0xFFFFFFFFUL << USB_OTG_CID_PRODUCT_ID_Pos) /*!< 0xFFFFFFFF */ -#define USB_OTG_CID_PRODUCT_ID USB_OTG_CID_PRODUCT_ID_Msk /*!< Product ID field */ - -/******************** Bit definition for USB_OTG_DIEPEACHMSK1 register ********************/ -#define USB_OTG_DIEPEACHMSK1_XFRCM_Pos (0U) -#define USB_OTG_DIEPEACHMSK1_XFRCM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_XFRCM_Pos) /*!< 0x00000001 */ -#define USB_OTG_DIEPEACHMSK1_XFRCM USB_OTG_DIEPEACHMSK1_XFRCM_Msk /*!< Transfer completed interrupt mask */ -#define USB_OTG_DIEPEACHMSK1_EPDM_Pos (1U) -#define USB_OTG_DIEPEACHMSK1_EPDM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_EPDM_Pos) /*!< 0x00000002 */ -#define USB_OTG_DIEPEACHMSK1_EPDM USB_OTG_DIEPEACHMSK1_EPDM_Msk /*!< Endpoint disabled interrupt mask */ -#define USB_OTG_DIEPEACHMSK1_TOM_Pos (3U) -#define USB_OTG_DIEPEACHMSK1_TOM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_TOM_Pos) /*!< 0x00000008 */ -#define USB_OTG_DIEPEACHMSK1_TOM USB_OTG_DIEPEACHMSK1_TOM_Msk /*!< Timeout condition mask (nonisochronous endpoints) */ -#define USB_OTG_DIEPEACHMSK1_ITTXFEMSK_Pos (4U) -#define USB_OTG_DIEPEACHMSK1_ITTXFEMSK_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_ITTXFEMSK_Pos) /*!< 0x00000010 */ -#define USB_OTG_DIEPEACHMSK1_ITTXFEMSK USB_OTG_DIEPEACHMSK1_ITTXFEMSK_Msk /*!< IN token received when TxFIFO empty mask */ -#define USB_OTG_DIEPEACHMSK1_INEPNMM_Pos (5U) -#define USB_OTG_DIEPEACHMSK1_INEPNMM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_INEPNMM_Pos) /*!< 0x00000020 */ -#define USB_OTG_DIEPEACHMSK1_INEPNMM USB_OTG_DIEPEACHMSK1_INEPNMM_Msk /*!< IN token received with EP mismatch mask */ -#define USB_OTG_DIEPEACHMSK1_INEPNEM_Pos (6U) -#define USB_OTG_DIEPEACHMSK1_INEPNEM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_INEPNEM_Pos) /*!< 0x00000040 */ -#define USB_OTG_DIEPEACHMSK1_INEPNEM USB_OTG_DIEPEACHMSK1_INEPNEM_Msk /*!< IN endpoint NAK effective mask */ -#define USB_OTG_DIEPEACHMSK1_TXFURM_Pos (8U) -#define USB_OTG_DIEPEACHMSK1_TXFURM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_TXFURM_Pos) /*!< 0x00000100 */ -#define USB_OTG_DIEPEACHMSK1_TXFURM USB_OTG_DIEPEACHMSK1_TXFURM_Msk /*!< FIFO underrun mask */ -#define USB_OTG_DIEPEACHMSK1_BIM_Pos (9U) -#define USB_OTG_DIEPEACHMSK1_BIM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_BIM_Pos) /*!< 0x00000200 */ -#define USB_OTG_DIEPEACHMSK1_BIM USB_OTG_DIEPEACHMSK1_BIM_Msk /*!< BNA interrupt mask */ -#define USB_OTG_DIEPEACHMSK1_NAKM_Pos (13U) -#define USB_OTG_DIEPEACHMSK1_NAKM_Msk (0x1UL << USB_OTG_DIEPEACHMSK1_NAKM_Pos) /*!< 0x00002000 */ -#define USB_OTG_DIEPEACHMSK1_NAKM USB_OTG_DIEPEACHMSK1_NAKM_Msk /*!< NAK interrupt mask */ - -/******************** Bit definition for USB_OTG_HPRT register ********************/ -#define USB_OTG_HPRT_PCSTS_Pos (0U) -#define USB_OTG_HPRT_PCSTS_Msk (0x1UL << USB_OTG_HPRT_PCSTS_Pos) /*!< 0x00000001 */ -#define USB_OTG_HPRT_PCSTS USB_OTG_HPRT_PCSTS_Msk /*!< Port connect status */ -#define USB_OTG_HPRT_PCDET_Pos (1U) -#define USB_OTG_HPRT_PCDET_Msk (0x1UL << USB_OTG_HPRT_PCDET_Pos) /*!< 0x00000002 */ -#define USB_OTG_HPRT_PCDET USB_OTG_HPRT_PCDET_Msk /*!< Port connect detected */ -#define USB_OTG_HPRT_PENA_Pos (2U) -#define USB_OTG_HPRT_PENA_Msk (0x1UL << USB_OTG_HPRT_PENA_Pos) /*!< 0x00000004 */ -#define USB_OTG_HPRT_PENA USB_OTG_HPRT_PENA_Msk /*!< Port enable */ -#define USB_OTG_HPRT_PENCHNG_Pos (3U) -#define USB_OTG_HPRT_PENCHNG_Msk (0x1UL << USB_OTG_HPRT_PENCHNG_Pos) /*!< 0x00000008 */ -#define USB_OTG_HPRT_PENCHNG USB_OTG_HPRT_PENCHNG_Msk /*!< Port enable/disable change */ -#define USB_OTG_HPRT_POCA_Pos (4U) -#define USB_OTG_HPRT_POCA_Msk (0x1UL << USB_OTG_HPRT_POCA_Pos) /*!< 0x00000010 */ -#define USB_OTG_HPRT_POCA USB_OTG_HPRT_POCA_Msk /*!< Port overcurrent active */ -#define USB_OTG_HPRT_POCCHNG_Pos (5U) -#define USB_OTG_HPRT_POCCHNG_Msk (0x1UL << USB_OTG_HPRT_POCCHNG_Pos) /*!< 0x00000020 */ -#define USB_OTG_HPRT_POCCHNG USB_OTG_HPRT_POCCHNG_Msk /*!< Port overcurrent change */ -#define USB_OTG_HPRT_PRES_Pos (6U) -#define USB_OTG_HPRT_PRES_Msk (0x1UL << USB_OTG_HPRT_PRES_Pos) /*!< 0x00000040 */ -#define USB_OTG_HPRT_PRES USB_OTG_HPRT_PRES_Msk /*!< Port resume */ -#define USB_OTG_HPRT_PSUSP_Pos (7U) -#define USB_OTG_HPRT_PSUSP_Msk (0x1UL << USB_OTG_HPRT_PSUSP_Pos) /*!< 0x00000080 */ -#define USB_OTG_HPRT_PSUSP USB_OTG_HPRT_PSUSP_Msk /*!< Port suspend */ -#define USB_OTG_HPRT_PRST_Pos (8U) -#define USB_OTG_HPRT_PRST_Msk (0x1UL << USB_OTG_HPRT_PRST_Pos) /*!< 0x00000100 */ -#define USB_OTG_HPRT_PRST USB_OTG_HPRT_PRST_Msk /*!< Port reset */ - -#define USB_OTG_HPRT_PLSTS_Pos (10U) -#define USB_OTG_HPRT_PLSTS_Msk (0x3UL << USB_OTG_HPRT_PLSTS_Pos) /*!< 0x00000C00 */ -#define USB_OTG_HPRT_PLSTS USB_OTG_HPRT_PLSTS_Msk /*!< Port line status */ -#define USB_OTG_HPRT_PLSTS_0 (0x1UL << USB_OTG_HPRT_PLSTS_Pos) /*!< 0x00000400 */ -#define USB_OTG_HPRT_PLSTS_1 (0x2UL << USB_OTG_HPRT_PLSTS_Pos) /*!< 0x00000800 */ -#define USB_OTG_HPRT_PPWR_Pos (12U) -#define USB_OTG_HPRT_PPWR_Msk (0x1UL << USB_OTG_HPRT_PPWR_Pos) /*!< 0x00001000 */ -#define USB_OTG_HPRT_PPWR USB_OTG_HPRT_PPWR_Msk /*!< Port power */ - -#define USB_OTG_HPRT_PTCTL_Pos (13U) -#define USB_OTG_HPRT_PTCTL_Msk (0xFUL << USB_OTG_HPRT_PTCTL_Pos) /*!< 0x0001E000 */ -#define USB_OTG_HPRT_PTCTL USB_OTG_HPRT_PTCTL_Msk /*!< Port test control */ -#define USB_OTG_HPRT_PTCTL_0 (0x1UL << USB_OTG_HPRT_PTCTL_Pos) /*!< 0x00002000 */ -#define USB_OTG_HPRT_PTCTL_1 (0x2UL << USB_OTG_HPRT_PTCTL_Pos) /*!< 0x00004000 */ -#define USB_OTG_HPRT_PTCTL_2 (0x4UL << USB_OTG_HPRT_PTCTL_Pos) /*!< 0x00008000 */ -#define USB_OTG_HPRT_PTCTL_3 (0x8UL << USB_OTG_HPRT_PTCTL_Pos) /*!< 0x00010000 */ - -#define USB_OTG_HPRT_PSPD_Pos (17U) -#define USB_OTG_HPRT_PSPD_Msk (0x3UL << USB_OTG_HPRT_PSPD_Pos) /*!< 0x00060000 */ -#define USB_OTG_HPRT_PSPD USB_OTG_HPRT_PSPD_Msk /*!< Port speed */ -#define USB_OTG_HPRT_PSPD_0 (0x1UL << USB_OTG_HPRT_PSPD_Pos) /*!< 0x00020000 */ -#define USB_OTG_HPRT_PSPD_1 (0x2UL << USB_OTG_HPRT_PSPD_Pos) /*!< 0x00040000 */ - -/******************** Bit definition for USB_OTG_DOEPEACHMSK1 register ********************/ -#define USB_OTG_DOEPEACHMSK1_XFRCM_Pos (0U) -#define USB_OTG_DOEPEACHMSK1_XFRCM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_XFRCM_Pos) /*!< 0x00000001 */ -#define USB_OTG_DOEPEACHMSK1_XFRCM USB_OTG_DOEPEACHMSK1_XFRCM_Msk /*!< Transfer completed interrupt mask */ -#define USB_OTG_DOEPEACHMSK1_EPDM_Pos (1U) -#define USB_OTG_DOEPEACHMSK1_EPDM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_EPDM_Pos) /*!< 0x00000002 */ -#define USB_OTG_DOEPEACHMSK1_EPDM USB_OTG_DOEPEACHMSK1_EPDM_Msk /*!< Endpoint disabled interrupt mask */ -#define USB_OTG_DOEPEACHMSK1_TOM_Pos (3U) -#define USB_OTG_DOEPEACHMSK1_TOM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_TOM_Pos) /*!< 0x00000008 */ -#define USB_OTG_DOEPEACHMSK1_TOM USB_OTG_DOEPEACHMSK1_TOM_Msk /*!< Timeout condition mask */ -#define USB_OTG_DOEPEACHMSK1_ITTXFEMSK_Pos (4U) -#define USB_OTG_DOEPEACHMSK1_ITTXFEMSK_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_ITTXFEMSK_Pos) /*!< 0x00000010 */ -#define USB_OTG_DOEPEACHMSK1_ITTXFEMSK USB_OTG_DOEPEACHMSK1_ITTXFEMSK_Msk /*!< IN token received when TxFIFO empty mask */ -#define USB_OTG_DOEPEACHMSK1_INEPNMM_Pos (5U) -#define USB_OTG_DOEPEACHMSK1_INEPNMM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_INEPNMM_Pos) /*!< 0x00000020 */ -#define USB_OTG_DOEPEACHMSK1_INEPNMM USB_OTG_DOEPEACHMSK1_INEPNMM_Msk /*!< IN token received with EP mismatch mask */ -#define USB_OTG_DOEPEACHMSK1_INEPNEM_Pos (6U) -#define USB_OTG_DOEPEACHMSK1_INEPNEM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_INEPNEM_Pos) /*!< 0x00000040 */ -#define USB_OTG_DOEPEACHMSK1_INEPNEM USB_OTG_DOEPEACHMSK1_INEPNEM_Msk /*!< IN endpoint NAK effective mask */ -#define USB_OTG_DOEPEACHMSK1_TXFURM_Pos (8U) -#define USB_OTG_DOEPEACHMSK1_TXFURM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_TXFURM_Pos) /*!< 0x00000100 */ -#define USB_OTG_DOEPEACHMSK1_TXFURM USB_OTG_DOEPEACHMSK1_TXFURM_Msk /*!< OUT packet error mask */ -#define USB_OTG_DOEPEACHMSK1_BIM_Pos (9U) -#define USB_OTG_DOEPEACHMSK1_BIM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_BIM_Pos) /*!< 0x00000200 */ -#define USB_OTG_DOEPEACHMSK1_BIM USB_OTG_DOEPEACHMSK1_BIM_Msk /*!< BNA interrupt mask */ -#define USB_OTG_DOEPEACHMSK1_BERRM_Pos (12U) -#define USB_OTG_DOEPEACHMSK1_BERRM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_BERRM_Pos) /*!< 0x00001000 */ -#define USB_OTG_DOEPEACHMSK1_BERRM USB_OTG_DOEPEACHMSK1_BERRM_Msk /*!< Bubble error interrupt mask */ -#define USB_OTG_DOEPEACHMSK1_NAKM_Pos (13U) -#define USB_OTG_DOEPEACHMSK1_NAKM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_NAKM_Pos) /*!< 0x00002000 */ -#define USB_OTG_DOEPEACHMSK1_NAKM USB_OTG_DOEPEACHMSK1_NAKM_Msk /*!< NAK interrupt mask */ -#define USB_OTG_DOEPEACHMSK1_NYETM_Pos (14U) -#define USB_OTG_DOEPEACHMSK1_NYETM_Msk (0x1UL << USB_OTG_DOEPEACHMSK1_NYETM_Pos) /*!< 0x00004000 */ -#define USB_OTG_DOEPEACHMSK1_NYETM USB_OTG_DOEPEACHMSK1_NYETM_Msk /*!< NYET interrupt mask */ - -/******************** Bit definition for USB_OTG_HPTXFSIZ register ********************/ -#define USB_OTG_HPTXFSIZ_PTXSA_Pos (0U) -#define USB_OTG_HPTXFSIZ_PTXSA_Msk (0xFFFFUL << USB_OTG_HPTXFSIZ_PTXSA_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_HPTXFSIZ_PTXSA USB_OTG_HPTXFSIZ_PTXSA_Msk /*!< Host periodic TxFIFO start address */ -#define USB_OTG_HPTXFSIZ_PTXFD_Pos (16U) -#define USB_OTG_HPTXFSIZ_PTXFD_Msk (0xFFFFUL << USB_OTG_HPTXFSIZ_PTXFD_Pos) /*!< 0xFFFF0000 */ -#define USB_OTG_HPTXFSIZ_PTXFD USB_OTG_HPTXFSIZ_PTXFD_Msk /*!< Host periodic TxFIFO depth */ - -/******************** Bit definition for USB_OTG_DIEPCTL register ********************/ -#define USB_OTG_DIEPCTL_MPSIZ_Pos (0U) -#define USB_OTG_DIEPCTL_MPSIZ_Msk (0x7FFUL << USB_OTG_DIEPCTL_MPSIZ_Pos) /*!< 0x000007FF */ -#define USB_OTG_DIEPCTL_MPSIZ USB_OTG_DIEPCTL_MPSIZ_Msk /*!< Maximum packet size */ -#define USB_OTG_DIEPCTL_USBAEP_Pos (15U) -#define USB_OTG_DIEPCTL_USBAEP_Msk (0x1UL << USB_OTG_DIEPCTL_USBAEP_Pos) /*!< 0x00008000 */ -#define USB_OTG_DIEPCTL_USBAEP USB_OTG_DIEPCTL_USBAEP_Msk /*!< USB active endpoint */ -#define USB_OTG_DIEPCTL_EONUM_DPID_Pos (16U) -#define USB_OTG_DIEPCTL_EONUM_DPID_Msk (0x1UL << USB_OTG_DIEPCTL_EONUM_DPID_Pos) /*!< 0x00010000 */ -#define USB_OTG_DIEPCTL_EONUM_DPID USB_OTG_DIEPCTL_EONUM_DPID_Msk /*!< Even/odd frame */ -#define USB_OTG_DIEPCTL_NAKSTS_Pos (17U) -#define USB_OTG_DIEPCTL_NAKSTS_Msk (0x1UL << USB_OTG_DIEPCTL_NAKSTS_Pos) /*!< 0x00020000 */ -#define USB_OTG_DIEPCTL_NAKSTS USB_OTG_DIEPCTL_NAKSTS_Msk /*!< NAK status */ - -#define USB_OTG_DIEPCTL_EPTYP_Pos (18U) -#define USB_OTG_DIEPCTL_EPTYP_Msk (0x3UL << USB_OTG_DIEPCTL_EPTYP_Pos) /*!< 0x000C0000 */ -#define USB_OTG_DIEPCTL_EPTYP USB_OTG_DIEPCTL_EPTYP_Msk /*!< Endpoint type */ -#define USB_OTG_DIEPCTL_EPTYP_0 (0x1UL << USB_OTG_DIEPCTL_EPTYP_Pos) /*!< 0x00040000 */ -#define USB_OTG_DIEPCTL_EPTYP_1 (0x2UL << USB_OTG_DIEPCTL_EPTYP_Pos) /*!< 0x00080000 */ -#define USB_OTG_DIEPCTL_STALL_Pos (21U) -#define USB_OTG_DIEPCTL_STALL_Msk (0x1UL << USB_OTG_DIEPCTL_STALL_Pos) /*!< 0x00200000 */ -#define USB_OTG_DIEPCTL_STALL USB_OTG_DIEPCTL_STALL_Msk /*!< STALL handshake */ - -#define USB_OTG_DIEPCTL_TXFNUM_Pos (22U) -#define USB_OTG_DIEPCTL_TXFNUM_Msk (0xFUL << USB_OTG_DIEPCTL_TXFNUM_Pos) /*!< 0x03C00000 */ -#define USB_OTG_DIEPCTL_TXFNUM USB_OTG_DIEPCTL_TXFNUM_Msk /*!< TxFIFO number */ -#define USB_OTG_DIEPCTL_TXFNUM_0 (0x1UL << USB_OTG_DIEPCTL_TXFNUM_Pos) /*!< 0x00400000 */ -#define USB_OTG_DIEPCTL_TXFNUM_1 (0x2UL << USB_OTG_DIEPCTL_TXFNUM_Pos) /*!< 0x00800000 */ -#define USB_OTG_DIEPCTL_TXFNUM_2 (0x4UL << USB_OTG_DIEPCTL_TXFNUM_Pos) /*!< 0x01000000 */ -#define USB_OTG_DIEPCTL_TXFNUM_3 (0x8UL << USB_OTG_DIEPCTL_TXFNUM_Pos) /*!< 0x02000000 */ -#define USB_OTG_DIEPCTL_CNAK_Pos (26U) -#define USB_OTG_DIEPCTL_CNAK_Msk (0x1UL << USB_OTG_DIEPCTL_CNAK_Pos) /*!< 0x04000000 */ -#define USB_OTG_DIEPCTL_CNAK USB_OTG_DIEPCTL_CNAK_Msk /*!< Clear NAK */ -#define USB_OTG_DIEPCTL_SNAK_Pos (27U) -#define USB_OTG_DIEPCTL_SNAK_Msk (0x1UL << USB_OTG_DIEPCTL_SNAK_Pos) /*!< 0x08000000 */ -#define USB_OTG_DIEPCTL_SNAK USB_OTG_DIEPCTL_SNAK_Msk /*!< Set NAK */ -#define USB_OTG_DIEPCTL_SD0PID_SEVNFRM_Pos (28U) -#define USB_OTG_DIEPCTL_SD0PID_SEVNFRM_Msk (0x1UL << USB_OTG_DIEPCTL_SD0PID_SEVNFRM_Pos) /*!< 0x10000000 */ -#define USB_OTG_DIEPCTL_SD0PID_SEVNFRM USB_OTG_DIEPCTL_SD0PID_SEVNFRM_Msk /*!< Set DATA0 PID */ -#define USB_OTG_DIEPCTL_SODDFRM_Pos (29U) -#define USB_OTG_DIEPCTL_SODDFRM_Msk (0x1UL << USB_OTG_DIEPCTL_SODDFRM_Pos) /*!< 0x20000000 */ -#define USB_OTG_DIEPCTL_SODDFRM USB_OTG_DIEPCTL_SODDFRM_Msk /*!< Set odd frame */ -#define USB_OTG_DIEPCTL_EPDIS_Pos (30U) -#define USB_OTG_DIEPCTL_EPDIS_Msk (0x1UL << USB_OTG_DIEPCTL_EPDIS_Pos) /*!< 0x40000000 */ -#define USB_OTG_DIEPCTL_EPDIS USB_OTG_DIEPCTL_EPDIS_Msk /*!< Endpoint disable */ -#define USB_OTG_DIEPCTL_EPENA_Pos (31U) -#define USB_OTG_DIEPCTL_EPENA_Msk (0x1UL << USB_OTG_DIEPCTL_EPENA_Pos) /*!< 0x80000000 */ -#define USB_OTG_DIEPCTL_EPENA USB_OTG_DIEPCTL_EPENA_Msk /*!< Endpoint enable */ - -/******************** Bit definition for USB_OTG_HCCHAR register ********************/ -#define USB_OTG_HCCHAR_MPSIZ_Pos (0U) -#define USB_OTG_HCCHAR_MPSIZ_Msk (0x7FFUL << USB_OTG_HCCHAR_MPSIZ_Pos) /*!< 0x000007FF */ -#define USB_OTG_HCCHAR_MPSIZ USB_OTG_HCCHAR_MPSIZ_Msk /*!< Maximum packet size */ - -#define USB_OTG_HCCHAR_EPNUM_Pos (11U) -#define USB_OTG_HCCHAR_EPNUM_Msk (0xFUL << USB_OTG_HCCHAR_EPNUM_Pos) /*!< 0x00007800 */ -#define USB_OTG_HCCHAR_EPNUM USB_OTG_HCCHAR_EPNUM_Msk /*!< Endpoint number */ -#define USB_OTG_HCCHAR_EPNUM_0 (0x1UL << USB_OTG_HCCHAR_EPNUM_Pos) /*!< 0x00000800 */ -#define USB_OTG_HCCHAR_EPNUM_1 (0x2UL << USB_OTG_HCCHAR_EPNUM_Pos) /*!< 0x00001000 */ -#define USB_OTG_HCCHAR_EPNUM_2 (0x4UL << USB_OTG_HCCHAR_EPNUM_Pos) /*!< 0x00002000 */ -#define USB_OTG_HCCHAR_EPNUM_3 (0x8UL << USB_OTG_HCCHAR_EPNUM_Pos) /*!< 0x00004000 */ -#define USB_OTG_HCCHAR_EPDIR_Pos (15U) -#define USB_OTG_HCCHAR_EPDIR_Msk (0x1UL << USB_OTG_HCCHAR_EPDIR_Pos) /*!< 0x00008000 */ -#define USB_OTG_HCCHAR_EPDIR USB_OTG_HCCHAR_EPDIR_Msk /*!< Endpoint direction */ -#define USB_OTG_HCCHAR_LSDEV_Pos (17U) -#define USB_OTG_HCCHAR_LSDEV_Msk (0x1UL << USB_OTG_HCCHAR_LSDEV_Pos) /*!< 0x00020000 */ -#define USB_OTG_HCCHAR_LSDEV USB_OTG_HCCHAR_LSDEV_Msk /*!< Low-speed device */ - -#define USB_OTG_HCCHAR_EPTYP_Pos (18U) -#define USB_OTG_HCCHAR_EPTYP_Msk (0x3UL << USB_OTG_HCCHAR_EPTYP_Pos) /*!< 0x000C0000 */ -#define USB_OTG_HCCHAR_EPTYP USB_OTG_HCCHAR_EPTYP_Msk /*!< Endpoint type */ -#define USB_OTG_HCCHAR_EPTYP_0 (0x1UL << USB_OTG_HCCHAR_EPTYP_Pos) /*!< 0x00040000 */ -#define USB_OTG_HCCHAR_EPTYP_1 (0x2UL << USB_OTG_HCCHAR_EPTYP_Pos) /*!< 0x00080000 */ - -#define USB_OTG_HCCHAR_MC_Pos (20U) -#define USB_OTG_HCCHAR_MC_Msk (0x3UL << USB_OTG_HCCHAR_MC_Pos) /*!< 0x00300000 */ -#define USB_OTG_HCCHAR_MC USB_OTG_HCCHAR_MC_Msk /*!< Multi Count (MC) / Error Count (EC) */ -#define USB_OTG_HCCHAR_MC_0 (0x1UL << USB_OTG_HCCHAR_MC_Pos) /*!< 0x00100000 */ -#define USB_OTG_HCCHAR_MC_1 (0x2UL << USB_OTG_HCCHAR_MC_Pos) /*!< 0x00200000 */ - -#define USB_OTG_HCCHAR_DAD_Pos (22U) -#define USB_OTG_HCCHAR_DAD_Msk (0x7FUL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x1FC00000 */ -#define USB_OTG_HCCHAR_DAD USB_OTG_HCCHAR_DAD_Msk /*!< Device address */ -#define USB_OTG_HCCHAR_DAD_0 (0x01UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x00400000 */ -#define USB_OTG_HCCHAR_DAD_1 (0x02UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x00800000 */ -#define USB_OTG_HCCHAR_DAD_2 (0x04UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x01000000 */ -#define USB_OTG_HCCHAR_DAD_3 (0x08UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x02000000 */ -#define USB_OTG_HCCHAR_DAD_4 (0x10UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x04000000 */ -#define USB_OTG_HCCHAR_DAD_5 (0x20UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x08000000 */ -#define USB_OTG_HCCHAR_DAD_6 (0x40UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x10000000 */ -#define USB_OTG_HCCHAR_ODDFRM_Pos (29U) -#define USB_OTG_HCCHAR_ODDFRM_Msk (0x1UL << USB_OTG_HCCHAR_ODDFRM_Pos) /*!< 0x20000000 */ -#define USB_OTG_HCCHAR_ODDFRM USB_OTG_HCCHAR_ODDFRM_Msk /*!< Odd frame */ -#define USB_OTG_HCCHAR_CHDIS_Pos (30U) -#define USB_OTG_HCCHAR_CHDIS_Msk (0x1UL << USB_OTG_HCCHAR_CHDIS_Pos) /*!< 0x40000000 */ -#define USB_OTG_HCCHAR_CHDIS USB_OTG_HCCHAR_CHDIS_Msk /*!< Channel disable */ -#define USB_OTG_HCCHAR_CHENA_Pos (31U) -#define USB_OTG_HCCHAR_CHENA_Msk (0x1UL << USB_OTG_HCCHAR_CHENA_Pos) /*!< 0x80000000 */ -#define USB_OTG_HCCHAR_CHENA USB_OTG_HCCHAR_CHENA_Msk /*!< Channel enable */ - -/******************** Bit definition for USB_OTG_HCSPLT register ********************/ - -#define USB_OTG_HCSPLT_PRTADDR_Pos (0U) -#define USB_OTG_HCSPLT_PRTADDR_Msk (0x7FUL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x0000007F */ -#define USB_OTG_HCSPLT_PRTADDR USB_OTG_HCSPLT_PRTADDR_Msk /*!< Port address */ -#define USB_OTG_HCSPLT_PRTADDR_0 (0x01UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000001 */ -#define USB_OTG_HCSPLT_PRTADDR_1 (0x02UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000002 */ -#define USB_OTG_HCSPLT_PRTADDR_2 (0x04UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000004 */ -#define USB_OTG_HCSPLT_PRTADDR_3 (0x08UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000008 */ -#define USB_OTG_HCSPLT_PRTADDR_4 (0x10UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000010 */ -#define USB_OTG_HCSPLT_PRTADDR_5 (0x20UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000020 */ -#define USB_OTG_HCSPLT_PRTADDR_6 (0x40UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000040 */ - -#define USB_OTG_HCSPLT_HUBADDR_Pos (7U) -#define USB_OTG_HCSPLT_HUBADDR_Msk (0x7FUL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00003F80 */ -#define USB_OTG_HCSPLT_HUBADDR USB_OTG_HCSPLT_HUBADDR_Msk /*!< Hub address */ -#define USB_OTG_HCSPLT_HUBADDR_0 (0x01UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00000080 */ -#define USB_OTG_HCSPLT_HUBADDR_1 (0x02UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00000100 */ -#define USB_OTG_HCSPLT_HUBADDR_2 (0x04UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00000200 */ -#define USB_OTG_HCSPLT_HUBADDR_3 (0x08UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00000400 */ -#define USB_OTG_HCSPLT_HUBADDR_4 (0x10UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00000800 */ -#define USB_OTG_HCSPLT_HUBADDR_5 (0x20UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00001000 */ -#define USB_OTG_HCSPLT_HUBADDR_6 (0x40UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00002000 */ - -#define USB_OTG_HCSPLT_XACTPOS_Pos (14U) -#define USB_OTG_HCSPLT_XACTPOS_Msk (0x3UL << USB_OTG_HCSPLT_XACTPOS_Pos) /*!< 0x0000C000 */ -#define USB_OTG_HCSPLT_XACTPOS USB_OTG_HCSPLT_XACTPOS_Msk /*!< XACTPOS */ -#define USB_OTG_HCSPLT_XACTPOS_0 (0x1UL << USB_OTG_HCSPLT_XACTPOS_Pos) /*!< 0x00004000 */ -#define USB_OTG_HCSPLT_XACTPOS_1 (0x2UL << USB_OTG_HCSPLT_XACTPOS_Pos) /*!< 0x00008000 */ -#define USB_OTG_HCSPLT_COMPLSPLT_Pos (16U) -#define USB_OTG_HCSPLT_COMPLSPLT_Msk (0x1UL << USB_OTG_HCSPLT_COMPLSPLT_Pos) /*!< 0x00010000 */ -#define USB_OTG_HCSPLT_COMPLSPLT USB_OTG_HCSPLT_COMPLSPLT_Msk /*!< Do complete split */ -#define USB_OTG_HCSPLT_SPLITEN_Pos (31U) -#define USB_OTG_HCSPLT_SPLITEN_Msk (0x1UL << USB_OTG_HCSPLT_SPLITEN_Pos) /*!< 0x80000000 */ -#define USB_OTG_HCSPLT_SPLITEN USB_OTG_HCSPLT_SPLITEN_Msk /*!< Split enable */ - -/******************** Bit definition for USB_OTG_HCINT register ********************/ -#define USB_OTG_HCINT_XFRC_Pos (0U) -#define USB_OTG_HCINT_XFRC_Msk (0x1UL << USB_OTG_HCINT_XFRC_Pos) /*!< 0x00000001 */ -#define USB_OTG_HCINT_XFRC USB_OTG_HCINT_XFRC_Msk /*!< Transfer completed */ -#define USB_OTG_HCINT_CHH_Pos (1U) -#define USB_OTG_HCINT_CHH_Msk (0x1UL << USB_OTG_HCINT_CHH_Pos) /*!< 0x00000002 */ -#define USB_OTG_HCINT_CHH USB_OTG_HCINT_CHH_Msk /*!< Channel halted */ -#define USB_OTG_HCINT_AHBERR_Pos (2U) -#define USB_OTG_HCINT_AHBERR_Msk (0x1UL << USB_OTG_HCINT_AHBERR_Pos) /*!< 0x00000004 */ -#define USB_OTG_HCINT_AHBERR USB_OTG_HCINT_AHBERR_Msk /*!< AHB error */ -#define USB_OTG_HCINT_STALL_Pos (3U) -#define USB_OTG_HCINT_STALL_Msk (0x1UL << USB_OTG_HCINT_STALL_Pos) /*!< 0x00000008 */ -#define USB_OTG_HCINT_STALL USB_OTG_HCINT_STALL_Msk /*!< STALL response received interrupt */ -#define USB_OTG_HCINT_NAK_Pos (4U) -#define USB_OTG_HCINT_NAK_Msk (0x1UL << USB_OTG_HCINT_NAK_Pos) /*!< 0x00000010 */ -#define USB_OTG_HCINT_NAK USB_OTG_HCINT_NAK_Msk /*!< NAK response received interrupt */ -#define USB_OTG_HCINT_ACK_Pos (5U) -#define USB_OTG_HCINT_ACK_Msk (0x1UL << USB_OTG_HCINT_ACK_Pos) /*!< 0x00000020 */ -#define USB_OTG_HCINT_ACK USB_OTG_HCINT_ACK_Msk /*!< ACK response received/transmitted interrupt */ -#define USB_OTG_HCINT_NYET_Pos (6U) -#define USB_OTG_HCINT_NYET_Msk (0x1UL << USB_OTG_HCINT_NYET_Pos) /*!< 0x00000040 */ -#define USB_OTG_HCINT_NYET USB_OTG_HCINT_NYET_Msk /*!< Response received interrupt */ -#define USB_OTG_HCINT_TXERR_Pos (7U) -#define USB_OTG_HCINT_TXERR_Msk (0x1UL << USB_OTG_HCINT_TXERR_Pos) /*!< 0x00000080 */ -#define USB_OTG_HCINT_TXERR USB_OTG_HCINT_TXERR_Msk /*!< Transaction error */ -#define USB_OTG_HCINT_BBERR_Pos (8U) -#define USB_OTG_HCINT_BBERR_Msk (0x1UL << USB_OTG_HCINT_BBERR_Pos) /*!< 0x00000100 */ -#define USB_OTG_HCINT_BBERR USB_OTG_HCINT_BBERR_Msk /*!< Babble error */ -#define USB_OTG_HCINT_FRMOR_Pos (9U) -#define USB_OTG_HCINT_FRMOR_Msk (0x1UL << USB_OTG_HCINT_FRMOR_Pos) /*!< 0x00000200 */ -#define USB_OTG_HCINT_FRMOR USB_OTG_HCINT_FRMOR_Msk /*!< Frame overrun */ -#define USB_OTG_HCINT_DTERR_Pos (10U) -#define USB_OTG_HCINT_DTERR_Msk (0x1UL << USB_OTG_HCINT_DTERR_Pos) /*!< 0x00000400 */ -#define USB_OTG_HCINT_DTERR USB_OTG_HCINT_DTERR_Msk /*!< Data toggle error */ - -/******************** Bit definition for USB_OTG_DIEPINT register ********************/ -#define USB_OTG_DIEPINT_XFRC_Pos (0U) -#define USB_OTG_DIEPINT_XFRC_Msk (0x1UL << USB_OTG_DIEPINT_XFRC_Pos) /*!< 0x00000001 */ -#define USB_OTG_DIEPINT_XFRC USB_OTG_DIEPINT_XFRC_Msk /*!< Transfer completed interrupt */ -#define USB_OTG_DIEPINT_EPDISD_Pos (1U) -#define USB_OTG_DIEPINT_EPDISD_Msk (0x1UL << USB_OTG_DIEPINT_EPDISD_Pos) /*!< 0x00000002 */ -#define USB_OTG_DIEPINT_EPDISD USB_OTG_DIEPINT_EPDISD_Msk /*!< Endpoint disabled interrupt */ -#define USB_OTG_DIEPINT_AHBERR_Pos (2U) -#define USB_OTG_DIEPINT_AHBERR_Msk (0x1UL << USB_OTG_DIEPINT_AHBERR_Pos) /*!< 0x00000004 */ -#define USB_OTG_DIEPINT_AHBERR USB_OTG_DIEPINT_AHBERR_Msk /*!< AHB Error (AHBErr) during an IN transaction */ -#define USB_OTG_DIEPINT_TOC_Pos (3U) -#define USB_OTG_DIEPINT_TOC_Msk (0x1UL << USB_OTG_DIEPINT_TOC_Pos) /*!< 0x00000008 */ -#define USB_OTG_DIEPINT_TOC USB_OTG_DIEPINT_TOC_Msk /*!< Timeout condition */ -#define USB_OTG_DIEPINT_ITTXFE_Pos (4U) -#define USB_OTG_DIEPINT_ITTXFE_Msk (0x1UL << USB_OTG_DIEPINT_ITTXFE_Pos) /*!< 0x00000010 */ -#define USB_OTG_DIEPINT_ITTXFE USB_OTG_DIEPINT_ITTXFE_Msk /*!< IN token received when TxFIFO is empty */ -#define USB_OTG_DIEPINT_INEPNM_Pos (5U) -#define USB_OTG_DIEPINT_INEPNM_Msk (0x1UL << USB_OTG_DIEPINT_INEPNM_Pos) /*!< 0x00000004 */ -#define USB_OTG_DIEPINT_INEPNM USB_OTG_DIEPINT_INEPNM_Msk /*!< IN token received with EP mismatch */ -#define USB_OTG_DIEPINT_INEPNE_Pos (6U) -#define USB_OTG_DIEPINT_INEPNE_Msk (0x1UL << USB_OTG_DIEPINT_INEPNE_Pos) /*!< 0x00000040 */ -#define USB_OTG_DIEPINT_INEPNE USB_OTG_DIEPINT_INEPNE_Msk /*!< IN endpoint NAK effective */ -#define USB_OTG_DIEPINT_TXFE_Pos (7U) -#define USB_OTG_DIEPINT_TXFE_Msk (0x1UL << USB_OTG_DIEPINT_TXFE_Pos) /*!< 0x00000080 */ -#define USB_OTG_DIEPINT_TXFE USB_OTG_DIEPINT_TXFE_Msk /*!< Transmit FIFO empty */ -#define USB_OTG_DIEPINT_TXFIFOUDRN_Pos (8U) -#define USB_OTG_DIEPINT_TXFIFOUDRN_Msk (0x1UL << USB_OTG_DIEPINT_TXFIFOUDRN_Pos) /*!< 0x00000100 */ -#define USB_OTG_DIEPINT_TXFIFOUDRN USB_OTG_DIEPINT_TXFIFOUDRN_Msk /*!< Transmit Fifo Underrun */ -#define USB_OTG_DIEPINT_BNA_Pos (9U) -#define USB_OTG_DIEPINT_BNA_Msk (0x1UL << USB_OTG_DIEPINT_BNA_Pos) /*!< 0x00000200 */ -#define USB_OTG_DIEPINT_BNA USB_OTG_DIEPINT_BNA_Msk /*!< Buffer not available interrupt */ -#define USB_OTG_DIEPINT_PKTDRPSTS_Pos (11U) -#define USB_OTG_DIEPINT_PKTDRPSTS_Msk (0x1UL << USB_OTG_DIEPINT_PKTDRPSTS_Pos) /*!< 0x00000800 */ -#define USB_OTG_DIEPINT_PKTDRPSTS USB_OTG_DIEPINT_PKTDRPSTS_Msk /*!< Packet dropped status */ -#define USB_OTG_DIEPINT_BERR_Pos (12U) -#define USB_OTG_DIEPINT_BERR_Msk (0x1UL << USB_OTG_DIEPINT_BERR_Pos) /*!< 0x00001000 */ -#define USB_OTG_DIEPINT_BERR USB_OTG_DIEPINT_BERR_Msk /*!< Babble error interrupt */ -#define USB_OTG_DIEPINT_NAK_Pos (13U) -#define USB_OTG_DIEPINT_NAK_Msk (0x1UL << USB_OTG_DIEPINT_NAK_Pos) /*!< 0x00002000 */ -#define USB_OTG_DIEPINT_NAK USB_OTG_DIEPINT_NAK_Msk /*!< NAK interrupt */ - -/******************** Bit definition for USB_OTG_HCINTMSK register ********************/ -#define USB_OTG_HCINTMSK_XFRCM_Pos (0U) -#define USB_OTG_HCINTMSK_XFRCM_Msk (0x1UL << USB_OTG_HCINTMSK_XFRCM_Pos) /*!< 0x00000001 */ -#define USB_OTG_HCINTMSK_XFRCM USB_OTG_HCINTMSK_XFRCM_Msk /*!< Transfer completed mask */ -#define USB_OTG_HCINTMSK_CHHM_Pos (1U) -#define USB_OTG_HCINTMSK_CHHM_Msk (0x1UL << USB_OTG_HCINTMSK_CHHM_Pos) /*!< 0x00000002 */ -#define USB_OTG_HCINTMSK_CHHM USB_OTG_HCINTMSK_CHHM_Msk /*!< Channel halted mask */ -#define USB_OTG_HCINTMSK_AHBERR_Pos (2U) -#define USB_OTG_HCINTMSK_AHBERR_Msk (0x1UL << USB_OTG_HCINTMSK_AHBERR_Pos) /*!< 0x00000004 */ -#define USB_OTG_HCINTMSK_AHBERR USB_OTG_HCINTMSK_AHBERR_Msk /*!< AHB error */ -#define USB_OTG_HCINTMSK_STALLM_Pos (3U) -#define USB_OTG_HCINTMSK_STALLM_Msk (0x1UL << USB_OTG_HCINTMSK_STALLM_Pos) /*!< 0x00000008 */ -#define USB_OTG_HCINTMSK_STALLM USB_OTG_HCINTMSK_STALLM_Msk /*!< STALL response received interrupt mask */ -#define USB_OTG_HCINTMSK_NAKM_Pos (4U) -#define USB_OTG_HCINTMSK_NAKM_Msk (0x1UL << USB_OTG_HCINTMSK_NAKM_Pos) /*!< 0x00000010 */ -#define USB_OTG_HCINTMSK_NAKM USB_OTG_HCINTMSK_NAKM_Msk /*!< NAK response received interrupt mask */ -#define USB_OTG_HCINTMSK_ACKM_Pos (5U) -#define USB_OTG_HCINTMSK_ACKM_Msk (0x1UL << USB_OTG_HCINTMSK_ACKM_Pos) /*!< 0x00000020 */ -#define USB_OTG_HCINTMSK_ACKM USB_OTG_HCINTMSK_ACKM_Msk /*!< ACK response received/transmitted interrupt mask */ -#define USB_OTG_HCINTMSK_NYET_Pos (6U) -#define USB_OTG_HCINTMSK_NYET_Msk (0x1UL << USB_OTG_HCINTMSK_NYET_Pos) /*!< 0x00000040 */ -#define USB_OTG_HCINTMSK_NYET USB_OTG_HCINTMSK_NYET_Msk /*!< response received interrupt mask */ -#define USB_OTG_HCINTMSK_TXERRM_Pos (7U) -#define USB_OTG_HCINTMSK_TXERRM_Msk (0x1UL << USB_OTG_HCINTMSK_TXERRM_Pos) /*!< 0x00000080 */ -#define USB_OTG_HCINTMSK_TXERRM USB_OTG_HCINTMSK_TXERRM_Msk /*!< Transaction error mask */ -#define USB_OTG_HCINTMSK_BBERRM_Pos (8U) -#define USB_OTG_HCINTMSK_BBERRM_Msk (0x1UL << USB_OTG_HCINTMSK_BBERRM_Pos) /*!< 0x00000100 */ -#define USB_OTG_HCINTMSK_BBERRM USB_OTG_HCINTMSK_BBERRM_Msk /*!< Babble error mask */ -#define USB_OTG_HCINTMSK_FRMORM_Pos (9U) -#define USB_OTG_HCINTMSK_FRMORM_Msk (0x1UL << USB_OTG_HCINTMSK_FRMORM_Pos) /*!< 0x00000200 */ -#define USB_OTG_HCINTMSK_FRMORM USB_OTG_HCINTMSK_FRMORM_Msk /*!< Frame overrun mask */ -#define USB_OTG_HCINTMSK_DTERRM_Pos (10U) -#define USB_OTG_HCINTMSK_DTERRM_Msk (0x1UL << USB_OTG_HCINTMSK_DTERRM_Pos) /*!< 0x00000400 */ -#define USB_OTG_HCINTMSK_DTERRM USB_OTG_HCINTMSK_DTERRM_Msk /*!< Data toggle error mask */ - -/******************** Bit definition for USB_OTG_DIEPTSIZ register ********************/ - -#define USB_OTG_DIEPTSIZ_XFRSIZ_Pos (0U) -#define USB_OTG_DIEPTSIZ_XFRSIZ_Msk (0x7FFFFUL << USB_OTG_DIEPTSIZ_XFRSIZ_Pos) /*!< 0x0007FFFF */ -#define USB_OTG_DIEPTSIZ_XFRSIZ USB_OTG_DIEPTSIZ_XFRSIZ_Msk /*!< Transfer size */ -#define USB_OTG_DIEPTSIZ_PKTCNT_Pos (19U) -#define USB_OTG_DIEPTSIZ_PKTCNT_Msk (0x3FFUL << USB_OTG_DIEPTSIZ_PKTCNT_Pos) /*!< 0x1FF80000 */ -#define USB_OTG_DIEPTSIZ_PKTCNT USB_OTG_DIEPTSIZ_PKTCNT_Msk /*!< Packet count */ -#define USB_OTG_DIEPTSIZ_MULCNT_Pos (29U) -#define USB_OTG_DIEPTSIZ_MULCNT_Msk (0x3UL << USB_OTG_DIEPTSIZ_MULCNT_Pos) /*!< 0x60000000 */ -#define USB_OTG_DIEPTSIZ_MULCNT USB_OTG_DIEPTSIZ_MULCNT_Msk /*!< Packet count */ -/******************** Bit definition for USB_OTG_HCTSIZ register ********************/ -#define USB_OTG_HCTSIZ_XFRSIZ_Pos (0U) -#define USB_OTG_HCTSIZ_XFRSIZ_Msk (0x7FFFFUL << USB_OTG_HCTSIZ_XFRSIZ_Pos) /*!< 0x0007FFFF */ -#define USB_OTG_HCTSIZ_XFRSIZ USB_OTG_HCTSIZ_XFRSIZ_Msk /*!< Transfer size */ -#define USB_OTG_HCTSIZ_PKTCNT_Pos (19U) -#define USB_OTG_HCTSIZ_PKTCNT_Msk (0x3FFUL << USB_OTG_HCTSIZ_PKTCNT_Pos) /*!< 0x1FF80000 */ -#define USB_OTG_HCTSIZ_PKTCNT USB_OTG_HCTSIZ_PKTCNT_Msk /*!< Packet count */ -#define USB_OTG_HCTSIZ_DOPING_Pos (31U) -#define USB_OTG_HCTSIZ_DOPING_Msk (0x1UL << USB_OTG_HCTSIZ_DOPING_Pos) /*!< 0x80000000 */ -#define USB_OTG_HCTSIZ_DOPING USB_OTG_HCTSIZ_DOPING_Msk /*!< Do PING */ -#define USB_OTG_HCTSIZ_DPID_Pos (29U) -#define USB_OTG_HCTSIZ_DPID_Msk (0x3UL << USB_OTG_HCTSIZ_DPID_Pos) /*!< 0x60000000 */ -#define USB_OTG_HCTSIZ_DPID USB_OTG_HCTSIZ_DPID_Msk /*!< Data PID */ -#define USB_OTG_HCTSIZ_DPID_0 (0x1UL << USB_OTG_HCTSIZ_DPID_Pos) /*!< 0x20000000 */ -#define USB_OTG_HCTSIZ_DPID_1 (0x2UL << USB_OTG_HCTSIZ_DPID_Pos) /*!< 0x40000000 */ - -/******************** Bit definition for USB_OTG_DIEPDMA register ********************/ -#define USB_OTG_DIEPDMA_DMAADDR_Pos (0U) -#define USB_OTG_DIEPDMA_DMAADDR_Msk (0xFFFFFFFFUL << USB_OTG_DIEPDMA_DMAADDR_Pos) /*!< 0xFFFFFFFF */ -#define USB_OTG_DIEPDMA_DMAADDR USB_OTG_DIEPDMA_DMAADDR_Msk /*!< DMA address */ - -/******************** Bit definition for USB_OTG_HCDMA register ********************/ -#define USB_OTG_HCDMA_DMAADDR_Pos (0U) -#define USB_OTG_HCDMA_DMAADDR_Msk (0xFFFFFFFFUL << USB_OTG_HCDMA_DMAADDR_Pos) /*!< 0xFFFFFFFF */ -#define USB_OTG_HCDMA_DMAADDR USB_OTG_HCDMA_DMAADDR_Msk /*!< DMA address */ - -/******************** Bit definition for USB_OTG_DTXFSTS register ********************/ -#define USB_OTG_DTXFSTS_INEPTFSAV_Pos (0U) -#define USB_OTG_DTXFSTS_INEPTFSAV_Msk (0xFFFFUL << USB_OTG_DTXFSTS_INEPTFSAV_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_DTXFSTS_INEPTFSAV USB_OTG_DTXFSTS_INEPTFSAV_Msk /*!< IN endpoint TxFIFO space available */ - -/******************** Bit definition for USB_OTG_DIEPTXF register ********************/ -#define USB_OTG_DIEPTXF_INEPTXSA_Pos (0U) -#define USB_OTG_DIEPTXF_INEPTXSA_Msk (0xFFFFUL << USB_OTG_DIEPTXF_INEPTXSA_Pos) /*!< 0x0000FFFF */ -#define USB_OTG_DIEPTXF_INEPTXSA USB_OTG_DIEPTXF_INEPTXSA_Msk /*!< IN endpoint FIFOx transmit RAM start address */ -#define USB_OTG_DIEPTXF_INEPTXFD_Pos (16U) -#define USB_OTG_DIEPTXF_INEPTXFD_Msk (0xFFFFUL << USB_OTG_DIEPTXF_INEPTXFD_Pos) /*!< 0xFFFF0000 */ -#define USB_OTG_DIEPTXF_INEPTXFD USB_OTG_DIEPTXF_INEPTXFD_Msk /*!< IN endpoint TxFIFO depth */ - -/******************** Bit definition for USB_OTG_DOEPCTL register ********************/ - -#define USB_OTG_DOEPCTL_MPSIZ_Pos (0U) -#define USB_OTG_DOEPCTL_MPSIZ_Msk (0x7FFUL << USB_OTG_DOEPCTL_MPSIZ_Pos) /*!< 0x000007FF */ -#define USB_OTG_DOEPCTL_MPSIZ USB_OTG_DOEPCTL_MPSIZ_Msk /*!< Maximum packet size */ /*! #include #include "musb_def.h" -#include "bsp/board.h" + +//#include "bsp/board_api.h" +extern uint32_t board_millis(void); // TODO remove typedef uint32_t u32; typedef uint16_t u16; @@ -58,7 +60,7 @@ typedef struct TU_ATTR_PACKED typedef struct { - tusb_control_request_t setup_packet; + CFG_TUD_MEM_ALIGN tusb_control_request_t setup_packet; uint16_t remaining_ctrl; /* The number of bytes remaining in data stage of control transfer. */ int8_t status_out; pipe_state_t pipe0; @@ -350,7 +352,7 @@ static void USBC_INT_DisableRxEp(u8 ep_index) * INTERNAL FUNCTION DECLARATION *------------------------------------------------------------------*/ -static dcd_data_t _dcd; +CFG_TUD_MEM_ALIGN static dcd_data_t _dcd; static inline free_block_t *find_containing_block(free_block_t *beg, free_block_t *end, uint_fast16_t addr) { @@ -560,7 +562,7 @@ static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigne static void process_setup_packet(uint8_t rhport) { - uint32_t *p = (uint32_t*)&_dcd.setup_packet; + uint32_t *p = (uint32_t*)(uintptr_t) &_dcd.setup_packet; p[0] = USBC_Readl(USBC_REG_EPFIFO0(USBC0_BASE)); p[1] = USBC_Readl(USBC_REG_EPFIFO0(USBC0_BASE)); @@ -594,7 +596,7 @@ static bool handle_xfer_in(uint_fast8_t ep_addr) if (len) { volatile void* addr = (volatile void*)(USBC_REG_EPFIFO1(USBC0_BASE) + (epnum_minus1 << 2)); if (_dcd.pipe_buf_is_fifo[TUSB_DIR_IN] & TU_BIT(epnum_minus1)) { - pipe_read_write_packet_ff((tu_fifo_t *)buf, addr, len, TUSB_DIR_IN); + pipe_read_write_packet_ff((tu_fifo_t *)(uintptr_t) buf, addr, len, TUSB_DIR_IN); } else { pipe_write_packet(buf, addr, len); pipe->buf = buf + len; @@ -622,7 +624,7 @@ static bool handle_xfer_out(uint_fast8_t ep_addr) if (len) { volatile void* addr = (volatile void*)(USBC_REG_EPFIFO1(USBC0_BASE) + (epnum_minus1 << 2)); if (_dcd.pipe_buf_is_fifo[TUSB_DIR_OUT] & TU_BIT(epnum_minus1)) { - pipe_read_write_packet_ff((tu_fifo_t *)buf, addr, len, TUSB_DIR_OUT); + pipe_read_write_packet_ff((tu_fifo_t *)(uintptr_t )buf, addr, len, TUSB_DIR_OUT); } else { pipe_read_packet(buf, addr, len); pipe->buf = buf + len; diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index c6132a1f5..692096fc8 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -82,8 +82,8 @@ static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[2]; typedef struct { - uint8_t * buffer; - tu_fifo_t * ff; + uint8_t* buffer; + tu_fifo_t* ff; uint16_t total_len; uint16_t max_size; uint8_t interval; @@ -93,45 +93,182 @@ static xfer_ctl_t xfer_status[DWC2_EP_MAX][2]; #define XFER_CTL_BASE(_ep, _dir) (&xfer_status[_ep][_dir]) // EP0 transfers are limited to 1 packet - larger sizes has to be split -static uint16_t ep0_pending[2]; // Index determines direction as tusb_dir_t type +static uint16_t ep0_pending[2]; // Index determines direction as tusb_dir_t type // TX FIFO RAM allocation so far in words - RX FIFO size is readily available from dwc2->grxfsiz -static uint16_t _allocated_fifo_words_tx; // TX FIFO size in words (IN EPs) -static bool _out_ep_closed; // Flag to check if RX FIFO size needs an update (reduce its size) +static uint16_t _allocated_fifo_words_tx; // TX FIFO size in words (IN EPs) // SOF enabling flag - required for SOF to not get disabled in ISR when SOF was enabled by static bool _sof_en; -// Calculate the RX FIFO size according to recommendations from reference manual -static inline uint16_t calc_grxfsiz(uint16_t max_ep_size, uint8_t ep_count) -{ - return 15 + 2*(max_ep_size/4) + 2*ep_count; +// Calculate the RX FIFO size according to minimum recommendations from reference manual +// RxFIFO = (5 * number of control endpoints + 8) + +// ((largest USB packet used / 4) + 1 for status information) + +// (2 * number of OUT endpoints) + 1 for Global NAK +// with number of control endpoints = 1 we have +// RxFIFO = 15 + (largest USB packet used / 4) + 2 * number of OUT endpoints +// we double the largest USB packet size to be able to hold up to 2 packets +static inline uint16_t calc_grxfsiz(uint16_t max_ep_size, uint8_t ep_count) { + return 15 + 2 * (max_ep_size / 4) + 2 * ep_count; } -static void update_grxfsiz(uint8_t rhport) -{ - dwc2_regs_t * dwc2 = DWC2_REG(rhport); - uint8_t const ep_count = _dwc2_controller[rhport].ep_count; +TU_ATTR_ALWAYS_INLINE static inline void fifo_flush_tx(dwc2_regs_t* dwc2, uint8_t epnum) { + // flush TX fifo and wait for it cleared + dwc2->grstctl = GRSTCTL_TXFFLSH | (epnum << GRSTCTL_TXFNUM_Pos); + while (dwc2->grstctl & GRSTCTL_TXFFLSH_Msk) {} +} +TU_ATTR_ALWAYS_INLINE static inline void fifo_flush_rx(dwc2_regs_t* dwc2) { + // flush RX fifo and wait for it cleared + dwc2->grstctl = GRSTCTL_RXFFLSH; + while (dwc2->grstctl & GRSTCTL_RXFFLSH_Msk) {} +} - // Determine largest EP size for RX FIFO - uint16_t max_epsize = 0; - for (uint8_t epnum = 0; epnum < ep_count; epnum++) - { - max_epsize = tu_max16(max_epsize, xfer_status[epnum][TUSB_DIR_OUT].max_size); +static bool fifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) { + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + uint8_t const ep_count = _dwc2_controller[rhport].ep_count; + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + TU_ASSERT(epnum < ep_count); + + uint16_t fifo_size = tu_div_ceil(packet_size, 4); + + // "USB Data FIFOs" section in reference manual + // Peripheral FIFO architecture + // + // --------------- 320 or 1024 ( 1280 or 4096 bytes ) + // | IN FIFO 0 | + // --------------- (320 or 1024) - 16 + // | IN FIFO 1 | + // --------------- (320 or 1024) - 16 - x + // | . . . . | + // --------------- (320 or 1024) - 16 - x - y - ... - z + // | IN FIFO MAX | + // --------------- + // | FREE | + // --------------- GRXFSIZ + // | OUT FIFO | + // | ( Shared ) | + // --------------- 0 + // + // In FIFO is allocated by following rules: + // - IN EP 1 gets FIFO 1, IN EP "n" gets FIFO "n". + if (dir == TUSB_DIR_OUT) { + // Calculate required size of RX FIFO + uint16_t const sz = calc_grxfsiz(4 * fifo_size, ep_count); + + // If size_rx needs to be extended check if possible and if so enlarge it + if (dwc2->grxfsiz < sz) { + TU_ASSERT(sz + _allocated_fifo_words_tx <= _dwc2_controller[rhport].ep_fifo_size / 4); + + // Enlarge RX FIFO + dwc2->grxfsiz = sz; + } + } else { + // Note if The TXFELVL is configured as half empty. In order + // to be able to write a packet at that point, the fifo must be twice the max_size. + if ((dwc2->gahbcfg & GAHBCFG_TXFELVL) == 0) { + fifo_size *= 2; + } + + // Check if free space is available + TU_ASSERT(_allocated_fifo_words_tx + fifo_size + dwc2->grxfsiz <= _dwc2_controller[rhport].ep_fifo_size / 4); + _allocated_fifo_words_tx += fifo_size; + TU_LOG(DWC2_DEBUG, " Allocated %u bytes at offset %" PRIu32, fifo_size * 4, + _dwc2_controller[rhport].ep_fifo_size - _allocated_fifo_words_tx * 4); + + // DIEPTXF starts at FIFO #1. + // Both TXFD and TXSA are in unit of 32-bit words. + dwc2->dieptxf[epnum - 1] = (fifo_size << DIEPTXF_INEPTXFD_Pos) | + (_dwc2_controller[rhport].ep_fifo_size / 4 - _allocated_fifo_words_tx); } - // Update size of RX FIFO - dwc2->grxfsiz = calc_grxfsiz(max_epsize, ep_count); + return true; +} + +static void edpt_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) { + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress); + uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); + + xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, dir); + xfer->max_size = tu_edpt_packet_size(p_endpoint_desc); + xfer->interval = p_endpoint_desc->bInterval; + + // USBAEP, EPTYP, SD0PID_SEVNFRM, MPSIZ are the same for IN and OUT endpoints. + uint32_t const dxepctl = (1 << DOEPCTL_USBAEP_Pos) | + (p_endpoint_desc->bmAttributes.xfer << DOEPCTL_EPTYP_Pos) | + (p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? DOEPCTL_SD0PID_SEVNFRM : 0) | + (xfer->max_size << DOEPCTL_MPSIZ_Pos); + + if (dir == TUSB_DIR_OUT) { + dwc2->epout[epnum].doepctl = dxepctl; + dwc2->daintmsk |= TU_BIT(DAINTMSK_OEPM_Pos + epnum); + } else { + dwc2->epin[epnum].diepctl = dxepctl | (epnum << DIEPCTL_TXFNUM_Pos); + dwc2->daintmsk |= (1 << (DAINTMSK_IEPM_Pos + epnum)); + } +} + +static void edpt_disable(uint8_t rhport, uint8_t ep_addr, bool stall) { + (void) rhport; + + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + if (dir == TUSB_DIR_IN) { + dwc2_epin_t* epin = dwc2->epin; + + // Only disable currently enabled non-control endpoint + if ((epnum == 0) || !(epin[epnum].diepctl & DIEPCTL_EPENA)) { + epin[epnum].diepctl |= DIEPCTL_SNAK | (stall ? DIEPCTL_STALL : 0); + } else { + // Stop transmitting packets and NAK IN xfers. + epin[epnum].diepctl |= DIEPCTL_SNAK; + while ((epin[epnum].diepint & DIEPINT_INEPNE) == 0) {} + + // Disable the endpoint. + epin[epnum].diepctl |= DIEPCTL_EPDIS | (stall ? DIEPCTL_STALL : 0); + while ((epin[epnum].diepint & DIEPINT_EPDISD_Msk) == 0) {} + + epin[epnum].diepint = DIEPINT_EPDISD; + } + + // Flush the FIFO, and wait until we have confirmed it cleared. + fifo_flush_tx(dwc2, epnum); + } else { + dwc2_epout_t* epout = dwc2->epout; + + // Only disable currently enabled non-control endpoint + if ((epnum == 0) || !(epout[epnum].doepctl & DOEPCTL_EPENA)) { + epout[epnum].doepctl |= stall ? DOEPCTL_STALL : 0; + } else { + // Asserting GONAK is required to STALL an OUT endpoint. + // Simpler to use polling here, we don't use the "B"OUTNAKEFF interrupt + // anyway, and it can't be cleared by user code. If this while loop never + // finishes, we have bigger problems than just the stack. + dwc2->dctl |= DCTL_SGONAK; + while ((dwc2->gintsts & GINTSTS_BOUTNAKEFF_Msk) == 0) {} + + // Ditto here- disable the endpoint. + epout[epnum].doepctl |= DOEPCTL_EPDIS | (stall ? DOEPCTL_STALL : 0); + while ((epout[epnum].doepint & DOEPINT_EPDISD_Msk) == 0) {} + + epout[epnum].doepint = DOEPINT_EPDISD; + + // Allow other OUT endpoints to keep receiving. + dwc2->dctl |= DCTL_CGONAK; + } + } } // Start of Bus Reset -static void bus_reset(uint8_t rhport) -{ - dwc2_regs_t * dwc2 = DWC2_REG(rhport); +static void bus_reset(uint8_t rhport) { + dwc2_regs_t* dwc2 = DWC2_REG(rhport); uint8_t const ep_count = _dwc2_controller[rhport].ep_count; tu_memclr(xfer_status, sizeof(xfer_status)); - _out_ep_closed = false; _sof_en = false; @@ -139,15 +276,24 @@ static void bus_reset(uint8_t rhport) dwc2->dcfg &= ~DCFG_DAD_Msk; // 1. NAK for all OUT endpoints - for ( uint8_t n = 0; n < ep_count; n++ ) - { + for (uint8_t n = 0; n < ep_count; n++) { dwc2->epout[n].doepctl |= DOEPCTL_SNAK; } - // 2. Set up interrupt mask + // 2. Disable all IN endpoints + for (uint8_t n = 0; n < ep_count; n++) { + if (dwc2->epin[n].diepctl & DIEPCTL_EPENA) { + dwc2->epin[n].diepctl |= DIEPCTL_SNAK | DIEPCTL_EPDIS; + } + } + + fifo_flush_tx(dwc2, 0x10); // all tx fifo + fifo_flush_rx(dwc2); + + // 3. Set up interrupt mask dwc2->daintmsk = TU_BIT(DAINTMSK_OEPM_Pos) | TU_BIT(DAINTMSK_IEPM_Pos); - dwc2->doepmsk = DOEPMSK_STUPM | DOEPMSK_XFRCM; - dwc2->diepmsk = DIEPMSK_TOM | DIEPMSK_XFRCM; + dwc2->doepmsk = DOEPMSK_STUPM | DOEPMSK_XFRCM; + dwc2->diepmsk = DIEPMSK_TOM | DIEPMSK_XFRCM; // "USB Data FIFOs" section in reference manual // Peripheral FIFO architecture @@ -206,36 +352,34 @@ static void bus_reset(uint8_t rhport) _allocated_fifo_words_tx = 16; // Control IN uses FIFO 0 with 64 bytes ( 16 32-bit word ) - dwc2->dieptxf0 = (16 << DIEPTXF0_TX0FD_Pos) | (_dwc2_controller[rhport].ep_fifo_size/4 - _allocated_fifo_words_tx); + dwc2->dieptxf0 = (16 << DIEPTXF0_TX0FD_Pos) | (_dwc2_controller[rhport].ep_fifo_size / 4 - _allocated_fifo_words_tx); // Fixed control EP0 size to 64 bytes dwc2->epin[0].diepctl &= ~(0x03 << DIEPCTL_MPSIZ_Pos); xfer_status[0][TUSB_DIR_OUT].max_size = 64; - xfer_status[0][TUSB_DIR_IN ].max_size = 64; + xfer_status[0][TUSB_DIR_IN].max_size = 64; dwc2->epout[0].doeptsiz |= (3 << DOEPTSIZ_STUPCNT_Pos); dwc2->gintmsk |= GINTMSK_OEPINT | GINTMSK_IEPINT; } -static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t const dir, uint16_t const num_packets, uint16_t total_bytes) -{ +static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t const dir, uint16_t const num_packets, + uint16_t total_bytes) { (void) rhport; - dwc2_regs_t * dwc2 = DWC2_REG(rhport); + dwc2_regs_t* dwc2 = DWC2_REG(rhport); // EP0 is limited to one packet each xfer // We use multiple transaction of xfer->max_size length to get a whole transfer done - if ( epnum == 0 ) - { - xfer_ctl_t *const xfer = XFER_CTL_BASE(epnum, dir); + if (epnum == 0) { + xfer_ctl_t* const xfer = XFER_CTL_BASE(epnum, dir); total_bytes = tu_min16(ep0_pending[dir], xfer->max_size); ep0_pending[dir] -= total_bytes; } // IN and OUT endpoint xfers are interrupt-driven, we just schedule them here. - if ( dir == TUSB_DIR_IN ) - { + if (dir == TUSB_DIR_IN) { dwc2_epin_t* epin = dwc2->epin; // A full IN transfer (multiple packets, possibly) triggers XFRC. @@ -245,20 +389,16 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c epin[epnum].diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK; // For ISO endpoint set correct odd/even bit for next frame. - if ( (epin[epnum].diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1 ) - { + if ((epin[epnum].diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) { // Take odd/even bit from frame counter. uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos)); epin[epnum].diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk); } // Enable fifo empty interrupt only if there are something to put in the fifo. - if ( total_bytes != 0 ) - { + if (total_bytes != 0) { dwc2->diepempmsk |= (1 << epnum); } - } - else - { + } else { dwc2_epout_t* epout = dwc2->epout; // A full OUT transfer (multiple packets, possibly) triggers XFRC. @@ -267,9 +407,8 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c ((total_bytes << DOEPTSIZ_XFRSIZ_Pos) & DOEPTSIZ_XFRSIZ_Msk); epout[epnum].doepctl |= DOEPCTL_EPENA | DOEPCTL_CNAK; - if ( (epout[epnum].doepctl & DOEPCTL_EPTYP) == DOEPCTL_EPTYP_0 && - XFER_CTL_BASE(epnum, dir)->interval == 1 ) - { + if ((epout[epnum].doepctl & DOEPCTL_EPTYP) == DOEPCTL_EPTYP_0 && + XFER_CTL_BASE(epnum, dir)->interval == 1) { // Take odd/even bit from frame counter. uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos)); epout[epnum].doepctl |= (odd_frame_now ? DOEPCTL_SD0PID_SEVNFRM_Msk : DOEPCTL_SODDFRM_Msk); @@ -281,103 +420,46 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c /* Controller API *------------------------------------------------------------------*/ #if CFG_TUSB_DEBUG >= DWC2_DEBUG -void print_dwc2_info(dwc2_regs_t * dwc2) -{ - dwc2_ghwcfg2_t const * hw_cfg2 = &dwc2->ghwcfg2_bm; - dwc2_ghwcfg3_t const * hw_cfg3 = &dwc2->ghwcfg3_bm; - dwc2_ghwcfg4_t const * hw_cfg4 = &dwc2->ghwcfg4_bm; - -// TU_LOG_HEX(DWC2_DEBUG, dwc2->gotgctl); -// TU_LOG_HEX(DWC2_DEBUG, dwc2->gusbcfg); -// TU_LOG_HEX(DWC2_DEBUG, dwc2->dcfg); - TU_LOG_HEX(DWC2_DEBUG, dwc2->guid); - TU_LOG_HEX(DWC2_DEBUG, dwc2->gsnpsid); - TU_LOG_HEX(DWC2_DEBUG, dwc2->ghwcfg1); - - // HW configure 2 - TU_LOG(DWC2_DEBUG, "\r\n"); - TU_LOG_HEX(DWC2_DEBUG, dwc2->ghwcfg2); - TU_LOG_INT(DWC2_DEBUG, hw_cfg2->op_mode ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg2->arch ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg2->point2point ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg2->hs_phy_type ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg2->fs_phy_type ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg2->num_dev_ep ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg2->num_host_ch ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg2->period_channel_support ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg2->enable_dynamic_fifo ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg2->mul_cpu_int ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg2->nperiod_tx_q_depth ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg2->host_period_tx_q_depth ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg2->dev_token_q_depth ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg2->otg_enable_ic_usb ); - - // HW configure 3 - TU_LOG(DWC2_DEBUG, "\r\n"); - TU_LOG_HEX(DWC2_DEBUG, dwc2->ghwcfg3); - TU_LOG_INT(DWC2_DEBUG, hw_cfg3->xfer_size_width ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg3->packet_size_width ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg3->otg_enable ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg3->i2c_enable ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg3->vendor_ctrl_itf ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg3->optional_feature_removed ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg3->synch_reset ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg3->otg_adp_support ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg3->otg_enable_hsic ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg3->battery_charger_support ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg3->lpm_mode ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg3->total_fifo_size ); - - // HW configure 4 - TU_LOG(DWC2_DEBUG, "\r\n"); - TU_LOG_HEX(DWC2_DEBUG, dwc2->ghwcfg4); - TU_LOG_INT(DWC2_DEBUG, hw_cfg4->num_dev_period_in_ep ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg4->power_optimized ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg4->ahb_freq_min ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg4->hibernation ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg4->service_interval_mode ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg4->ipg_isoc_en ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg4->acg_enable ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg4->utmi_phy_data_width ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg4->dev_ctrl_ep_num ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg4->iddg_filter_enabled ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg4->vbus_valid_filter_enabled ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg4->a_valid_filter_enabled ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg4->b_valid_filter_enabled ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg4->dedicated_fifos ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg4->num_dev_in_eps ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg4->dma_desc_enable ); - TU_LOG_INT(DWC2_DEBUG, hw_cfg4->dma_dynamic ); +void print_dwc2_info(dwc2_regs_t* dwc2) { + // print guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4 + // use dwc2_info.py/md for bit-field value and comparison with other ports + volatile uint32_t const* p = (volatile uint32_t const*) &dwc2->guid; + TU_LOG(DWC2_DEBUG, "guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4\r\n"); + for (size_t i = 0; i < 5; i++) { + TU_LOG(DWC2_DEBUG, "0x%08" PRIX32 ", ", p[i]); + } + TU_LOG(DWC2_DEBUG, "0x%08" PRIX32 "\r\n", p[5]); } #endif -static void reset_core(dwc2_regs_t * dwc2) -{ +static void reset_core(dwc2_regs_t* dwc2) { // reset core dwc2->grstctl |= GRSTCTL_CSRST; // wait for reset bit is cleared // TODO version 4.20a should wait for RESET DONE mask - while (dwc2->grstctl & GRSTCTL_CSRST) { } + while (dwc2->grstctl & GRSTCTL_CSRST) {} // wait for AHB master IDLE - while ( !(dwc2->grstctl & GRSTCTL_AHBIDL) ) { } + while (!(dwc2->grstctl & GRSTCTL_AHBIDL)) {} // wait for device mode ? } -static bool phy_hs_supported(dwc2_regs_t * dwc2) -{ - // note: esp32 incorrect report its hs_phy_type as utmi +static bool phy_hs_supported(dwc2_regs_t* dwc2) { + (void) dwc2; + #if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) + // note: esp32 incorrect report its hs_phy_type as utmi + return false; +#elif !TUD_OPT_HIGH_SPEED return false; #else - return TUD_OPT_HIGH_SPEED && dwc2->ghwcfg2_bm.hs_phy_type != HS_PHY_TYPE_NONE; + return dwc2->ghwcfg2_bm.hs_phy_type != HS_PHY_TYPE_NONE; #endif } -static void phy_fs_init(dwc2_regs_t * dwc2) -{ +static void phy_fs_init(dwc2_regs_t* dwc2) { TU_LOG(DWC2_DEBUG, "Fullspeed PHY init\r\n"); // Select FS PHY @@ -401,15 +483,13 @@ static void phy_fs_init(dwc2_regs_t * dwc2) dwc2->dcfg = (dwc2->dcfg & ~DCFG_DSPD_Msk) | (DCFG_DSPD_FS << DCFG_DSPD_Pos); } -static void phy_hs_init(dwc2_regs_t * dwc2) -{ +static void phy_hs_init(dwc2_regs_t* dwc2) { uint32_t gusbcfg = dwc2->gusbcfg; // De-select FS PHY gusbcfg &= ~GUSBCFG_PHYSEL; - if (dwc2->ghwcfg2_bm.hs_phy_type == HS_PHY_TYPE_ULPI) - { + if (dwc2->ghwcfg2_bm.hs_phy_type == HS_PHY_TYPE_ULPI) { TU_LOG(DWC2_DEBUG, "Highspeed ULPI PHY init\r\n"); // Select ULPI @@ -423,8 +503,7 @@ static void phy_hs_init(dwc2_regs_t * dwc2) // Disable FS/LS ULPI gusbcfg &= ~(GUSBCFG_ULPIFSLS | GUSBCFG_ULPICSM); - }else - { + } else { TU_LOG(DWC2_DEBUG, "Highspeed UTMI+ PHY init\r\n"); // Select UTMI+ with 8-bit interface @@ -465,8 +544,7 @@ static void phy_hs_init(dwc2_regs_t * dwc2) dwc2->dcfg = dcfg; } -static bool check_dwc2(dwc2_regs_t * dwc2) -{ +static bool check_dwc2(dwc2_regs_t* dwc2) { #if CFG_TUSB_DEBUG >= DWC2_DEBUG print_dwc2_info(dwc2); #endif @@ -481,41 +559,35 @@ static bool check_dwc2(dwc2_regs_t * dwc2) return true; } -void dcd_init (uint8_t rhport) -{ +void dcd_init(uint8_t rhport) { // Programming model begins in the last section of the chapter on the USB // peripheral in each Reference Manual. - dwc2_regs_t * dwc2 = DWC2_REG(rhport); + dwc2_regs_t* dwc2 = DWC2_REG(rhport); // Check Synopsys ID register, failed if controller clock/power is not enabled - TU_VERIFY(check_dwc2(dwc2), ); - + if (!check_dwc2(dwc2)) return; dcd_disconnect(rhport); // max number of endpoints & total_fifo_size are: // hw_cfg2->num_dev_ep, hw_cfg2->total_fifo_size - if( phy_hs_supported(dwc2) ) - { - // Highspeed - phy_hs_init(dwc2); - }else - { - // core does not support highspeed or hs-phy is not present - phy_fs_init(dwc2); + if (phy_hs_supported(dwc2)) { + phy_hs_init(dwc2); // Highspeed + } else { + phy_fs_init(dwc2); // core does not support highspeed or hs phy is not present } // Restart PHY clock dwc2->pcgctl &= ~(PCGCTL_STOPPCLK | PCGCTL_GATEHCLK | PCGCTL_PWRCLMP | PCGCTL_RSTPDWNMODULE); - /* Set HS/FS Timeout Calibration to 7 (max available value). - * The number of PHY clocks that the application programs in - * this field is added to the high/full speed interpacket timeout - * duration in the core to account for any additional delays - * introduced by the PHY. This can be required, because the delay - * introduced by the PHY in generating the linestate condition - * can vary from one PHY to another. - */ + /* Set HS/FS Timeout Calibration to 7 (max available value). + * The number of PHY clocks that the application programs in + * this field is added to the high/full speed interpacket timeout + * duration in the core to account for any additional delays + * introduced by the PHY. This can be required, because the delay + * introduced by the PHY in generating the linestate condition + * can vary from one PHY to another. + */ dwc2->gusbcfg |= (7ul << GUSBCFG_TOCAL_Pos); // Force device mode @@ -528,6 +600,9 @@ void dcd_init (uint8_t rhport) // (non zero-length packet), send STALL back and discard. dwc2->dcfg |= DCFG_NZLSOHSK; + fifo_flush_tx(dwc2, 0x10); // all tx fifo + fifo_flush_rx(dwc2); + // Clear all interrupts uint32_t int_mask = dwc2->gintsts; dwc2->gintsts |= int_mask; @@ -535,11 +610,12 @@ void dcd_init (uint8_t rhport) dwc2->gotgint |= int_mask; // Required as part of core initialization. - // TODO: How should mode mismatch be handled? It will cause - // the core to stop working/require reset. - dwc2->gintmsk = GINTMSK_OTGINT | GINTMSK_MMISM | GINTMSK_RXFLVLM | + dwc2->gintmsk = GINTMSK_OTGINT | GINTMSK_RXFLVLM | GINTMSK_USBSUSPM | GINTMSK_USBRST | GINTMSK_ENUMDNEM | GINTMSK_WUIM; + // Configure TX FIFO empty level for interrupt. Default is complete empty + dwc2->gahbcfg |= GAHBCFG_TXFELVL; + // Enable global interrupt dwc2->gahbcfg |= GAHBCFG_GINT; @@ -554,30 +630,26 @@ void dcd_init (uint8_t rhport) dcd_connect(rhport); } -void dcd_int_enable (uint8_t rhport) -{ +void dcd_int_enable(uint8_t rhport) { dwc2_dcd_int_enable(rhport); } -void dcd_int_disable (uint8_t rhport) -{ +void dcd_int_disable(uint8_t rhport) { dwc2_dcd_int_disable(rhport); } -void dcd_set_address (uint8_t rhport, uint8_t dev_addr) -{ - dwc2_regs_t * dwc2 = DWC2_REG(rhport); +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { + dwc2_regs_t* dwc2 = DWC2_REG(rhport); dwc2->dcfg = (dwc2->dcfg & ~DCFG_DAD_Msk) | (dev_addr << DCFG_DAD_Pos); // Response with status after changing device address dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); } -void dcd_remote_wakeup(uint8_t rhport) -{ +void dcd_remote_wakeup(uint8_t rhport) { (void) rhport; - dwc2_regs_t * dwc2 = DWC2_REG(rhport); + dwc2_regs_t* dwc2 = DWC2_REG(rhport); // set remote wakeup dwc2->dctl |= DCTL_RWUSIG; @@ -592,35 +664,29 @@ void dcd_remote_wakeup(uint8_t rhport) dwc2->dctl &= ~DCTL_RWUSIG; } -void dcd_connect(uint8_t rhport) -{ +void dcd_connect(uint8_t rhport) { (void) rhport; - dwc2_regs_t * dwc2 = DWC2_REG(rhport); + dwc2_regs_t* dwc2 = DWC2_REG(rhport); dwc2->dctl &= ~DCTL_SDIS; } -void dcd_disconnect(uint8_t rhport) -{ +void dcd_disconnect(uint8_t rhport) { (void) rhport; - dwc2_regs_t * dwc2 = DWC2_REG(rhport); + dwc2_regs_t* dwc2 = DWC2_REG(rhport); dwc2->dctl |= DCTL_SDIS; } // Be advised: audio, video and possibly other iso-ep classes use dcd_sof_enable() to enable/disable its corresponding ISR on purpose! -void dcd_sof_enable(uint8_t rhport, bool en) -{ +void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; - dwc2_regs_t * dwc2 = DWC2_REG(rhport); + dwc2_regs_t* dwc2 = DWC2_REG(rhport); _sof_en = en; - if (en) - { + if (en) { dwc2->gintsts = GINTSTS_SOF; dwc2->gintmsk |= GINTMSK_SOFM; - } - else - { + } else { dwc2->gintmsk &= ~GINTMSK_SOFM; } } @@ -629,140 +695,78 @@ void dcd_sof_enable(uint8_t rhport, bool en) /* DCD Endpoint port *------------------------------------------------------------------*/ -bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) -{ - (void) rhport; - - dwc2_regs_t * dwc2 = DWC2_REG(rhport); - uint8_t const ep_count = _dwc2_controller[rhport].ep_count; - - uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); - uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); - - TU_ASSERT(epnum < ep_count); - - xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); - xfer->max_size = tu_edpt_packet_size(desc_edpt); - xfer->interval = desc_edpt->bInterval; - - uint16_t const fifo_size = tu_div_ceil(xfer->max_size, 4); - - if(dir == TUSB_DIR_OUT) - { - // Calculate required size of RX FIFO - uint16_t const sz = calc_grxfsiz(4*fifo_size, ep_count); - - // If size_rx needs to be extended check if possible and if so enlarge it - if (dwc2->grxfsiz < sz) - { - TU_ASSERT(sz + _allocated_fifo_words_tx <= _dwc2_controller[rhport].ep_fifo_size/4); - - // Enlarge RX FIFO - dwc2->grxfsiz = sz; - } - - dwc2->epout[epnum].doepctl |= (1 << DOEPCTL_USBAEP_Pos) | - (desc_edpt->bmAttributes.xfer << DOEPCTL_EPTYP_Pos) | - (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? DOEPCTL_SD0PID_SEVNFRM : 0) | - (xfer->max_size << DOEPCTL_MPSIZ_Pos); - - dwc2->daintmsk |= TU_BIT(DAINTMSK_OEPM_Pos + epnum); - } - else - { - // "USB Data FIFOs" section in reference manual - // Peripheral FIFO architecture - // - // --------------- 320 or 1024 ( 1280 or 4096 bytes ) - // | IN FIFO 0 | - // --------------- (320 or 1024) - 16 - // | IN FIFO 1 | - // --------------- (320 or 1024) - 16 - x - // | . . . . | - // --------------- (320 or 1024) - 16 - x - y - ... - z - // | IN FIFO MAX | - // --------------- - // | FREE | - // --------------- GRXFSIZ - // | OUT FIFO | - // | ( Shared ) | - // --------------- 0 - // - // In FIFO is allocated by following rules: - // - IN EP 1 gets FIFO 1, IN EP "n" gets FIFO "n". - - // Check if free space is available - TU_ASSERT(_allocated_fifo_words_tx + fifo_size + dwc2->grxfsiz <= _dwc2_controller[rhport].ep_fifo_size/4); - - _allocated_fifo_words_tx += fifo_size; - - TU_LOG(DWC2_DEBUG, " Allocated %u bytes at offset %lu", fifo_size*4, _dwc2_controller[rhport].ep_fifo_size-_allocated_fifo_words_tx*4); - - // DIEPTXF starts at FIFO #1. - // Both TXFD and TXSA are in unit of 32-bit words. - dwc2->dieptxf[epnum - 1] = (fifo_size << DIEPTXF_INEPTXFD_Pos) | (_dwc2_controller[rhport].ep_fifo_size/4 - _allocated_fifo_words_tx); - - dwc2->epin[epnum].diepctl |= (1 << DIEPCTL_USBAEP_Pos) | - (epnum << DIEPCTL_TXFNUM_Pos) | - (desc_edpt->bmAttributes.xfer << DIEPCTL_EPTYP_Pos) | - (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? DIEPCTL_SD0PID_SEVNFRM : 0) | - (xfer->max_size << DIEPCTL_MPSIZ_Pos); - - dwc2->daintmsk |= (1 << (DAINTMSK_IEPM_Pos + epnum)); - } - +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const* desc_edpt) { + TU_ASSERT(fifo_alloc(rhport, desc_edpt->bEndpointAddress, tu_edpt_packet_size(desc_edpt))); + edpt_activate(rhport, desc_edpt); return true; } // Close all non-control endpoints, cancel all pending transfers if any. -void dcd_edpt_close_all (uint8_t rhport) -{ - dwc2_regs_t * dwc2 = DWC2_REG(rhport); +void dcd_edpt_close_all(uint8_t rhport) { + dwc2_regs_t* dwc2 = DWC2_REG(rhport); uint8_t const ep_count = _dwc2_controller[rhport].ep_count; // Disable non-control interrupt dwc2->daintmsk = (1 << DAINTMSK_OEPM_Pos) | (1 << DAINTMSK_IEPM_Pos); - for(uint8_t n = 1; n < ep_count; n++) - { + for (uint8_t n = 1; n < ep_count; n++) { // disable OUT endpoint - dwc2->epout[n].doepctl = 0; + if (dwc2->epout[n].doepctl & DOEPCTL_EPENA) { + dwc2->epout[n].doepctl |= DOEPCTL_SNAK | DOEPCTL_EPDIS; + } xfer_status[n][TUSB_DIR_OUT].max_size = 0; // disable IN endpoint - dwc2->epin[n].diepctl = 0; + if (dwc2->epin[n].diepctl & DIEPCTL_EPENA) { + dwc2->epin[n].diepctl |= DIEPCTL_SNAK | DIEPCTL_EPDIS; + } xfer_status[n][TUSB_DIR_IN].max_size = 0; } + // reset allocated fifo OUT + dwc2->grxfsiz = calc_grxfsiz(64, ep_count); // reset allocated fifo IN _allocated_fifo_words_tx = 16; + + fifo_flush_tx(dwc2, 0x10); // all tx fifo + fifo_flush_rx(dwc2); } -bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) -{ - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { + TU_ASSERT(fifo_alloc(rhport, ep_addr, largest_packet_size)); + return true; +} - xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); - xfer->buffer = buffer; - xfer->ff = NULL; - xfer->total_len = total_bytes; +bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) { + // Disable EP to clear potential incomplete transfers + edpt_disable(rhport, p_endpoint_desc->bEndpointAddress, false); + + edpt_activate(rhport, p_endpoint_desc); + + return true; +} + +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) { + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, dir); + xfer->buffer = buffer; + xfer->ff = NULL; + xfer->total_len = total_bytes; // EP0 can only handle one packet - if(epnum == 0) - { + if (epnum == 0) { ep0_pending[dir] = total_bytes; // Schedule the first transaction for EP0 transfer edpt_schedule_packets(rhport, epnum, dir, 1, ep0_pending[dir]); - } - else - { + } else { uint16_t num_packets = (total_bytes / xfer->max_size); uint16_t const short_packet_size = total_bytes % xfer->max_size; // Zero-size packet is special case. - if ( (short_packet_size > 0) || (total_bytes == 0) ) num_packets++; + if ((short_packet_size > 0) || (total_bytes == 0)) num_packets++; // Schedule packets to be sent within interrupt edpt_schedule_packets(rhport, epnum, dir, num_packets, total_bytes); @@ -775,24 +779,23 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t // bytes should be written and second to keep the return value free to give back a boolean // success message. If total_bytes is too big, the FIFO will copy only what is available // into the USB buffer! -bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) -{ +bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_t total_bytes) { // USB buffers always work in bytes so to avoid unnecessary divisions we demand item_size = 1 TU_ASSERT(ff->item_size == 1); uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); - xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); - xfer->buffer = NULL; - xfer->ff = ff; - xfer->total_len = total_bytes; + xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, dir); + xfer->buffer = NULL; + xfer->ff = ff; + xfer->total_len = total_bytes; uint16_t num_packets = (total_bytes / xfer->max_size); uint16_t const short_packet_size = total_bytes % xfer->max_size; // Zero-size packet is special case. - if ( short_packet_size > 0 || (total_bytes == 0) ) num_packets++; + if (short_packet_size > 0 || (total_bytes == 0)) num_packets++; // Schedule packets to be sent within interrupt edpt_schedule_packets(rhport, epnum, dir, num_packets, total_bytes); @@ -800,123 +803,27 @@ bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16 return true; } -static void dcd_edpt_disable (uint8_t rhport, uint8_t ep_addr, bool stall) -{ +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { + edpt_disable(rhport, ep_addr, false); +} + +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { + edpt_disable(rhport, ep_addr, true); +} + +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; - dwc2_regs_t *dwc2 = DWC2_REG(rhport); + dwc2_regs_t* dwc2 = DWC2_REG(rhport); uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - if ( dir == TUSB_DIR_IN ) - { - dwc2_epin_t* epin = dwc2->epin; - - // Only disable currently enabled non-control endpoint - if ( (epnum == 0) || !(epin[epnum].diepctl & DIEPCTL_EPENA) ) - { - epin[epnum].diepctl |= DIEPCTL_SNAK | (stall ? DIEPCTL_STALL : 0); - } - else - { - // Stop transmitting packets and NAK IN xfers. - epin[epnum].diepctl |= DIEPCTL_SNAK; - while ( (epin[epnum].diepint & DIEPINT_INEPNE) == 0 ) {} - - // Disable the endpoint. - epin[epnum].diepctl |= DIEPCTL_EPDIS | (stall ? DIEPCTL_STALL : 0); - while ( (epin[epnum].diepint & DIEPINT_EPDISD_Msk) == 0 ) {} - - epin[epnum].diepint = DIEPINT_EPDISD; - } - - // Flush the FIFO, and wait until we have confirmed it cleared. - dwc2->grstctl = ((epnum << GRSTCTL_TXFNUM_Pos) | GRSTCTL_TXFFLSH); - while ( (dwc2->grstctl & GRSTCTL_TXFFLSH_Msk) != 0 ) {} - } - else - { - dwc2_epout_t* epout = dwc2->epout; - - // Only disable currently enabled non-control endpoint - if ( (epnum == 0) || !(epout[epnum].doepctl & DOEPCTL_EPENA) ) - { - epout[epnum].doepctl |= stall ? DOEPCTL_STALL : 0; - } - else - { - // Asserting GONAK is required to STALL an OUT endpoint. - // Simpler to use polling here, we don't use the "B"OUTNAKEFF interrupt - // anyway, and it can't be cleared by user code. If this while loop never - // finishes, we have bigger problems than just the stack. - dwc2->dctl |= DCTL_SGONAK; - while ( (dwc2->gintsts & GINTSTS_BOUTNAKEFF_Msk) == 0 ) {} - - // Ditto here- disable the endpoint. - epout[epnum].doepctl |= DOEPCTL_EPDIS | (stall ? DOEPCTL_STALL : 0); - while ( (epout[epnum].doepint & DOEPINT_EPDISD_Msk) == 0 ) {} - - epout[epnum].doepint = DOEPINT_EPDISD; - - // Allow other OUT endpoints to keep receiving. - dwc2->dctl |= DCTL_CGONAK; - } - } -} - -/** - * Close an endpoint. - */ -void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) -{ - dwc2_regs_t * dwc2 = DWC2_REG(rhport); - - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - dcd_edpt_disable(rhport, ep_addr, false); - - // Update max_size - xfer_status[epnum][dir].max_size = 0; // max_size = 0 marks a disabled EP - required for changing FIFO allocation - - if (dir == TUSB_DIR_IN) - { - uint16_t const fifo_size = (dwc2->dieptxf[epnum - 1] & DIEPTXF_INEPTXFD_Msk) >> DIEPTXF_INEPTXFD_Pos; - uint16_t const fifo_start = (dwc2->dieptxf[epnum - 1] & DIEPTXF_INEPTXSA_Msk) >> DIEPTXF_INEPTXSA_Pos; - - // For now only the last opened endpoint can be closed without fuss. - TU_ASSERT(fifo_start == _dwc2_controller[rhport].ep_fifo_size/4 - _allocated_fifo_words_tx,); - _allocated_fifo_words_tx -= fifo_size; - } - else - { - _out_ep_closed = true; // Set flag such that RX FIFO gets reduced in size once RX FIFO is empty - } -} - -void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) -{ - dcd_edpt_disable(rhport, ep_addr, true); -} - -void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) -{ - (void) rhport; - - dwc2_regs_t * dwc2 = DWC2_REG(rhport); - - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); // Clear stall and reset data toggle - if ( dir == TUSB_DIR_IN ) - { + if (dir == TUSB_DIR_IN) { dwc2->epin[epnum].diepctl &= ~DIEPCTL_STALL; dwc2->epin[epnum].diepctl |= DIEPCTL_SD0PID_SEVNFRM; - } - else - { + } else { dwc2->epout[epnum].doepctl &= ~DOEPCTL_STALL; dwc2->epout[epnum].doepctl |= DOEPCTL_SD0PID_SEVNFRM; } @@ -925,70 +832,63 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) /*------------------------------------------------------------------*/ // Read a single data packet from receive FIFO -static void read_fifo_packet(uint8_t rhport, uint8_t * dst, uint16_t len) -{ +static void read_fifo_packet(uint8_t rhport, uint8_t* dst, uint16_t len) { (void) rhport; - dwc2_regs_t * dwc2 = DWC2_REG(rhport); - volatile const uint32_t * rx_fifo = dwc2->fifo[0]; + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + volatile const uint32_t* rx_fifo = dwc2->fifo[0]; // Reading full available 32 bit words from fifo uint16_t full_words = len >> 2; - while(full_words--) - { + while (full_words--) { tu_unaligned_write32(dst, *rx_fifo); dst += 4; } // Read the remaining 1-3 bytes from fifo uint8_t const bytes_rem = len & 0x03; - if ( bytes_rem != 0 ) - { + if (bytes_rem != 0) { uint32_t const tmp = *rx_fifo; dst[0] = tu_u32_byte0(tmp); - if ( bytes_rem > 1 ) dst[1] = tu_u32_byte1(tmp); - if ( bytes_rem > 2 ) dst[2] = tu_u32_byte2(tmp); + if (bytes_rem > 1) dst[1] = tu_u32_byte1(tmp); + if (bytes_rem > 2) dst[2] = tu_u32_byte2(tmp); } } // Write a single data packet to EPIN FIFO -static void write_fifo_packet(uint8_t rhport, uint8_t fifo_num, uint8_t const * src, uint16_t len) -{ +static void write_fifo_packet(uint8_t rhport, uint8_t fifo_num, uint8_t const* src, uint16_t len) { (void) rhport; - dwc2_regs_t * dwc2 = DWC2_REG(rhport); - volatile uint32_t * tx_fifo = dwc2->fifo[fifo_num]; + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + volatile uint32_t* tx_fifo = dwc2->fifo[fifo_num]; // Pushing full available 32 bit words to fifo uint16_t full_words = len >> 2; - while(full_words--) - { + while (full_words--) { *tx_fifo = tu_unaligned_read32(src); src += 4; } // Write the remaining 1-3 bytes into fifo uint8_t const bytes_rem = len & 0x03; - if ( bytes_rem ) - { + if (bytes_rem) { uint32_t tmp_word = src[0]; - if ( bytes_rem > 1 ) tmp_word |= (src[1] << 8); - if ( bytes_rem > 2 ) tmp_word |= (src[2] << 16); + if (bytes_rem > 1) tmp_word |= (src[1] << 8); + if (bytes_rem > 2) tmp_word |= (src[2] << 16); *tx_fifo = tmp_word; } } -static void handle_rxflvl_irq(uint8_t rhport) -{ - dwc2_regs_t * dwc2 = DWC2_REG(rhport); - volatile uint32_t const * rx_fifo = dwc2->fifo[0]; +static void handle_rxflvl_irq(uint8_t rhport) { + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + volatile uint32_t const* rx_fifo = dwc2->fifo[0]; // Pop control word off FIFO uint32_t const ctl_word = dwc2->grxstsp; - uint8_t const pktsts = (ctl_word & GRXSTSP_PKTSTS_Msk ) >> GRXSTSP_PKTSTS_Pos; - uint8_t const epnum = (ctl_word & GRXSTSP_EPNUM_Msk ) >> GRXSTSP_EPNUM_Pos; - uint16_t const bcnt = (ctl_word & GRXSTSP_BCNT_Msk ) >> GRXSTSP_BCNT_Pos; + uint8_t const pktsts = (ctl_word & GRXSTSP_PKTSTS_Msk) >> GRXSTSP_PKTSTS_Pos; + uint8_t const epnum = (ctl_word & GRXSTSP_EPNUM_Msk) >> GRXSTSP_EPNUM_Pos; + uint16_t const bcnt = (ctl_word & GRXSTSP_BCNT_Msk) >> GRXSTSP_BCNT_Pos; dwc2_epout_t* epout = &dwc2->epout[epnum]; @@ -1003,10 +903,10 @@ static void handle_rxflvl_irq(uint8_t rhport) // TU_LOG(DWC2_DEBUG, " daint = %08lX, doepint = %04X\r\n", (unsigned long) dwc2->daint, (unsigned int) epout->doepint); //#endif - switch ( pktsts ) - { + switch (pktsts) { // Global OUT NAK: do nothing - case GRXSTS_PKTSTS_GLOBALOUTNAK: break; + case GRXSTS_PKTSTS_GLOBALOUTNAK: + break; case GRXSTS_PKTSTS_SETUPRX: // Setup packet received @@ -1015,26 +915,22 @@ static void handle_rxflvl_irq(uint8_t rhport) // only the last one is valid. _setup_packet[0] = (*rx_fifo); _setup_packet[1] = (*rx_fifo); - break; + break; case GRXSTS_PKTSTS_SETUPDONE: // Setup packet done (Interrupt) epout->doeptsiz |= (3 << DOEPTSIZ_STUPCNT_Pos); - break; + break; - case GRXSTS_PKTSTS_OUTRX: - { + case GRXSTS_PKTSTS_OUTRX: { // Out packet received - xfer_ctl_t *xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); + xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); // Read packet off RxFIFO - if ( xfer->ff ) - { + if (xfer->ff) { // Ring buffer tu_fifo_write_n_const_addr_full_words(xfer->ff, (const void*) (uintptr_t) rx_fifo, bcnt); - } - else - { + } else { // Linear buffer read_fifo_packet(rhport, xfer->buffer, bcnt); @@ -1043,73 +939,64 @@ static void handle_rxflvl_irq(uint8_t rhport) } // Truncate transfer length in case of short packet - if ( bcnt < xfer->max_size ) - { + if (bcnt < xfer->max_size) { xfer->total_len -= (epout->doeptsiz & DOEPTSIZ_XFRSIZ_Msk) >> DOEPTSIZ_XFRSIZ_Pos; - if ( epnum == 0 ) - { + if (epnum == 0) { xfer->total_len -= ep0_pending[TUSB_DIR_OUT]; ep0_pending[TUSB_DIR_OUT] = 0; } } } - break; + break; - // Out packet done (Interrupt) + // Out packet done (Interrupt) case GRXSTS_PKTSTS_OUTDONE: - // Occurred on STM32L47 with dwc2 version 3.10a but not found on other version like 2.80a or 3.30a - // May (or not) be 3.10a specific feature/bug or depending on MCU configuration - // XFRC complete is additionally generated when - // - setup packet is received - // - complete the data stage of control write is complete - if ((epnum == 0) && (bcnt == 0) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) - { - uint32_t doepint = epout->doepint; + // Occurred on STM32L47 with dwc2 version 3.10a but not found on other version like 2.80a or 3.30a + // May (or not) be 3.10a specific feature/bug or depending on MCU configuration + // XFRC complete is additionally generated when + // - setup packet is received + // - complete the data stage of control write is complete + if ((epnum == 0) && (bcnt == 0) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { + uint32_t doepint = epout->doepint; - if (doepint & (DOEPINT_STPKTRX | DOEPINT_OTEPSPR)) - { - // skip this "no-data" transfer complete event - // Note: STPKTRX will be clear later by setup received handler - uint32_t clear_flags = DOEPINT_XFRC; + if (doepint & (DOEPINT_STPKTRX | DOEPINT_OTEPSPR)) { + // skip this "no-data" transfer complete event + // Note: STPKTRX will be clear later by setup received handler + uint32_t clear_flags = DOEPINT_XFRC; - if (doepint & DOEPINT_OTEPSPR) clear_flags |= DOEPINT_OTEPSPR; + if (doepint & DOEPINT_OTEPSPR) clear_flags |= DOEPINT_OTEPSPR; - epout->doepint = clear_flags; + epout->doepint = clear_flags; - // TU_LOG(DWC2_DEBUG, " FIX extra transfer complete on setup/data compete\r\n"); - } + // TU_LOG(DWC2_DEBUG, " FIX extra transfer complete on setup/data compete\r\n"); } - break; + } + break; default: // Invalid TU_BREAKPOINT(); - break; + break; } } -static void handle_epout_irq (uint8_t rhport) -{ - dwc2_regs_t * dwc2 = DWC2_REG(rhport); +static void handle_epout_irq(uint8_t rhport) { + dwc2_regs_t* dwc2 = DWC2_REG(rhport); uint8_t const ep_count = _dwc2_controller[rhport].ep_count; // DAINT for a given EP clears when DOEPINTx is cleared. // OEPINT will be cleared when DAINT's out bits are cleared. - for ( uint8_t n = 0; n < ep_count; n++ ) - { - if ( dwc2->daint & TU_BIT(DAINT_OEPINT_Pos + n) ) - { + for (uint8_t n = 0; n < ep_count; n++) { + if (dwc2->daint & TU_BIT(DAINT_OEPINT_Pos + n)) { dwc2_epout_t* epout = &dwc2->epout[n]; uint32_t const doepint = epout->doepint; // SETUP packet Setup Phase done. - if ( doepint & DOEPINT_STUP ) - { + if (doepint & DOEPINT_STUP) { uint32_t clear_flag = DOEPINT_STUP; // STPKTRX is only available for version from 3_00a - if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) - { + if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { clear_flag |= DOEPINT_STPKTRX; } @@ -1118,20 +1005,16 @@ static void handle_epout_irq (uint8_t rhport) } // OUT XFER complete - if ( epout->doepint & DOEPINT_XFRC ) - { + if (epout->doepint & DOEPINT_XFRC) { epout->doepint = DOEPINT_XFRC; - xfer_ctl_t *xfer = XFER_CTL_BASE(n, TUSB_DIR_OUT); + xfer_ctl_t* xfer = XFER_CTL_BASE(n, TUSB_DIR_OUT); // EP0 can only handle one packet - if ( (n == 0) && ep0_pending[TUSB_DIR_OUT] ) - { + if ((n == 0) && ep0_pending[TUSB_DIR_OUT]) { // Schedule another packet to be received. edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); - } - else - { + } else { dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); } } @@ -1139,40 +1022,32 @@ static void handle_epout_irq (uint8_t rhport) } } -static void handle_epin_irq (uint8_t rhport) -{ - dwc2_regs_t * dwc2 = DWC2_REG(rhport); +static void handle_epin_irq(uint8_t rhport) { + dwc2_regs_t* dwc2 = DWC2_REG(rhport); uint8_t const ep_count = _dwc2_controller[rhport].ep_count; - dwc2_epin_t* epin = dwc2->epin; + dwc2_epin_t* epin = dwc2->epin; // DAINT for a given EP clears when DIEPINTx is cleared. // IEPINT will be cleared when DAINT's out bits are cleared. - for ( uint8_t n = 0; n < ep_count; n++ ) - { - if ( dwc2->daint & TU_BIT(DAINT_IEPINT_Pos + n) ) - { + for (uint8_t n = 0; n < ep_count; n++) { + if (dwc2->daint & TU_BIT(DAINT_IEPINT_Pos + n)) { // IN XFER complete (entire xfer). - xfer_ctl_t *xfer = XFER_CTL_BASE(n, TUSB_DIR_IN); + xfer_ctl_t* xfer = XFER_CTL_BASE(n, TUSB_DIR_IN); - if ( epin[n].diepint & DIEPINT_XFRC ) - { + if (epin[n].diepint & DIEPINT_XFRC) { epin[n].diepint = DIEPINT_XFRC; // EP0 can only handle one packet - if ( (n == 0) && ep0_pending[TUSB_DIR_IN] ) - { + if ((n == 0) && ep0_pending[TUSB_DIR_IN]) { // Schedule another packet to be transmitted. edpt_schedule_packets(rhport, n, TUSB_DIR_IN, 1, ep0_pending[TUSB_DIR_IN]); - } - else - { + } else { dcd_event_xfer_complete(rhport, n | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true); } } // XFER FIFO empty - if ( (epin[n].diepint & DIEPINT_TXFE) && (dwc2->diepempmsk & (1 << n)) ) - { + if ((epin[n].diepint & DIEPINT_TXFE) && (dwc2->diepempmsk & (1 << n))) { // diepint's TXFE bit is read-only, software cannot clear it. // It will only be cleared by hardware when written bytes is more than // - 64 bytes or @@ -1181,8 +1056,7 @@ static void handle_epin_irq (uint8_t rhport) uint16_t remaining_packets = (epin[n].dieptsiz & DIEPTSIZ_PKTCNT_Msk) >> DIEPTSIZ_PKTCNT_Pos; // Process every single packet (only whole packets can be written to fifo) - for ( uint16_t i = 0; i < remaining_packets; i++ ) - { + for (uint16_t i = 0; i < remaining_packets; i++) { uint16_t const remaining_bytes = (epin[n].dieptsiz & DIEPTSIZ_XFRSIZ_Msk) >> DIEPTSIZ_XFRSIZ_Pos; // Packet can not be larger than ep max size @@ -1190,16 +1064,13 @@ static void handle_epin_irq (uint8_t rhport) // It's only possible to write full packets into FIFO. Therefore DTXFSTS register of current // EP has to be checked if the buffer can take another WHOLE packet - if ( packet_size > ((epin[n].dtxfsts & DTXFSTS_INEPTFSAV_Msk) << 2) ) break; + if (packet_size > ((epin[n].dtxfsts & DTXFSTS_INEPTFSAV_Msk) << 2)) break; // Push packet to Tx-FIFO - if ( xfer->ff ) - { - volatile uint32_t *tx_fifo = dwc2->fifo[n]; + if (xfer->ff) { + volatile uint32_t* tx_fifo = dwc2->fifo[n]; tu_fifo_read_n_const_addr_full_words(xfer->ff, (void*) (uintptr_t) tx_fifo, packet_size); - } - else - { + } else { write_fifo_packet(rhport, n, xfer->buffer, packet_size); // Increment pointer to xfer data @@ -1208,8 +1079,7 @@ static void handle_epin_irq (uint8_t rhport) } // Turn off TXFE if all bytes are written. - if ( ((epin[n].dieptsiz & DIEPTSIZ_XFRSIZ_Msk) >> DIEPTSIZ_XFRSIZ_Pos) == 0 ) - { + if (((epin[n].dieptsiz & DIEPTSIZ_XFRSIZ_Msk) >> DIEPTSIZ_XFRSIZ_Pos) == 0) { dwc2->diepempmsk &= ~(1 << n); } } @@ -1217,55 +1087,50 @@ static void handle_epin_irq (uint8_t rhport) } } -void dcd_int_handler(uint8_t rhport) -{ - dwc2_regs_t *dwc2 = DWC2_REG(rhport); +void dcd_int_handler(uint8_t rhport) { + dwc2_regs_t* dwc2 = DWC2_REG(rhport); uint32_t const int_mask = dwc2->gintmsk; uint32_t const int_status = dwc2->gintsts & int_mask; - if(int_status & GINTSTS_USBRST) - { + if (int_status & GINTSTS_USBRST) { // USBRST is start of reset. dwc2->gintsts = GINTSTS_USBRST; bus_reset(rhport); } - if(int_status & GINTSTS_ENUMDNE) - { + if (int_status & GINTSTS_ENUMDNE) { // ENUMDNE is the end of reset where speed of the link is detected - dwc2->gintsts = GINTSTS_ENUMDNE; tusb_speed_t speed; - switch ((dwc2->dsts & DSTS_ENUMSPD_Msk) >> DSTS_ENUMSPD_Pos) - { + switch ((dwc2->dsts & DSTS_ENUMSPD_Msk) >> DSTS_ENUMSPD_Pos) { case DSTS_ENUMSPD_HS: speed = TUSB_SPEED_HIGH; - break; + break; case DSTS_ENUMSPD_LS: speed = TUSB_SPEED_LOW; - break; + break; case DSTS_ENUMSPD_FS_HSPHY: case DSTS_ENUMSPD_FS: default: speed = TUSB_SPEED_FULL; - break; + break; } + // TODO must update GUSBCFG_TRDT according to link speed + dcd_event_bus_reset(rhport, speed, true); } - if(int_status & GINTSTS_USBSUSP) - { + if (int_status & GINTSTS_USBSUSP) { dwc2->gintsts = GINTSTS_USBSUSP; dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); } - if(int_status & GINTSTS_WKUINT) - { + if (int_status & GINTSTS_WKUINT) { dwc2->gintsts = GINTSTS_WKUINT; dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); } @@ -1273,73 +1138,52 @@ void dcd_int_handler(uint8_t rhport) // TODO check GINTSTS_DISCINT for disconnect detection // if(int_status & GINTSTS_DISCINT) - if(int_status & GINTSTS_OTGINT) - { + if (int_status & GINTSTS_OTGINT) { // OTG INT bit is read-only uint32_t const otg_int = dwc2->gotgint; - if (otg_int & GOTGINT_SEDET) - { + if (otg_int & GOTGINT_SEDET) { dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); } dwc2->gotgint = otg_int; } - if(int_status & GINTSTS_SOF) - { - dwc2->gotgint = GINTSTS_SOF; + if(int_status & GINTSTS_SOF) { + dwc2->gintsts = GINTSTS_SOF; + const uint32_t frame = (dwc2->dsts & DSTS_FNSOF) >> DSTS_FNSOF_Pos; - if (_sof_en) - { - uint32_t frame = (dwc2->dsts & (DSTS_FNSOF)) >> 8; - dcd_event_sof(rhport, frame, true); - } - else - { - // Disable SOF interrupt if SOF was not explicitly enabled. SOF was used for remote wakeup detection + // Disable SOF interrupt if SOF was not explicitly enabled since SOF was used for remote wakeup detection + if (!_sof_en) { dwc2->gintmsk &= ~GINTMSK_SOFM; } - dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); + dcd_event_sof(rhport, frame, true); } // RxFIFO non-empty interrupt handling. - if(int_status & GINTSTS_RXFLVL) - { + if (int_status & GINTSTS_RXFLVL) { // RXFLVL bit is read-only // Mask out RXFLVL while reading data from FIFO dwc2->gintmsk &= ~GINTMSK_RXFLVLM; // Loop until all available packets were handled - do - { + do { handle_rxflvl_irq(rhport); - } while(dwc2->gotgint & GINTSTS_RXFLVL); - - // Manage RX FIFO size - if (_out_ep_closed) - { - update_grxfsiz(rhport); - - // Disable flag - _out_ep_closed = false; - } + } while(dwc2->gintsts & GINTSTS_RXFLVL); dwc2->gintmsk |= GINTMSK_RXFLVLM; } // OUT endpoint interrupt handling. - if(int_status & GINTSTS_OEPINT) - { + if (int_status & GINTSTS_OEPINT) { // OEPINT is read-only, clear using DOEPINTn handle_epout_irq(rhport); } // IN endpoint interrupt handling. - if(int_status & GINTSTS_IEPINT) - { + if (int_status & GINTSTS_IEPINT) { // IEPINT bit read-only, clear using DIEPINTn handle_epin_irq(rhport); } diff --git a/src/portable/synopsys/dwc2/dwc2_info.md b/src/portable/synopsys/dwc2/dwc2_info.md new file mode 100644 index 000000000..8690a0755 --- /dev/null +++ b/src/portable/synopsys/dwc2/dwc2_info.md @@ -0,0 +1,55 @@ +| | BCM2711 (Pi4) | EFM32GG FullSpeed | ESP32-S2 | STM32F407 Fullspeed | STM32F407 Highspeed | STM32F411 Fullspeed | STM32F412 Fullspeed | STM32F429 Fullspeed | STM32F429 Highspeed | STM32F723 Fullspeed | STM32F723 HighSpeed | STM32F767 Fullspeed | STM32H743 Highspeed | STM32L476 Fullspeed | STM32U5A5 Highspeed | GD32VF103 Fullspeed | XMC4500 | +|:----------------------------|:----------------|:--------------------|:-----------|:----------------------|:----------------------|:----------------------|:----------------------|:----------------------|:----------------------|:----------------------|:----------------------|:----------------------|:----------------------|:----------------------|:----------------------|:----------------------|:-----------| +| guid | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00001200 | 0x00002000 | 0x00001200 | 0x00001100 | 0x00003000 | 0x00003100 | 0x00002000 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00001000 | 0x00AEC000 | +| gsnpsid | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54281A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54281A | 0x4F54281A | 0x4F54330A | 0x4F54330A | 0x4F54320A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x00000000 | 0x4F54292A | +| - specs version | 2.80a | 3.30a | 4.00a | 2.81a | 2.81a | 2.81a | 3.20a | 2.81a | 2.81a | 3.30a | 3.30a | 3.20a | 3.30a | 3.10a | 4.11a | 0.00W | 2.92a | +| ghwcfg1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | +| ghwcfg2 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x229DCD20 | 0x229ED590 | 0x229DCD20 | 0x229ED520 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229FE1D0 | 0x229ED520 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x00000000 | 0x228F5930 | +| - op_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | +| - arch | 2 | 2 | 2 | 0 | 2 | 0 | 0 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | +| - point2point | 0 | 0 | 1 | 1 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | +| - hs_phy_type | 1 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | 2 | 0 | 3 | 0 | 2 | 0 | 1 | 0 | 0 | +| - fs_phy_type | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - num_dev_ep | 7 | 6 | 6 | 3 | 5 | 3 | 5 | 3 | 5 | 5 | 8 | 5 | 8 | 5 | 8 | 0 | 6 | +| - num_host_ch | 7 | 13 | 7 | 7 | 11 | 7 | 11 | 7 | 11 | 11 | 15 | 11 | 15 | 11 | 15 | 0 | 13 | +| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - mul_cpu_int | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - reserved21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - nperiod_tx_q_depth | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | +| - host_period_tx_q_depth | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | +| - dev_token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 8 | +| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| ghwcfg3 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x020001E8 | 0x03F403E8 | 0x020001E8 | 0x0200D1E8 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x03EED2E8 | 0x0200D1E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x00000000 | 0x027A01E5 | +| - xfer_size_width | 8 | 8 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 5 | +| - packet_size_width | 6 | 6 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | 6 | +| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - i2c_enable | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | +| - vendor_ctrl_itf | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | +| - optional_feature_removed | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - synch_reset | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - otg_adp_support | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - battery_charger_support | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | +| - total_fifo_size | 4080 | 498 | 200 | 512 | 1012 | 512 | 512 | 512 | 1012 | 512 | 1006 | 512 | 952 | 512 | 952 | 0 | 634 | +| ghwcfg4 | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0x0FF08030 | 0x17F00030 | 0x0FF08030 | 0x17F08030 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x23F00030 | 0x17F08030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0x00000000 | 0xDBF08030 | +| - num_dev_period_in_ep | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - power_optimized | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - ahb_freq_min | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - reserved7 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 4 | 0 | 0 | +| - service_interval_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - ipg_isoc_en | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - acg_enable | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - reserved13 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - utmi_phy_data_width | 0 | 2 | 2 | 2 | 0 | 2 | 2 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | 0 | 2 | +| - dev_ctrl_ep_num | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - iddg_filter_enabled | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - vbus_valid_filter_enabled | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - a_valid_filter_enabled | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - b_valid_filter_enabled | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - dedicated_fifos | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - num_dev_in_eps | 15 | 13 | 9 | 7 | 11 | 7 | 11 | 7 | 11 | 11 | 1 | 11 | 1 | 11 | 1 | 0 | 13 | +| - dma_desc_enable | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | +| - dma_dynamic | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | diff --git a/src/portable/synopsys/dwc2/dwc2_info.py b/src/portable/synopsys/dwc2/dwc2_info.py new file mode 100644 index 000000000..55bec3d23 --- /dev/null +++ b/src/portable/synopsys/dwc2/dwc2_info.py @@ -0,0 +1,169 @@ +import click +import ctypes +import pandas as pd + +# hex value for register: guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4 +dwc2_reg_list = ['guid', 'gsnpsid', 'ghwcfg1', 'ghwcfg2', 'ghwcfg3', 'ghwcfg4'] +dwc2_reg_value = { + 'BCM2711 (Pi4)': [0x2708A000, 0x4F54280A, 0, 0x228DDD50, 0xFF000E8, 0x1FF00020], + 'EFM32GG FullSpeed': [0, 0x4F54330A, 0, 0x228F5910, 0x1F204E8, 0x1BF08030], + 'ESP32-S2': [0, 0x4F54400A, 0, 0x224DD930, 0xC804B5, 0xD3F0A030], + 'STM32F407 Fullspeed': [0x1200, 0x4F54281A, 0, 0x229DCD20, 0x20001E8, 0xFF08030], + 'STM32F407 Highspeed': [0x1100, 0x4F54281A, 0, 0x229ED590, 0x3F403E8, 0x17F00030], + 'STM32F411 Fullspeed': [0x1200, 0x4F54281A, 0, 0x229DCD20, 0x20001E8, 0xFF08030], + 'STM32F412 Fullspeed': [0x2000, 0x4F54320A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], + 'STM32F429 Fullspeed': [0x1200, 0x4F54281A, 0, 0x229DCD20, 0x20001E8, 0xFF08030], + 'STM32F429 Highspeed': [0x1100, 0x4F54281A, 0, 0x229ED590, 0x3F403E8, 0x17F00030], + 'STM32F723 Fullspeed': [0x3000, 0x4F54330A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], + 'STM32F723 HighSpeed': [0x3100, 0x4F54330A, 0, 0x229FE1D0, 0x3EED2E8, 0x23F00030], + 'STM32F767 Fullspeed': [0x2000, 0x4F54320A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], + 'STM32H743 Highspeed': [0x2300, 0x4F54330A, 0, 0x229FE190, 0x3B8D2E8, 0xE3F00030], # both HS cores + 'STM32L476 Fullspeed': [0x2000, 0x4F54310A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], + 'STM32U5A5 Highspeed': [0x00005000, 0x4F54411A, 0x00000000, 0x228FE052, 0x03B882E8, 0xE2103E30], + 'GD32VF103 Fullspeed': [0x1000, 0, 0, 0, 0, 0], + 'XMC4500': [0xAEC000, 0x4F54292A, 0, 0x228F5930, 0x27A01E5, 0xDBF08030] +} + +# Combine dwc2_info with dwc2_reg_list +# dwc2_info = { +# 'BCM2711 (Pi4)': { +# 'guid': 0x2708A000, +# 'gsnpsid': 0x4F54280A, +# 'ghwcfg1': 0, +# 'ghwcfg2': 0x228DDD50, +# 'ghwcfg3': 0xFF000E8, +# 'ghwcfg4': 0x1FF00020 +# }, +dwc2_info = {key: {field: value for field, value in zip(dwc2_reg_list, values)} for key, values in dwc2_reg_value.items()} + + +class GHWCFG2(ctypes.LittleEndianStructure): + _fields_ = [ + ("op_mode", ctypes.c_uint32, 3), + ("arch", ctypes.c_uint32, 2), + ("point2point", ctypes.c_uint32, 1), + ("hs_phy_type", ctypes.c_uint32, 2), + ("fs_phy_type", ctypes.c_uint32, 2), + ("num_dev_ep", ctypes.c_uint32, 4), + ("num_host_ch", ctypes.c_uint32, 4), + ("period_channel_support", ctypes.c_uint32, 1), + ("enable_dynamic_fifo", ctypes.c_uint32, 1), + ("mul_cpu_int", ctypes.c_uint32, 1), + ("reserved21", ctypes.c_uint32, 1), + ("nperiod_tx_q_depth", ctypes.c_uint32, 2), + ("host_period_tx_q_depth", ctypes.c_uint32, 2), + ("dev_token_q_depth", ctypes.c_uint32, 5), + ("otg_enable_ic_usb", ctypes.c_uint32, 1) + ] + + +class GHWCFG3(ctypes.LittleEndianStructure): + _fields_ = [ + ("xfer_size_width", ctypes.c_uint32, 4), + ("packet_size_width", ctypes.c_uint32, 3), + ("otg_enable", ctypes.c_uint32, 1), + ("i2c_enable", ctypes.c_uint32, 1), + ("vendor_ctrl_itf", ctypes.c_uint32, 1), + ("optional_feature_removed", ctypes.c_uint32, 1), + ("synch_reset", ctypes.c_uint32, 1), + ("otg_adp_support", ctypes.c_uint32, 1), + ("otg_enable_hsic", ctypes.c_uint32, 1), + ("battery_charger_support", ctypes.c_uint32, 1), + ("lpm_mode", ctypes.c_uint32, 1), + ("total_fifo_size", ctypes.c_uint32, 16) + ] + + +class GHWCFG4(ctypes.LittleEndianStructure): + _fields_ = [ + ("num_dev_period_in_ep", ctypes.c_uint32, 4), + ("power_optimized", ctypes.c_uint32, 1), + ("ahb_freq_min", ctypes.c_uint32, 1), + ("hibernation", ctypes.c_uint32, 1), + ("reserved7", ctypes.c_uint32, 3), + ("service_interval_mode", ctypes.c_uint32, 1), + ("ipg_isoc_en", ctypes.c_uint32, 1), + ("acg_enable", ctypes.c_uint32, 1), + ("reserved13", ctypes.c_uint32, 1), + ("utmi_phy_data_width", ctypes.c_uint32, 2), + ("dev_ctrl_ep_num", ctypes.c_uint32, 4), + ("iddg_filter_enabled", ctypes.c_uint32, 1), + ("vbus_valid_filter_enabled", ctypes.c_uint32, 1), + ("a_valid_filter_enabled", ctypes.c_uint32, 1), + ("b_valid_filter_enabled", ctypes.c_uint32, 1), + ("dedicated_fifos", ctypes.c_uint32, 1), + ("num_dev_in_eps", ctypes.c_uint32, 4), + ("dma_desc_enable", ctypes.c_uint32, 1), + ("dma_dynamic", ctypes.c_uint32, 1) + ] + + +@click.group() +def cli(): + pass + + +@cli.command() +@click.argument('mcus', nargs=-1) +@click.option('-a', '--all', is_flag=True, help='Print all bit-field values') +def info(mcus, all): + """Print DWC2 register values for given MCU(s)""" + if len(mcus) == 0: + mcus = dwc2_info + + for mcu in mcus: + for entry in dwc2_info: + if mcu.lower() in entry.lower(): + print(f"## {entry}") + for r_name, r_value in dwc2_info[entry].items(): + print(f"{r_name} = 0x{r_value:08X}") + # Print bit-field values + if all and r_name.upper() in globals(): + class_name = globals()[r_name.upper()] + ghwcfg = class_name.from_buffer_copy(r_value.to_bytes(4, byteorder='little')) + for field_name, field_type, _ in class_name._fields_: + print(f" {field_name} = {getattr(ghwcfg, field_name)}") + + +@cli.command() +def render_md(): + """Render dwc2_info to Markdown table""" + # Create an empty list to hold the dictionaries + dwc2_info_list = [] + + # Iterate over the dwc2_info dictionary and extract fields + for device, reg_values in dwc2_info.items(): + entry_dict = {"Device": device} + for r_name, r_value in reg_values.items(): + entry_dict[r_name] = f"0x{r_value:08X}" + + if r_name == 'gsnpsid': + # Get dwc2 specs version + major = ((r_value >> 8) >> 4) & 0x0F + minor = (r_value >> 4) & 0xFF + patch = chr((r_value & 0x0F) + ord('a') - 0xA) + entry_dict[f' - specs version'] = f"{major:X}.{minor:02X}{patch}" + elif r_name.upper() in globals(): + # Get bit-field values which exist as ctypes structures + class_name = globals()[r_name.upper()] + ghwcfg = class_name.from_buffer_copy(r_value.to_bytes(4, byteorder='little')) + for field_name, field_type, _ in class_name._fields_: + entry_dict[f' - {field_name}'] = getattr(ghwcfg, field_name) + + dwc2_info_list.append(entry_dict) + + # Create a Pandas DataFrame from the list of dictionaries + df = pd.DataFrame(dwc2_info_list).set_index('Device') + + # Transpose the DataFrame to switch rows and columns + df = df.T + #print(df) + + # Write the Markdown table to a file + with open('dwc2_info.md', 'w') as md_file: + md_file.write(df.to_markdown()) + md_file.write('\n') + + +if __name__ == '__main__': + cli() diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index cb455bd90..3237a50f6 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -24,11 +24,11 @@ * This file is part of the TinyUSB stack. */ -#ifndef _DWC2_STM32_H_ -#define _DWC2_STM32_H_ +#ifndef DWC2_STM32_H_ +#define DWC2_STM32_H_ #ifdef __cplusplus - extern "C" { +extern "C" { #endif // EP_MAX : Max number of bi-directional endpoints including EP0 @@ -84,10 +84,16 @@ #elif CFG_TUSB_MCU == OPT_MCU_STM32U5 #include "stm32u5xx.h" - #define USB_OTG_FS_PERIPH_BASE USB_OTG_FS_BASE - #define EP_MAX_FS 6 - #define EP_FIFO_SIZE_FS 1280 - + // U59x/5Ax/5Fx/5Gx are highspeed with built-in HS PHY + #ifdef USB_OTG_FS + #define USB_OTG_FS_PERIPH_BASE USB_OTG_FS_BASE + #define EP_MAX_FS 6 + #define EP_FIFO_SIZE_FS 1280 + #else + #define USB_OTG_HS_PERIPH_BASE USB_OTG_HS_BASE + #define EP_MAX_HS 9 + #define EP_FIFO_SIZE_HS 4096 + #endif #else #error "Unsupported MCUs" #endif @@ -101,15 +107,14 @@ // On STM32 for consistency we associate // - Port0 to OTG_FS, and Port1 to OTG_HS -static const dwc2_controller_t _dwc2_controller[] = -{ -#ifdef USB_OTG_FS_PERIPH_BASE - { .reg_base = USB_OTG_FS_PERIPH_BASE, .irqnum = OTG_FS_IRQn, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS }, -#endif +static const dwc2_controller_t _dwc2_controller[] = { + #ifdef USB_OTG_FS_PERIPH_BASE + { .reg_base = USB_OTG_FS_PERIPH_BASE, .irqnum = OTG_FS_IRQn, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS }, + #endif -#ifdef USB_OTG_HS_PERIPH_BASE - { .reg_base = USB_OTG_HS_PERIPH_BASE, .irqnum = OTG_HS_IRQn, .ep_count = EP_MAX_HS, .ep_fifo_size = EP_FIFO_SIZE_HS }, -#endif + #ifdef USB_OTG_HS_PERIPH_BASE + { .reg_base = USB_OTG_HS_PERIPH_BASE, .irqnum = OTG_HS_IRQn, .ep_count = EP_MAX_HS, .ep_fifo_size = EP_FIFO_SIZE_HS }, + #endif }; //--------------------------------------------------------------------+ @@ -119,42 +124,59 @@ static const dwc2_controller_t _dwc2_controller[] = // SystemCoreClock is already included by family header // extern uint32_t SystemCoreClock; -TU_ATTR_ALWAYS_INLINE -static inline void dwc2_dcd_int_enable(uint8_t rhport) -{ - NVIC_EnableIRQ((IRQn_Type)_dwc2_controller[rhport].irqnum); +TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_enable(uint8_t rhport) { + NVIC_EnableIRQ((IRQn_Type) _dwc2_controller[rhport].irqnum); } -TU_ATTR_ALWAYS_INLINE -static inline void dwc2_dcd_int_disable (uint8_t rhport) -{ - NVIC_DisableIRQ((IRQn_Type)_dwc2_controller[rhport].irqnum); +TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_disable(uint8_t rhport) { + NVIC_DisableIRQ((IRQn_Type) _dwc2_controller[rhport].irqnum); } -TU_ATTR_ALWAYS_INLINE -static inline void dwc2_remote_wakeup_delay(void) -{ +TU_ATTR_ALWAYS_INLINE static inline void dwc2_remote_wakeup_delay(void) { // try to delay for 1 ms uint32_t count = SystemCoreClock / 1000; - while ( count-- ) __NOP(); + while (count--) __NOP(); } // MCU specific PHY init, called BEFORE core reset -static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type) -{ - if ( hs_phy_type == HS_PHY_TYPE_NONE ) - { +// - dwc2 3.30a (H5) use USB_HS_PHYC +// - dwc2 4.11a (U5) use femtoPHY +static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { + if (hs_phy_type == HS_PHY_TYPE_NONE) { // Enable on-chip FS PHY dwc2->stm32_gccfg |= STM32_GCCFG_PWRDWN; - }else - { - // Disable FS PHY + + // https://community.st.com/t5/stm32cubemx-mcus/why-stm32h743-usb-fs-doesn-t-work-if-freertos-tickless-idle/m-p/349480#M18867 + // H7 running on full-speed phy need to disable ULPI clock in sleep mode. + // Otherwise, USB won't work when mcu executing WFI/WFE instruction i.e tick-less RTOS. + // Note: there may be other family that is affected by this, but only H7 and F7 is tested so far + #if defined(USB_OTG_FS_PERIPH_BASE) && defined(RCC_AHB1LPENR_USB2OTGFSULPILPEN) + if ( USB_OTG_FS_PERIPH_BASE == (uint32_t) dwc2 ) { + RCC->AHB1LPENR &= ~RCC_AHB1LPENR_USB2OTGFSULPILPEN; + } + #endif + + #if defined(USB_OTG_HS_PERIPH_BASE) && defined(RCC_AHB1LPENR_USB1OTGHSULPILPEN) + if ( USB_OTG_HS_PERIPH_BASE == (uint32_t) dwc2 ) { + RCC->AHB1LPENR &= ~RCC_AHB1LPENR_USB1OTGHSULPILPEN; + } + #endif + + #if defined(USB_OTG_HS_PERIPH_BASE) && defined(RCC_AHB1LPENR_OTGHSULPILPEN) + if ( USB_OTG_HS_PERIPH_BASE == (uint32_t) dwc2 ) { + RCC->AHB1LPENR &= ~RCC_AHB1LPENR_OTGHSULPILPEN; + } + #endif + + } else { +#if CFG_TUSB_MCU != OPT_MCU_STM32U5 + // Disable FS PHY, TODO on U5A5 (dwc2 4.11a) 16th bit is 'Host CDP behavior enable' dwc2->stm32_gccfg &= ~STM32_GCCFG_PWRDWN; +#endif // Enable on-chip HS PHY - if (hs_phy_type == HS_PHY_TYPE_UTMI || hs_phy_type == HS_PHY_TYPE_UTMI_ULPI) - { -#ifdef USB_HS_PHYC + if (hs_phy_type == HS_PHY_TYPE_UTMI || hs_phy_type == HS_PHY_TYPE_UTMI_ULPI) { + #ifdef USB_HS_PHYC // Enable UTMI HS PHY dwc2->stm32_gccfg |= STM32_GCCFG_PHYHSEN; @@ -186,40 +208,47 @@ static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type) // Enable PLL internal PHY USB_HS_PHYC->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL_PLLEN; -#endif + #else + + #endif } } } // MCU specific PHY update, it is called AFTER init() and core reset -static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type) -{ +static inline void dwc2_phy_update(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { // used to set turnaround time for fullspeed, nothing to do in highspeed mode - if ( hs_phy_type == HS_PHY_TYPE_NONE ) - { + if (hs_phy_type == HS_PHY_TYPE_NONE) { // Turnaround timeout depends on the AHB clock dictated by STM32 Reference Manual uint32_t turnaround; - if ( SystemCoreClock >= 32000000u ) + if (SystemCoreClock >= 32000000u) { turnaround = 0x6u; - else if ( SystemCoreClock >= 27500000u ) + } else if (SystemCoreClock >= 27500000u) { turnaround = 0x7u; - else if ( SystemCoreClock >= 24000000u ) + } else if (SystemCoreClock >= 24000000u) { turnaround = 0x8u; - else if ( SystemCoreClock >= 21800000u ) + } else if (SystemCoreClock >= 21800000u) { turnaround = 0x9u; - else if ( SystemCoreClock >= 20000000u ) + } + else if (SystemCoreClock >= 20000000u) { turnaround = 0xAu; - else if ( SystemCoreClock >= 18500000u ) + } + else if (SystemCoreClock >= 18500000u) { turnaround = 0xBu; - else if ( SystemCoreClock >= 17200000u ) + } + else if (SystemCoreClock >= 17200000u) { turnaround = 0xCu; - else if ( SystemCoreClock >= 16000000u ) + } + else if (SystemCoreClock >= 16000000u) { turnaround = 0xDu; - else if ( SystemCoreClock >= 15000000u ) + } + else if (SystemCoreClock >= 15000000u) { turnaround = 0xEu; - else + } + else { turnaround = 0xFu; + } dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_TRDT_Msk) | (turnaround << GUSBCFG_TRDT_Pos); } @@ -229,4 +258,4 @@ static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type) } #endif -#endif /* _DWC2_STM32_H_ */ +#endif diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h index 3fc979337..c15771237 100644 --- a/src/portable/synopsys/dwc2/dwc2_type.h +++ b/src/portable/synopsys/dwc2/dwc2_type.h @@ -32,7 +32,7 @@ typedef struct uint32_t ep_fifo_size; }dwc2_controller_t; -/* DWC OTG HW Release versions */ +// DWC OTG HW Release versions #define DWC2_CORE_REV_2_71a 0x4f54271a #define DWC2_CORE_REV_2_72a 0x4f54272a #define DWC2_CORE_REV_2_80a 0x4f54280a @@ -43,12 +43,13 @@ typedef struct #define DWC2_CORE_REV_3_00a 0x4f54300a #define DWC2_CORE_REV_3_10a 0x4f54310a #define DWC2_CORE_REV_4_00a 0x4f54400a +#define DWC2_CORE_REV_4_11a 0x4f54411a #define DWC2_CORE_REV_4_20a 0x4f54420a #define DWC2_FS_IOT_REV_1_00a 0x5531100a #define DWC2_HS_IOT_REV_1_00a 0x5532100a #define DWC2_CORE_REV_MASK 0x0000ffff -/* DWC OTG HW Core ID */ +// DWC OTG HW Core ID #define DWC2_OTG_ID 0x4f540000 #define DWC2_FS_IOT_ID 0x55310000 #define DWC2_HS_IOT_ID 0x55320000 @@ -57,13 +58,13 @@ typedef struct // HS PHY typedef struct { - volatile uint32_t HS_PHYC_PLL; // This register is used to control the PLL of the HS PHY. 000h */ - volatile uint32_t Reserved04; // Reserved 004h */ - volatile uint32_t Reserved08; // Reserved 008h */ - volatile uint32_t HS_PHYC_TUNE; // This register is used to control the tuning interface of the High Speed PHY. 00Ch */ - volatile uint32_t Reserved10; // Reserved 010h */ - volatile uint32_t Reserved14; // Reserved 014h */ - volatile uint32_t HS_PHYC_LDO; // This register is used to control the regulator (LDO). 018h */ + volatile uint32_t HS_PHYC_PLL; // 000h This register is used to control the PLL of the HS PHY. + volatile uint32_t Reserved04; // 004h Reserved + volatile uint32_t Reserved08; // 008h Reserved + volatile uint32_t HS_PHYC_TUNE; // 00Ch This register is used to control the tuning interface of the High Speed PHY. + volatile uint32_t Reserved10; // 010h Reserved + volatile uint32_t Reserved14; // 014h Reserved + volatile uint32_t HS_PHYC_LDO; // 018h This register is used to control the regulator (LDO). } HS_PHYC_GlobalTypeDef; #endif @@ -298,103 +299,103 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); /******************** Bit definition for GOTGCTL register ********************/ #define GOTGCTL_SRQSCS_Pos (0U) -#define GOTGCTL_SRQSCS_Msk (0x1UL << GOTGCTL_SRQSCS_Pos) // 0x00000001 */ -#define GOTGCTL_SRQSCS GOTGCTL_SRQSCS_Msk // Session request success */ +#define GOTGCTL_SRQSCS_Msk (0x1UL << GOTGCTL_SRQSCS_Pos) // 0x00000001 +#define GOTGCTL_SRQSCS GOTGCTL_SRQSCS_Msk // Session request success #define GOTGCTL_SRQ_Pos (1U) -#define GOTGCTL_SRQ_Msk (0x1UL << GOTGCTL_SRQ_Pos) // 0x00000002 */ -#define GOTGCTL_SRQ GOTGCTL_SRQ_Msk // Session request */ +#define GOTGCTL_SRQ_Msk (0x1UL << GOTGCTL_SRQ_Pos) // 0x00000002 +#define GOTGCTL_SRQ GOTGCTL_SRQ_Msk // Session request #define GOTGCTL_VBVALOEN_Pos (2U) -#define GOTGCTL_VBVALOEN_Msk (0x1UL << GOTGCTL_VBVALOEN_Pos) // 0x00000004 */ -#define GOTGCTL_VBVALOEN GOTGCTL_VBVALOEN_Msk // VBUS valid override enable */ +#define GOTGCTL_VBVALOEN_Msk (0x1UL << GOTGCTL_VBVALOEN_Pos) // 0x00000004 +#define GOTGCTL_VBVALOEN GOTGCTL_VBVALOEN_Msk // VBUS valid override enable #define GOTGCTL_VBVALOVAL_Pos (3U) -#define GOTGCTL_VBVALOVAL_Msk (0x1UL << GOTGCTL_VBVALOVAL_Pos) // 0x00000008 */ -#define GOTGCTL_VBVALOVAL GOTGCTL_VBVALOVAL_Msk // VBUS valid override value */ +#define GOTGCTL_VBVALOVAL_Msk (0x1UL << GOTGCTL_VBVALOVAL_Pos) // 0x00000008 +#define GOTGCTL_VBVALOVAL GOTGCTL_VBVALOVAL_Msk // VBUS valid override value #define GOTGCTL_AVALOEN_Pos (4U) -#define GOTGCTL_AVALOEN_Msk (0x1UL << GOTGCTL_AVALOEN_Pos) // 0x00000010 */ -#define GOTGCTL_AVALOEN GOTGCTL_AVALOEN_Msk // A-peripheral session valid override enable */ +#define GOTGCTL_AVALOEN_Msk (0x1UL << GOTGCTL_AVALOEN_Pos) // 0x00000010 +#define GOTGCTL_AVALOEN GOTGCTL_AVALOEN_Msk // A-peripheral session valid override enable #define GOTGCTL_AVALOVAL_Pos (5U) -#define GOTGCTL_AVALOVAL_Msk (0x1UL << GOTGCTL_AVALOVAL_Pos) // 0x00000020 */ -#define GOTGCTL_AVALOVAL GOTGCTL_AVALOVAL_Msk // A-peripheral session valid override value */ +#define GOTGCTL_AVALOVAL_Msk (0x1UL << GOTGCTL_AVALOVAL_Pos) // 0x00000020 +#define GOTGCTL_AVALOVAL GOTGCTL_AVALOVAL_Msk // A-peripheral session valid override value #define GOTGCTL_BVALOEN_Pos (6U) -#define GOTGCTL_BVALOEN_Msk (0x1UL << GOTGCTL_BVALOEN_Pos) // 0x00000040 */ -#define GOTGCTL_BVALOEN GOTGCTL_BVALOEN_Msk // B-peripheral session valid override enable */ +#define GOTGCTL_BVALOEN_Msk (0x1UL << GOTGCTL_BVALOEN_Pos) // 0x00000040 +#define GOTGCTL_BVALOEN GOTGCTL_BVALOEN_Msk // B-peripheral session valid override enable #define GOTGCTL_BVALOVAL_Pos (7U) -#define GOTGCTL_BVALOVAL_Msk (0x1UL << GOTGCTL_BVALOVAL_Pos) // 0x00000080 */ -#define GOTGCTL_BVALOVAL GOTGCTL_BVALOVAL_Msk // B-peripheral session valid override value */ +#define GOTGCTL_BVALOVAL_Msk (0x1UL << GOTGCTL_BVALOVAL_Pos) // 0x00000080 +#define GOTGCTL_BVALOVAL GOTGCTL_BVALOVAL_Msk // B-peripheral session valid override value #define GOTGCTL_HNGSCS_Pos (8U) -#define GOTGCTL_HNGSCS_Msk (0x1UL << GOTGCTL_HNGSCS_Pos) // 0x00000100 */ -#define GOTGCTL_HNGSCS GOTGCTL_HNGSCS_Msk // Host set HNP enable */ +#define GOTGCTL_HNGSCS_Msk (0x1UL << GOTGCTL_HNGSCS_Pos) // 0x00000100 +#define GOTGCTL_HNGSCS GOTGCTL_HNGSCS_Msk // Host set HNP enable #define GOTGCTL_HNPRQ_Pos (9U) -#define GOTGCTL_HNPRQ_Msk (0x1UL << GOTGCTL_HNPRQ_Pos) // 0x00000200 */ -#define GOTGCTL_HNPRQ GOTGCTL_HNPRQ_Msk // HNP request */ +#define GOTGCTL_HNPRQ_Msk (0x1UL << GOTGCTL_HNPRQ_Pos) // 0x00000200 +#define GOTGCTL_HNPRQ GOTGCTL_HNPRQ_Msk // HNP request #define GOTGCTL_HSHNPEN_Pos (10U) -#define GOTGCTL_HSHNPEN_Msk (0x1UL << GOTGCTL_HSHNPEN_Pos) // 0x00000400 */ -#define GOTGCTL_HSHNPEN GOTGCTL_HSHNPEN_Msk // Host set HNP enable */ +#define GOTGCTL_HSHNPEN_Msk (0x1UL << GOTGCTL_HSHNPEN_Pos) // 0x00000400 +#define GOTGCTL_HSHNPEN GOTGCTL_HSHNPEN_Msk // Host set HNP enable #define GOTGCTL_DHNPEN_Pos (11U) -#define GOTGCTL_DHNPEN_Msk (0x1UL << GOTGCTL_DHNPEN_Pos) // 0x00000800 */ -#define GOTGCTL_DHNPEN GOTGCTL_DHNPEN_Msk // Device HNP enabled */ +#define GOTGCTL_DHNPEN_Msk (0x1UL << GOTGCTL_DHNPEN_Pos) // 0x00000800 +#define GOTGCTL_DHNPEN GOTGCTL_DHNPEN_Msk // Device HNP enabled #define GOTGCTL_EHEN_Pos (12U) -#define GOTGCTL_EHEN_Msk (0x1UL << GOTGCTL_EHEN_Pos) // 0x00001000 */ -#define GOTGCTL_EHEN GOTGCTL_EHEN_Msk // Embedded host enable */ +#define GOTGCTL_EHEN_Msk (0x1UL << GOTGCTL_EHEN_Pos) // 0x00001000 +#define GOTGCTL_EHEN GOTGCTL_EHEN_Msk // Embedded host enable #define GOTGCTL_CIDSTS_Pos (16U) -#define GOTGCTL_CIDSTS_Msk (0x1UL << GOTGCTL_CIDSTS_Pos) // 0x00010000 */ -#define GOTGCTL_CIDSTS GOTGCTL_CIDSTS_Msk // Connector ID status */ +#define GOTGCTL_CIDSTS_Msk (0x1UL << GOTGCTL_CIDSTS_Pos) // 0x00010000 +#define GOTGCTL_CIDSTS GOTGCTL_CIDSTS_Msk // Connector ID status #define GOTGCTL_DBCT_Pos (17U) -#define GOTGCTL_DBCT_Msk (0x1UL << GOTGCTL_DBCT_Pos) // 0x00020000 */ -#define GOTGCTL_DBCT GOTGCTL_DBCT_Msk // Long/short debounce time */ +#define GOTGCTL_DBCT_Msk (0x1UL << GOTGCTL_DBCT_Pos) // 0x00020000 +#define GOTGCTL_DBCT GOTGCTL_DBCT_Msk // Long/short debounce time #define GOTGCTL_ASVLD_Pos (18U) -#define GOTGCTL_ASVLD_Msk (0x1UL << GOTGCTL_ASVLD_Pos) // 0x00040000 */ -#define GOTGCTL_ASVLD GOTGCTL_ASVLD_Msk // A-session valid */ +#define GOTGCTL_ASVLD_Msk (0x1UL << GOTGCTL_ASVLD_Pos) // 0x00040000 +#define GOTGCTL_ASVLD GOTGCTL_ASVLD_Msk // A-session valid #define GOTGCTL_BSESVLD_Pos (19U) -#define GOTGCTL_BSESVLD_Msk (0x1UL << GOTGCTL_BSESVLD_Pos) // 0x00080000 */ -#define GOTGCTL_BSESVLD GOTGCTL_BSESVLD_Msk // B-session valid */ +#define GOTGCTL_BSESVLD_Msk (0x1UL << GOTGCTL_BSESVLD_Pos) // 0x00080000 +#define GOTGCTL_BSESVLD GOTGCTL_BSESVLD_Msk // B-session valid #define GOTGCTL_OTGVER_Pos (20U) -#define GOTGCTL_OTGVER_Msk (0x1UL << GOTGCTL_OTGVER_Pos) // 0x00100000 */ -#define GOTGCTL_OTGVER GOTGCTL_OTGVER_Msk // OTG version */ +#define GOTGCTL_OTGVER_Msk (0x1UL << GOTGCTL_OTGVER_Pos) // 0x00100000 +#define GOTGCTL_OTGVER GOTGCTL_OTGVER_Msk // OTG version /******************** Bit definition for HCFG register ********************/ #define HCFG_FSLSPCS_Pos (0U) -#define HCFG_FSLSPCS_Msk (0x3UL << HCFG_FSLSPCS_Pos) // 0x00000003 */ -#define HCFG_FSLSPCS HCFG_FSLSPCS_Msk // FS/LS PHY clock select */ -#define HCFG_FSLSPCS_0 (0x1UL << HCFG_FSLSPCS_Pos) // 0x00000001 */ -#define HCFG_FSLSPCS_1 (0x2UL << HCFG_FSLSPCS_Pos) // 0x00000002 */ +#define HCFG_FSLSPCS_Msk (0x3UL << HCFG_FSLSPCS_Pos) // 0x00000003 +#define HCFG_FSLSPCS HCFG_FSLSPCS_Msk // FS/LS PHY clock select +#define HCFG_FSLSPCS_0 (0x1UL << HCFG_FSLSPCS_Pos) // 0x00000001 +#define HCFG_FSLSPCS_1 (0x2UL << HCFG_FSLSPCS_Pos) // 0x00000002 #define HCFG_FSLSS_Pos (2U) -#define HCFG_FSLSS_Msk (0x1UL << HCFG_FSLSS_Pos) // 0x00000004 */ -#define HCFG_FSLSS HCFG_FSLSS_Msk // FS- and LS-only support */ +#define HCFG_FSLSS_Msk (0x1UL << HCFG_FSLSS_Pos) // 0x00000004 +#define HCFG_FSLSS HCFG_FSLSS_Msk // FS- and LS-only support /******************** Bit definition for PCGCR register ********************/ #define PCGCR_STPPCLK_Pos (0U) -#define PCGCR_STPPCLK_Msk (0x1UL << PCGCR_STPPCLK_Pos) // 0x00000001 */ -#define PCGCR_STPPCLK PCGCR_STPPCLK_Msk // Stop PHY clock */ +#define PCGCR_STPPCLK_Msk (0x1UL << PCGCR_STPPCLK_Pos) // 0x00000001 +#define PCGCR_STPPCLK PCGCR_STPPCLK_Msk // Stop PHY clock #define PCGCR_GATEHCLK_Pos (1U) -#define PCGCR_GATEHCLK_Msk (0x1UL << PCGCR_GATEHCLK_Pos) // 0x00000002 */ -#define PCGCR_GATEHCLK PCGCR_GATEHCLK_Msk // Gate HCLK */ +#define PCGCR_GATEHCLK_Msk (0x1UL << PCGCR_GATEHCLK_Pos) // 0x00000002 +#define PCGCR_GATEHCLK PCGCR_GATEHCLK_Msk // Gate HCLK #define PCGCR_PHYSUSP_Pos (4U) -#define PCGCR_PHYSUSP_Msk (0x1UL << PCGCR_PHYSUSP_Pos) // 0x00000010 */ -#define PCGCR_PHYSUSP PCGCR_PHYSUSP_Msk // PHY suspended */ +#define PCGCR_PHYSUSP_Msk (0x1UL << PCGCR_PHYSUSP_Pos) // 0x00000010 +#define PCGCR_PHYSUSP PCGCR_PHYSUSP_Msk // PHY suspended /******************** Bit definition for GOTGINT register ********************/ #define GOTGINT_SEDET_Pos (2U) -#define GOTGINT_SEDET_Msk (0x1UL << GOTGINT_SEDET_Pos) // 0x00000004 */ -#define GOTGINT_SEDET GOTGINT_SEDET_Msk // Session end detected */ +#define GOTGINT_SEDET_Msk (0x1UL << GOTGINT_SEDET_Pos) // 0x00000004 +#define GOTGINT_SEDET GOTGINT_SEDET_Msk // Session end detected #define GOTGINT_SRSSCHG_Pos (8U) -#define GOTGINT_SRSSCHG_Msk (0x1UL << GOTGINT_SRSSCHG_Pos) // 0x00000100 */ -#define GOTGINT_SRSSCHG GOTGINT_SRSSCHG_Msk // Session request success status change */ +#define GOTGINT_SRSSCHG_Msk (0x1UL << GOTGINT_SRSSCHG_Pos) // 0x00000100 +#define GOTGINT_SRSSCHG GOTGINT_SRSSCHG_Msk // Session request success status change #define GOTGINT_HNSSCHG_Pos (9U) -#define GOTGINT_HNSSCHG_Msk (0x1UL << GOTGINT_HNSSCHG_Pos) // 0x00000200 */ -#define GOTGINT_HNSSCHG GOTGINT_HNSSCHG_Msk // Host negotiation success status change */ +#define GOTGINT_HNSSCHG_Msk (0x1UL << GOTGINT_HNSSCHG_Pos) // 0x00000200 +#define GOTGINT_HNSSCHG GOTGINT_HNSSCHG_Msk // Host negotiation success status change #define GOTGINT_HNGDET_Pos (17U) -#define GOTGINT_HNGDET_Msk (0x1UL << GOTGINT_HNGDET_Pos) // 0x00020000 */ -#define GOTGINT_HNGDET GOTGINT_HNGDET_Msk // Host negotiation detected */ +#define GOTGINT_HNGDET_Msk (0x1UL << GOTGINT_HNGDET_Pos) // 0x00020000 +#define GOTGINT_HNGDET GOTGINT_HNGDET_Msk // Host negotiation detected #define GOTGINT_ADTOCHG_Pos (18U) -#define GOTGINT_ADTOCHG_Msk (0x1UL << GOTGINT_ADTOCHG_Pos) // 0x00040000 */ -#define GOTGINT_ADTOCHG GOTGINT_ADTOCHG_Msk // A-device timeout change */ +#define GOTGINT_ADTOCHG_Msk (0x1UL << GOTGINT_ADTOCHG_Pos) // 0x00040000 +#define GOTGINT_ADTOCHG GOTGINT_ADTOCHG_Msk // A-device timeout change #define GOTGINT_DBCDNE_Pos (19U) -#define GOTGINT_DBCDNE_Msk (0x1UL << GOTGINT_DBCDNE_Pos) // 0x00080000 */ -#define GOTGINT_DBCDNE GOTGINT_DBCDNE_Msk // Debounce done */ +#define GOTGINT_DBCDNE_Msk (0x1UL << GOTGINT_DBCDNE_Pos) // 0x00080000 +#define GOTGINT_DBCDNE GOTGINT_DBCDNE_Msk // Debounce done #define GOTGINT_IDCHNG_Pos (20U) -#define GOTGINT_IDCHNG_Msk (0x1UL << GOTGINT_IDCHNG_Pos) // 0x00100000 */ -#define GOTGINT_IDCHNG GOTGINT_IDCHNG_Msk // Change in ID pin input value */ +#define GOTGINT_IDCHNG_Msk (0x1UL << GOTGINT_IDCHNG_Pos) // 0x00100000 +#define GOTGINT_IDCHNG GOTGINT_IDCHNG_Msk // Change in ID pin input value /******************** Bit definition for DCFG register ********************/ #define DCFG_DSPD_Pos (0U) @@ -405,92 +406,92 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); #define DCFG_DSPD_FS 3 // Fullspeed on FS PHY #define DCFG_NZLSOHSK_Pos (2U) -#define DCFG_NZLSOHSK_Msk (0x1UL << DCFG_NZLSOHSK_Pos) // 0x00000004 */ -#define DCFG_NZLSOHSK DCFG_NZLSOHSK_Msk // Nonzero-length status OUT handshake */ +#define DCFG_NZLSOHSK_Msk (0x1UL << DCFG_NZLSOHSK_Pos) // 0x00000004 +#define DCFG_NZLSOHSK DCFG_NZLSOHSK_Msk // Nonzero-length status OUT handshake #define DCFG_DAD_Pos (4U) -#define DCFG_DAD_Msk (0x7FUL << DCFG_DAD_Pos) // 0x000007F0 */ -#define DCFG_DAD DCFG_DAD_Msk // Device address */ -#define DCFG_DAD_0 (0x01UL << DCFG_DAD_Pos) // 0x00000010 */ -#define DCFG_DAD_1 (0x02UL << DCFG_DAD_Pos) // 0x00000020 */ -#define DCFG_DAD_2 (0x04UL << DCFG_DAD_Pos) // 0x00000040 */ -#define DCFG_DAD_3 (0x08UL << DCFG_DAD_Pos) // 0x00000080 */ -#define DCFG_DAD_4 (0x10UL << DCFG_DAD_Pos) // 0x00000100 */ -#define DCFG_DAD_5 (0x20UL << DCFG_DAD_Pos) // 0x00000200 */ -#define DCFG_DAD_6 (0x40UL << DCFG_DAD_Pos) // 0x00000400 */ +#define DCFG_DAD_Msk (0x7FUL << DCFG_DAD_Pos) // 0x000007F0 +#define DCFG_DAD DCFG_DAD_Msk // Device address +#define DCFG_DAD_0 (0x01UL << DCFG_DAD_Pos) // 0x00000010 +#define DCFG_DAD_1 (0x02UL << DCFG_DAD_Pos) // 0x00000020 +#define DCFG_DAD_2 (0x04UL << DCFG_DAD_Pos) // 0x00000040 +#define DCFG_DAD_3 (0x08UL << DCFG_DAD_Pos) // 0x00000080 +#define DCFG_DAD_4 (0x10UL << DCFG_DAD_Pos) // 0x00000100 +#define DCFG_DAD_5 (0x20UL << DCFG_DAD_Pos) // 0x00000200 +#define DCFG_DAD_6 (0x40UL << DCFG_DAD_Pos) // 0x00000400 #define DCFG_PFIVL_Pos (11U) -#define DCFG_PFIVL_Msk (0x3UL << DCFG_PFIVL_Pos) // 0x00001800 */ -#define DCFG_PFIVL DCFG_PFIVL_Msk // Periodic (micro)frame interval */ -#define DCFG_PFIVL_0 (0x1UL << DCFG_PFIVL_Pos) // 0x00000800 */ -#define DCFG_PFIVL_1 (0x2UL << DCFG_PFIVL_Pos) // 0x00001000 */ +#define DCFG_PFIVL_Msk (0x3UL << DCFG_PFIVL_Pos) // 0x00001800 +#define DCFG_PFIVL DCFG_PFIVL_Msk // Periodic (micro)frame interval +#define DCFG_PFIVL_0 (0x1UL << DCFG_PFIVL_Pos) // 0x00000800 +#define DCFG_PFIVL_1 (0x2UL << DCFG_PFIVL_Pos) // 0x00001000 #define DCFG_XCVRDLY_Pos (14U) -#define DCFG_XCVRDLY_Msk (0x1UL << DCFG_XCVRDLY_Pos) /*!< 0x00004000 */ +#define DCFG_XCVRDLY_Msk (0x1UL << DCFG_XCVRDLY_Pos) // 0x00004000 #define DCFG_XCVRDLY DCFG_XCVRDLY_Msk // Enables delay between xcvr_sel and txvalid during device chirp #define DCFG_PERSCHIVL_Pos (24U) -#define DCFG_PERSCHIVL_Msk (0x3UL << DCFG_PERSCHIVL_Pos) // 0x03000000 */ -#define DCFG_PERSCHIVL DCFG_PERSCHIVL_Msk // Periodic scheduling interval */ -#define DCFG_PERSCHIVL_0 (0x1UL << DCFG_PERSCHIVL_Pos) // 0x01000000 */ -#define DCFG_PERSCHIVL_1 (0x2UL << DCFG_PERSCHIVL_Pos) // 0x02000000 */ +#define DCFG_PERSCHIVL_Msk (0x3UL << DCFG_PERSCHIVL_Pos) // 0x03000000 +#define DCFG_PERSCHIVL DCFG_PERSCHIVL_Msk // Periodic scheduling interval +#define DCFG_PERSCHIVL_0 (0x1UL << DCFG_PERSCHIVL_Pos) // 0x01000000 +#define DCFG_PERSCHIVL_1 (0x2UL << DCFG_PERSCHIVL_Pos) // 0x02000000 /******************** Bit definition for DCTL register ********************/ #define DCTL_RWUSIG_Pos (0U) -#define DCTL_RWUSIG_Msk (0x1UL << DCTL_RWUSIG_Pos) // 0x00000001 */ -#define DCTL_RWUSIG DCTL_RWUSIG_Msk // Remote wakeup signaling */ +#define DCTL_RWUSIG_Msk (0x1UL << DCTL_RWUSIG_Pos) // 0x00000001 +#define DCTL_RWUSIG DCTL_RWUSIG_Msk // Remote wakeup signaling #define DCTL_SDIS_Pos (1U) -#define DCTL_SDIS_Msk (0x1UL << DCTL_SDIS_Pos) // 0x00000002 */ -#define DCTL_SDIS DCTL_SDIS_Msk // Soft disconnect */ +#define DCTL_SDIS_Msk (0x1UL << DCTL_SDIS_Pos) // 0x00000002 +#define DCTL_SDIS DCTL_SDIS_Msk // Soft disconnect #define DCTL_GINSTS_Pos (2U) -#define DCTL_GINSTS_Msk (0x1UL << DCTL_GINSTS_Pos) // 0x00000004 */ -#define DCTL_GINSTS DCTL_GINSTS_Msk // Global IN NAK status */ +#define DCTL_GINSTS_Msk (0x1UL << DCTL_GINSTS_Pos) // 0x00000004 +#define DCTL_GINSTS DCTL_GINSTS_Msk // Global IN NAK status #define DCTL_GONSTS_Pos (3U) -#define DCTL_GONSTS_Msk (0x1UL << DCTL_GONSTS_Pos) // 0x00000008 */ -#define DCTL_GONSTS DCTL_GONSTS_Msk // Global OUT NAK status */ +#define DCTL_GONSTS_Msk (0x1UL << DCTL_GONSTS_Pos) // 0x00000008 +#define DCTL_GONSTS DCTL_GONSTS_Msk // Global OUT NAK status #define DCTL_TCTL_Pos (4U) -#define DCTL_TCTL_Msk (0x7UL << DCTL_TCTL_Pos) // 0x00000070 */ -#define DCTL_TCTL DCTL_TCTL_Msk // Test control */ -#define DCTL_TCTL_0 (0x1UL << DCTL_TCTL_Pos) // 0x00000010 */ -#define DCTL_TCTL_1 (0x2UL << DCTL_TCTL_Pos) // 0x00000020 */ -#define DCTL_TCTL_2 (0x4UL << DCTL_TCTL_Pos) // 0x00000040 */ +#define DCTL_TCTL_Msk (0x7UL << DCTL_TCTL_Pos) // 0x00000070 +#define DCTL_TCTL DCTL_TCTL_Msk // Test control +#define DCTL_TCTL_0 (0x1UL << DCTL_TCTL_Pos) // 0x00000010 +#define DCTL_TCTL_1 (0x2UL << DCTL_TCTL_Pos) // 0x00000020 +#define DCTL_TCTL_2 (0x4UL << DCTL_TCTL_Pos) // 0x00000040 #define DCTL_SGINAK_Pos (7U) -#define DCTL_SGINAK_Msk (0x1UL << DCTL_SGINAK_Pos) // 0x00000080 */ -#define DCTL_SGINAK DCTL_SGINAK_Msk // Set global IN NAK */ +#define DCTL_SGINAK_Msk (0x1UL << DCTL_SGINAK_Pos) // 0x00000080 +#define DCTL_SGINAK DCTL_SGINAK_Msk // Set global IN NAK #define DCTL_CGINAK_Pos (8U) -#define DCTL_CGINAK_Msk (0x1UL << DCTL_CGINAK_Pos) // 0x00000100 */ -#define DCTL_CGINAK DCTL_CGINAK_Msk // Clear global IN NAK */ +#define DCTL_CGINAK_Msk (0x1UL << DCTL_CGINAK_Pos) // 0x00000100 +#define DCTL_CGINAK DCTL_CGINAK_Msk // Clear global IN NAK #define DCTL_SGONAK_Pos (9U) -#define DCTL_SGONAK_Msk (0x1UL << DCTL_SGONAK_Pos) // 0x00000200 */ -#define DCTL_SGONAK DCTL_SGONAK_Msk // Set global OUT NAK */ +#define DCTL_SGONAK_Msk (0x1UL << DCTL_SGONAK_Pos) // 0x00000200 +#define DCTL_SGONAK DCTL_SGONAK_Msk // Set global OUT NAK #define DCTL_CGONAK_Pos (10U) -#define DCTL_CGONAK_Msk (0x1UL << DCTL_CGONAK_Pos) // 0x00000400 */ -#define DCTL_CGONAK DCTL_CGONAK_Msk // Clear global OUT NAK */ +#define DCTL_CGONAK_Msk (0x1UL << DCTL_CGONAK_Pos) // 0x00000400 +#define DCTL_CGONAK DCTL_CGONAK_Msk // Clear global OUT NAK #define DCTL_POPRGDNE_Pos (11U) -#define DCTL_POPRGDNE_Msk (0x1UL << DCTL_POPRGDNE_Pos) // 0x00000800 */ -#define DCTL_POPRGDNE DCTL_POPRGDNE_Msk // Power-on programming done */ +#define DCTL_POPRGDNE_Msk (0x1UL << DCTL_POPRGDNE_Pos) // 0x00000800 +#define DCTL_POPRGDNE DCTL_POPRGDNE_Msk // Power-on programming done /******************** Bit definition for HFIR register ********************/ #define HFIR_FRIVL_Pos (0U) -#define HFIR_FRIVL_Msk (0xFFFFUL << HFIR_FRIVL_Pos) // 0x0000FFFF */ -#define HFIR_FRIVL HFIR_FRIVL_Msk // Frame interval */ +#define HFIR_FRIVL_Msk (0xFFFFUL << HFIR_FRIVL_Pos) // 0x0000FFFF +#define HFIR_FRIVL HFIR_FRIVL_Msk // Frame interval /******************** Bit definition for HFNUM register ********************/ #define HFNUM_FRNUM_Pos (0U) -#define HFNUM_FRNUM_Msk (0xFFFFUL << HFNUM_FRNUM_Pos) // 0x0000FFFF */ -#define HFNUM_FRNUM HFNUM_FRNUM_Msk // Frame number */ +#define HFNUM_FRNUM_Msk (0xFFFFUL << HFNUM_FRNUM_Pos) // 0x0000FFFF +#define HFNUM_FRNUM HFNUM_FRNUM_Msk // Frame number #define HFNUM_FTREM_Pos (16U) -#define HFNUM_FTREM_Msk (0xFFFFUL << HFNUM_FTREM_Pos) // 0xFFFF0000 */ -#define HFNUM_FTREM HFNUM_FTREM_Msk // Frame time remaining */ +#define HFNUM_FTREM_Msk (0xFFFFUL << HFNUM_FTREM_Pos) // 0xFFFF0000 +#define HFNUM_FTREM HFNUM_FTREM_Msk // Frame time remaining /******************** Bit definition for DSTS register ********************/ #define DSTS_SUSPSTS_Pos (0U) -#define DSTS_SUSPSTS_Msk (0x1UL << DSTS_SUSPSTS_Pos) // 0x00000001 */ -#define DSTS_SUSPSTS DSTS_SUSPSTS_Msk // Suspend status */ +#define DSTS_SUSPSTS_Msk (0x1UL << DSTS_SUSPSTS_Pos) // 0x00000001 +#define DSTS_SUSPSTS DSTS_SUSPSTS_Msk // Suspend status #define DSTS_ENUMSPD_Pos (1U) -#define DSTS_ENUMSPD_Msk (0x3UL << DSTS_ENUMSPD_Pos) // 0x00000006 */ -#define DSTS_ENUMSPD DSTS_ENUMSPD_Msk // Enumerated speed */ +#define DSTS_ENUMSPD_Msk (0x3UL << DSTS_ENUMSPD_Pos) // 0x00000006 +#define DSTS_ENUMSPD DSTS_ENUMSPD_Msk // Enumerated speed #define DSTS_ENUMSPD_HS 0 // Highspeed #define DSTS_ENUMSPD_FS_HSPHY 1 // Fullspeed on HS PHY #define DSTS_ENUMSPD_LS 2 // Lowspeed @@ -498,427 +499,427 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); #define DSTS_EERR_Pos (3U) -#define DSTS_EERR_Msk (0x1UL << DSTS_EERR_Pos) // 0x00000008 */ -#define DSTS_EERR DSTS_EERR_Msk // Erratic error */ +#define DSTS_EERR_Msk (0x1UL << DSTS_EERR_Pos) // 0x00000008 +#define DSTS_EERR DSTS_EERR_Msk // Erratic error #define DSTS_FNSOF_Pos (8U) -#define DSTS_FNSOF_Msk (0x3FFFUL << DSTS_FNSOF_Pos) // 0x003FFF00 */ -#define DSTS_FNSOF DSTS_FNSOF_Msk // Frame number of the received SOF */ +#define DSTS_FNSOF_Msk (0x3FFFUL << DSTS_FNSOF_Pos) // 0x003FFF00 +#define DSTS_FNSOF DSTS_FNSOF_Msk // Frame number of the received SOF /******************** Bit definition for GAHBCFG register ********************/ #define GAHBCFG_GINT_Pos (0U) -#define GAHBCFG_GINT_Msk (0x1UL << GAHBCFG_GINT_Pos) // 0x00000001 */ -#define GAHBCFG_GINT GAHBCFG_GINT_Msk // Global interrupt mask */ +#define GAHBCFG_GINT_Msk (0x1UL << GAHBCFG_GINT_Pos) // 0x00000001 +#define GAHBCFG_GINT GAHBCFG_GINT_Msk // Global interrupt mask #define GAHBCFG_HBSTLEN_Pos (1U) -#define GAHBCFG_HBSTLEN_Msk (0xFUL << GAHBCFG_HBSTLEN_Pos) // 0x0000001E */ -#define GAHBCFG_HBSTLEN GAHBCFG_HBSTLEN_Msk // Burst length/type */ -#define GAHBCFG_HBSTLEN_0 (0x0UL << GAHBCFG_HBSTLEN_Pos) // Single */ -#define GAHBCFG_HBSTLEN_1 (0x1UL << GAHBCFG_HBSTLEN_Pos) // INCR */ -#define GAHBCFG_HBSTLEN_2 (0x3UL << GAHBCFG_HBSTLEN_Pos) // INCR4 */ -#define GAHBCFG_HBSTLEN_3 (0x5UL << GAHBCFG_HBSTLEN_Pos) // INCR8 */ -#define GAHBCFG_HBSTLEN_4 (0x7UL << GAHBCFG_HBSTLEN_Pos) // INCR16 */ +#define GAHBCFG_HBSTLEN_Msk (0xFUL << GAHBCFG_HBSTLEN_Pos) // 0x0000001E +#define GAHBCFG_HBSTLEN GAHBCFG_HBSTLEN_Msk // Burst length/type +#define GAHBCFG_HBSTLEN_0 (0x0UL << GAHBCFG_HBSTLEN_Pos) // Single +#define GAHBCFG_HBSTLEN_1 (0x1UL << GAHBCFG_HBSTLEN_Pos) // INCR +#define GAHBCFG_HBSTLEN_2 (0x3UL << GAHBCFG_HBSTLEN_Pos) // INCR4 +#define GAHBCFG_HBSTLEN_3 (0x5UL << GAHBCFG_HBSTLEN_Pos) // INCR8 +#define GAHBCFG_HBSTLEN_4 (0x7UL << GAHBCFG_HBSTLEN_Pos) // INCR16 #define GAHBCFG_DMAEN_Pos (5U) -#define GAHBCFG_DMAEN_Msk (0x1UL << GAHBCFG_DMAEN_Pos) // 0x00000020 */ -#define GAHBCFG_DMAEN GAHBCFG_DMAEN_Msk // DMA enable */ +#define GAHBCFG_DMAEN_Msk (0x1UL << GAHBCFG_DMAEN_Pos) // 0x00000020 +#define GAHBCFG_DMAEN GAHBCFG_DMAEN_Msk // DMA enable #define GAHBCFG_TXFELVL_Pos (7U) -#define GAHBCFG_TXFELVL_Msk (0x1UL << GAHBCFG_TXFELVL_Pos) // 0x00000080 */ -#define GAHBCFG_TXFELVL GAHBCFG_TXFELVL_Msk // TxFIFO empty level */ +#define GAHBCFG_TXFELVL_Msk (0x1UL << GAHBCFG_TXFELVL_Pos) // 0x00000080 +#define GAHBCFG_TXFELVL GAHBCFG_TXFELVL_Msk // TxFIFO empty level #define GAHBCFG_PTXFELVL_Pos (8U) -#define GAHBCFG_PTXFELVL_Msk (0x1UL << GAHBCFG_PTXFELVL_Pos) // 0x00000100 */ -#define GAHBCFG_PTXFELVL GAHBCFG_PTXFELVL_Msk // Periodic TxFIFO empty level */ +#define GAHBCFG_PTXFELVL_Msk (0x1UL << GAHBCFG_PTXFELVL_Pos) // 0x00000100 +#define GAHBCFG_PTXFELVL GAHBCFG_PTXFELVL_Msk // Periodic TxFIFO empty level #define GSNPSID_ID_MASK TU_GENMASK(31, 16) /******************** Bit definition for GUSBCFG register ********************/ #define GUSBCFG_TOCAL_Pos (0U) -#define GUSBCFG_TOCAL_Msk (0x7UL << GUSBCFG_TOCAL_Pos) // 0x00000007 */ -#define GUSBCFG_TOCAL GUSBCFG_TOCAL_Msk // FS timeout calibration */ +#define GUSBCFG_TOCAL_Msk (0x7UL << GUSBCFG_TOCAL_Pos) // 0x00000007 +#define GUSBCFG_TOCAL GUSBCFG_TOCAL_Msk // FS timeout calibration #define GUSBCFG_PHYIF16_Pos (3U) -#define GUSBCFG_PHYIF16_Msk (0x1UL << GUSBCFG_PHYIF16_Pos) // 0x00000008 */ -#define GUSBCFG_PHYIF16 GUSBCFG_PHYIF16_Msk // PHY Interface (PHYIf) */ +#define GUSBCFG_PHYIF16_Msk (0x1UL << GUSBCFG_PHYIF16_Pos) // 0x00000008 +#define GUSBCFG_PHYIF16 GUSBCFG_PHYIF16_Msk // PHY Interface (PHYIf) #define GUSBCFG_ULPI_UTMI_SEL_Pos (4U) -#define GUSBCFG_ULPI_UTMI_SEL_Msk (0x1UL << GUSBCFG_ULPI_UTMI_SEL_Pos) // 0x00000010 */ -#define GUSBCFG_ULPI_UTMI_SEL GUSBCFG_ULPI_UTMI_SEL_Msk // ULPI or UTMI+ Select (ULPI_UTMI_Sel) */ +#define GUSBCFG_ULPI_UTMI_SEL_Msk (0x1UL << GUSBCFG_ULPI_UTMI_SEL_Pos) // 0x00000010 +#define GUSBCFG_ULPI_UTMI_SEL GUSBCFG_ULPI_UTMI_SEL_Msk // ULPI or UTMI+ Select (ULPI_UTMI_Sel) #define GUSBCFG_PHYSEL_Pos (6U) -#define GUSBCFG_PHYSEL_Msk (0x1UL << GUSBCFG_PHYSEL_Pos) // 0x00000040 */ -#define GUSBCFG_PHYSEL GUSBCFG_PHYSEL_Msk // USB 2.0 high-speed ULPI PHY or USB 1.1 full-speed serial transceiver select */ +#define GUSBCFG_PHYSEL_Msk (0x1UL << GUSBCFG_PHYSEL_Pos) // 0x00000040 +#define GUSBCFG_PHYSEL GUSBCFG_PHYSEL_Msk // USB 2.0 high-speed ULPI PHY or USB 1.1 full-speed serial transceiver select #define GUSBCFG_DDRSEL TU_BIT(7) // Single Data Rate (SDR) or Double Data Rate (DDR) or ULPI interface. #define GUSBCFG_SRPCAP_Pos (8U) -#define GUSBCFG_SRPCAP_Msk (0x1UL << GUSBCFG_SRPCAP_Pos) // 0x00000100 */ -#define GUSBCFG_SRPCAP GUSBCFG_SRPCAP_Msk // SRP-capable */ +#define GUSBCFG_SRPCAP_Msk (0x1UL << GUSBCFG_SRPCAP_Pos) // 0x00000100 +#define GUSBCFG_SRPCAP GUSBCFG_SRPCAP_Msk // SRP-capable #define GUSBCFG_HNPCAP_Pos (9U) -#define GUSBCFG_HNPCAP_Msk (0x1UL << GUSBCFG_HNPCAP_Pos) // 0x00000200 */ -#define GUSBCFG_HNPCAP GUSBCFG_HNPCAP_Msk // HNP-capable */ +#define GUSBCFG_HNPCAP_Msk (0x1UL << GUSBCFG_HNPCAP_Pos) // 0x00000200 +#define GUSBCFG_HNPCAP GUSBCFG_HNPCAP_Msk // HNP-capable #define GUSBCFG_TRDT_Pos (10U) -#define GUSBCFG_TRDT_Msk (0xFUL << GUSBCFG_TRDT_Pos) // 0x00003C00 */ -#define GUSBCFG_TRDT GUSBCFG_TRDT_Msk // USB turnaround time */ +#define GUSBCFG_TRDT_Msk (0xFUL << GUSBCFG_TRDT_Pos) // 0x00003C00 +#define GUSBCFG_TRDT GUSBCFG_TRDT_Msk // USB turnaround time #define GUSBCFG_PHYLPCS_Pos (15U) -#define GUSBCFG_PHYLPCS_Msk (0x1UL << GUSBCFG_PHYLPCS_Pos) // 0x00008000 */ -#define GUSBCFG_PHYLPCS GUSBCFG_PHYLPCS_Msk // PHY Low-power clock select */ +#define GUSBCFG_PHYLPCS_Msk (0x1UL << GUSBCFG_PHYLPCS_Pos) // 0x00008000 +#define GUSBCFG_PHYLPCS GUSBCFG_PHYLPCS_Msk // PHY Low-power clock select #define GUSBCFG_ULPIFSLS_Pos (17U) -#define GUSBCFG_ULPIFSLS_Msk (0x1UL << GUSBCFG_ULPIFSLS_Pos) // 0x00020000 */ -#define GUSBCFG_ULPIFSLS GUSBCFG_ULPIFSLS_Msk // ULPI FS/LS select */ +#define GUSBCFG_ULPIFSLS_Msk (0x1UL << GUSBCFG_ULPIFSLS_Pos) // 0x00020000 +#define GUSBCFG_ULPIFSLS GUSBCFG_ULPIFSLS_Msk // ULPI FS/LS select #define GUSBCFG_ULPIAR_Pos (18U) -#define GUSBCFG_ULPIAR_Msk (0x1UL << GUSBCFG_ULPIAR_Pos) // 0x00040000 */ -#define GUSBCFG_ULPIAR GUSBCFG_ULPIAR_Msk // ULPI Auto-resume */ +#define GUSBCFG_ULPIAR_Msk (0x1UL << GUSBCFG_ULPIAR_Pos) // 0x00040000 +#define GUSBCFG_ULPIAR GUSBCFG_ULPIAR_Msk // ULPI Auto-resume #define GUSBCFG_ULPICSM_Pos (19U) -#define GUSBCFG_ULPICSM_Msk (0x1UL << GUSBCFG_ULPICSM_Pos) // 0x00080000 */ -#define GUSBCFG_ULPICSM GUSBCFG_ULPICSM_Msk // ULPI Clock SuspendM */ +#define GUSBCFG_ULPICSM_Msk (0x1UL << GUSBCFG_ULPICSM_Pos) // 0x00080000 +#define GUSBCFG_ULPICSM GUSBCFG_ULPICSM_Msk // ULPI Clock SuspendM #define GUSBCFG_ULPIEVBUSD_Pos (20U) -#define GUSBCFG_ULPIEVBUSD_Msk (0x1UL << GUSBCFG_ULPIEVBUSD_Pos) // 0x00100000 */ -#define GUSBCFG_ULPIEVBUSD GUSBCFG_ULPIEVBUSD_Msk // ULPI External VBUS Drive */ +#define GUSBCFG_ULPIEVBUSD_Msk (0x1UL << GUSBCFG_ULPIEVBUSD_Pos) // 0x00100000 +#define GUSBCFG_ULPIEVBUSD GUSBCFG_ULPIEVBUSD_Msk // ULPI External VBUS Drive #define GUSBCFG_ULPIEVBUSI_Pos (21U) -#define GUSBCFG_ULPIEVBUSI_Msk (0x1UL << GUSBCFG_ULPIEVBUSI_Pos) // 0x00200000 */ -#define GUSBCFG_ULPIEVBUSI GUSBCFG_ULPIEVBUSI_Msk // ULPI external VBUS indicator */ +#define GUSBCFG_ULPIEVBUSI_Msk (0x1UL << GUSBCFG_ULPIEVBUSI_Pos) // 0x00200000 +#define GUSBCFG_ULPIEVBUSI GUSBCFG_ULPIEVBUSI_Msk // ULPI external VBUS indicator #define GUSBCFG_TSDPS_Pos (22U) -#define GUSBCFG_TSDPS_Msk (0x1UL << GUSBCFG_TSDPS_Pos) // 0x00400000 */ -#define GUSBCFG_TSDPS GUSBCFG_TSDPS_Msk // TermSel DLine pulsing selection */ +#define GUSBCFG_TSDPS_Msk (0x1UL << GUSBCFG_TSDPS_Pos) // 0x00400000 +#define GUSBCFG_TSDPS GUSBCFG_TSDPS_Msk // TermSel DLine pulsing selection #define GUSBCFG_PCCI_Pos (23U) -#define GUSBCFG_PCCI_Msk (0x1UL << GUSBCFG_PCCI_Pos) // 0x00800000 */ -#define GUSBCFG_PCCI GUSBCFG_PCCI_Msk // Indicator complement */ +#define GUSBCFG_PCCI_Msk (0x1UL << GUSBCFG_PCCI_Pos) // 0x00800000 +#define GUSBCFG_PCCI GUSBCFG_PCCI_Msk // Indicator complement #define GUSBCFG_PTCI_Pos (24U) -#define GUSBCFG_PTCI_Msk (0x1UL << GUSBCFG_PTCI_Pos) // 0x01000000 */ -#define GUSBCFG_PTCI GUSBCFG_PTCI_Msk // Indicator pass through */ +#define GUSBCFG_PTCI_Msk (0x1UL << GUSBCFG_PTCI_Pos) // 0x01000000 +#define GUSBCFG_PTCI GUSBCFG_PTCI_Msk // Indicator pass through #define GUSBCFG_ULPIIPD_Pos (25U) -#define GUSBCFG_ULPIIPD_Msk (0x1UL << GUSBCFG_ULPIIPD_Pos) // 0x02000000 */ -#define GUSBCFG_ULPIIPD GUSBCFG_ULPIIPD_Msk // ULPI interface protect disable */ +#define GUSBCFG_ULPIIPD_Msk (0x1UL << GUSBCFG_ULPIIPD_Pos) // 0x02000000 +#define GUSBCFG_ULPIIPD GUSBCFG_ULPIIPD_Msk // ULPI interface protect disable #define GUSBCFG_FHMOD_Pos (29U) -#define GUSBCFG_FHMOD_Msk (0x1UL << GUSBCFG_FHMOD_Pos) // 0x20000000 */ -#define GUSBCFG_FHMOD GUSBCFG_FHMOD_Msk // Forced host mode */ +#define GUSBCFG_FHMOD_Msk (0x1UL << GUSBCFG_FHMOD_Pos) // 0x20000000 +#define GUSBCFG_FHMOD GUSBCFG_FHMOD_Msk // Forced host mode #define GUSBCFG_FDMOD_Pos (30U) -#define GUSBCFG_FDMOD_Msk (0x1UL << GUSBCFG_FDMOD_Pos) // 0x40000000 */ -#define GUSBCFG_FDMOD GUSBCFG_FDMOD_Msk // Forced peripheral mode */ +#define GUSBCFG_FDMOD_Msk (0x1UL << GUSBCFG_FDMOD_Pos) // 0x40000000 +#define GUSBCFG_FDMOD GUSBCFG_FDMOD_Msk // Forced peripheral mode #define GUSBCFG_CTXPKT_Pos (31U) -#define GUSBCFG_CTXPKT_Msk (0x1UL << GUSBCFG_CTXPKT_Pos) // 0x80000000 */ -#define GUSBCFG_CTXPKT GUSBCFG_CTXPKT_Msk // Corrupt Tx packet */ +#define GUSBCFG_CTXPKT_Msk (0x1UL << GUSBCFG_CTXPKT_Pos) // 0x80000000 +#define GUSBCFG_CTXPKT GUSBCFG_CTXPKT_Msk // Corrupt Tx packet /******************** Bit definition for GRSTCTL register ********************/ #define GRSTCTL_CSRST_Pos (0U) -#define GRSTCTL_CSRST_Msk (0x1UL << GRSTCTL_CSRST_Pos) // 0x00000001 */ -#define GRSTCTL_CSRST GRSTCTL_CSRST_Msk // Core soft reset */ +#define GRSTCTL_CSRST_Msk (0x1UL << GRSTCTL_CSRST_Pos) // 0x00000001 +#define GRSTCTL_CSRST GRSTCTL_CSRST_Msk // Core soft reset #define GRSTCTL_HSRST_Pos (1U) -#define GRSTCTL_HSRST_Msk (0x1UL << GRSTCTL_HSRST_Pos) // 0x00000002 */ -#define GRSTCTL_HSRST GRSTCTL_HSRST_Msk // HCLK soft reset */ +#define GRSTCTL_HSRST_Msk (0x1UL << GRSTCTL_HSRST_Pos) // 0x00000002 +#define GRSTCTL_HSRST GRSTCTL_HSRST_Msk // HCLK soft reset #define GRSTCTL_FCRST_Pos (2U) -#define GRSTCTL_FCRST_Msk (0x1UL << GRSTCTL_FCRST_Pos) // 0x00000004 */ -#define GRSTCTL_FCRST GRSTCTL_FCRST_Msk // Host frame counter reset */ +#define GRSTCTL_FCRST_Msk (0x1UL << GRSTCTL_FCRST_Pos) // 0x00000004 +#define GRSTCTL_FCRST GRSTCTL_FCRST_Msk // Host frame counter reset #define GRSTCTL_RXFFLSH_Pos (4U) -#define GRSTCTL_RXFFLSH_Msk (0x1UL << GRSTCTL_RXFFLSH_Pos) // 0x00000010 */ -#define GRSTCTL_RXFFLSH GRSTCTL_RXFFLSH_Msk // RxFIFO flush */ +#define GRSTCTL_RXFFLSH_Msk (0x1UL << GRSTCTL_RXFFLSH_Pos) // 0x00000010 +#define GRSTCTL_RXFFLSH GRSTCTL_RXFFLSH_Msk // RxFIFO flush #define GRSTCTL_TXFFLSH_Pos (5U) -#define GRSTCTL_TXFFLSH_Msk (0x1UL << GRSTCTL_TXFFLSH_Pos) // 0x00000020 */ -#define GRSTCTL_TXFFLSH GRSTCTL_TXFFLSH_Msk // TxFIFO flush */ +#define GRSTCTL_TXFFLSH_Msk (0x1UL << GRSTCTL_TXFFLSH_Pos) // 0x00000020 +#define GRSTCTL_TXFFLSH GRSTCTL_TXFFLSH_Msk // TxFIFO flush #define GRSTCTL_TXFNUM_Pos (6U) -#define GRSTCTL_TXFNUM_Msk (0x1FUL << GRSTCTL_TXFNUM_Pos) // 0x000007C0 */ -#define GRSTCTL_TXFNUM GRSTCTL_TXFNUM_Msk // TxFIFO number */ -#define GRSTCTL_TXFNUM_0 (0x01UL << GRSTCTL_TXFNUM_Pos) // 0x00000040 */ -#define GRSTCTL_TXFNUM_1 (0x02UL << GRSTCTL_TXFNUM_Pos) // 0x00000080 */ -#define GRSTCTL_TXFNUM_2 (0x04UL << GRSTCTL_TXFNUM_Pos) // 0x00000100 */ -#define GRSTCTL_TXFNUM_3 (0x08UL << GRSTCTL_TXFNUM_Pos) // 0x00000200 */ -#define GRSTCTL_TXFNUM_4 (0x10UL << GRSTCTL_TXFNUM_Pos) // 0x00000400 */ +#define GRSTCTL_TXFNUM_Msk (0x1FUL << GRSTCTL_TXFNUM_Pos) // 0x000007C0 +#define GRSTCTL_TXFNUM GRSTCTL_TXFNUM_Msk // TxFIFO number +#define GRSTCTL_TXFNUM_0 (0x01UL << GRSTCTL_TXFNUM_Pos) // 0x00000040 +#define GRSTCTL_TXFNUM_1 (0x02UL << GRSTCTL_TXFNUM_Pos) // 0x00000080 +#define GRSTCTL_TXFNUM_2 (0x04UL << GRSTCTL_TXFNUM_Pos) // 0x00000100 +#define GRSTCTL_TXFNUM_3 (0x08UL << GRSTCTL_TXFNUM_Pos) // 0x00000200 +#define GRSTCTL_TXFNUM_4 (0x10UL << GRSTCTL_TXFNUM_Pos) // 0x00000400 #define GRSTCTL_CSFTRST_DONE_Pos (29) #define GRSTCTL_CSFTRST_DONE (1u << GRSTCTL_CSFTRST_DONE_Pos) // Reset Done, only available from v4.20a #define GRSTCTL_DMAREQ_Pos (30U) -#define GRSTCTL_DMAREQ_Msk (0x1UL << GRSTCTL_DMAREQ_Pos) // 0x40000000 */ -#define GRSTCTL_DMAREQ GRSTCTL_DMAREQ_Msk // DMA request signal */ +#define GRSTCTL_DMAREQ_Msk (0x1UL << GRSTCTL_DMAREQ_Pos) // 0x40000000 +#define GRSTCTL_DMAREQ GRSTCTL_DMAREQ_Msk // DMA request signal #define GRSTCTL_AHBIDL_Pos (31U) -#define GRSTCTL_AHBIDL_Msk (0x1UL << GRSTCTL_AHBIDL_Pos) // 0x80000000 */ -#define GRSTCTL_AHBIDL GRSTCTL_AHBIDL_Msk // AHB master idle */ +#define GRSTCTL_AHBIDL_Msk (0x1UL << GRSTCTL_AHBIDL_Pos) // 0x80000000 +#define GRSTCTL_AHBIDL GRSTCTL_AHBIDL_Msk // AHB master idle /******************** Bit definition for DIEPMSK register ********************/ #define DIEPMSK_XFRCM_Pos (0U) -#define DIEPMSK_XFRCM_Msk (0x1UL << DIEPMSK_XFRCM_Pos) // 0x00000001 */ -#define DIEPMSK_XFRCM DIEPMSK_XFRCM_Msk // Transfer completed interrupt mask */ +#define DIEPMSK_XFRCM_Msk (0x1UL << DIEPMSK_XFRCM_Pos) // 0x00000001 +#define DIEPMSK_XFRCM DIEPMSK_XFRCM_Msk // Transfer completed interrupt mask #define DIEPMSK_EPDM_Pos (1U) -#define DIEPMSK_EPDM_Msk (0x1UL << DIEPMSK_EPDM_Pos) // 0x00000002 */ -#define DIEPMSK_EPDM DIEPMSK_EPDM_Msk // Endpoint disabled interrupt mask */ +#define DIEPMSK_EPDM_Msk (0x1UL << DIEPMSK_EPDM_Pos) // 0x00000002 +#define DIEPMSK_EPDM DIEPMSK_EPDM_Msk // Endpoint disabled interrupt mask #define DIEPMSK_TOM_Pos (3U) -#define DIEPMSK_TOM_Msk (0x1UL << DIEPMSK_TOM_Pos) // 0x00000008 */ -#define DIEPMSK_TOM DIEPMSK_TOM_Msk // Timeout condition mask (nonisochronous endpoints) */ +#define DIEPMSK_TOM_Msk (0x1UL << DIEPMSK_TOM_Pos) // 0x00000008 +#define DIEPMSK_TOM DIEPMSK_TOM_Msk // Timeout condition mask (nonisochronous endpoints) #define DIEPMSK_ITTXFEMSK_Pos (4U) -#define DIEPMSK_ITTXFEMSK_Msk (0x1UL << DIEPMSK_ITTXFEMSK_Pos) // 0x00000010 */ -#define DIEPMSK_ITTXFEMSK DIEPMSK_ITTXFEMSK_Msk // IN token received when TxFIFO empty mask */ +#define DIEPMSK_ITTXFEMSK_Msk (0x1UL << DIEPMSK_ITTXFEMSK_Pos) // 0x00000010 +#define DIEPMSK_ITTXFEMSK DIEPMSK_ITTXFEMSK_Msk // IN token received when TxFIFO empty mask #define DIEPMSK_INEPNMM_Pos (5U) -#define DIEPMSK_INEPNMM_Msk (0x1UL << DIEPMSK_INEPNMM_Pos) // 0x00000020 */ -#define DIEPMSK_INEPNMM DIEPMSK_INEPNMM_Msk // IN token received with EP mismatch mask */ +#define DIEPMSK_INEPNMM_Msk (0x1UL << DIEPMSK_INEPNMM_Pos) // 0x00000020 +#define DIEPMSK_INEPNMM DIEPMSK_INEPNMM_Msk // IN token received with EP mismatch mask #define DIEPMSK_INEPNEM_Pos (6U) -#define DIEPMSK_INEPNEM_Msk (0x1UL << DIEPMSK_INEPNEM_Pos) // 0x00000040 */ -#define DIEPMSK_INEPNEM DIEPMSK_INEPNEM_Msk // IN endpoint NAK effective mask */ +#define DIEPMSK_INEPNEM_Msk (0x1UL << DIEPMSK_INEPNEM_Pos) // 0x00000040 +#define DIEPMSK_INEPNEM DIEPMSK_INEPNEM_Msk // IN endpoint NAK effective mask #define DIEPMSK_TXFURM_Pos (8U) -#define DIEPMSK_TXFURM_Msk (0x1UL << DIEPMSK_TXFURM_Pos) // 0x00000100 */ -#define DIEPMSK_TXFURM DIEPMSK_TXFURM_Msk // FIFO underrun mask */ +#define DIEPMSK_TXFURM_Msk (0x1UL << DIEPMSK_TXFURM_Pos) // 0x00000100 +#define DIEPMSK_TXFURM DIEPMSK_TXFURM_Msk // FIFO underrun mask #define DIEPMSK_BIM_Pos (9U) -#define DIEPMSK_BIM_Msk (0x1UL << DIEPMSK_BIM_Pos) // 0x00000200 */ -#define DIEPMSK_BIM DIEPMSK_BIM_Msk // BNA interrupt mask */ +#define DIEPMSK_BIM_Msk (0x1UL << DIEPMSK_BIM_Pos) // 0x00000200 +#define DIEPMSK_BIM DIEPMSK_BIM_Msk // BNA interrupt mask /******************** Bit definition for HPTXSTS register ********************/ #define HPTXSTS_PTXFSAVL_Pos (0U) -#define HPTXSTS_PTXFSAVL_Msk (0xFFFFUL << HPTXSTS_PTXFSAVL_Pos) // 0x0000FFFF */ -#define HPTXSTS_PTXFSAVL HPTXSTS_PTXFSAVL_Msk // Periodic transmit data FIFO space available */ +#define HPTXSTS_PTXFSAVL_Msk (0xFFFFUL << HPTXSTS_PTXFSAVL_Pos) // 0x0000FFFF +#define HPTXSTS_PTXFSAVL HPTXSTS_PTXFSAVL_Msk // Periodic transmit data FIFO space available #define HPTXSTS_PTXQSAV_Pos (16U) -#define HPTXSTS_PTXQSAV_Msk (0xFFUL << HPTXSTS_PTXQSAV_Pos) // 0x00FF0000 */ -#define HPTXSTS_PTXQSAV HPTXSTS_PTXQSAV_Msk // Periodic transmit request queue space available */ -#define HPTXSTS_PTXQSAV_0 (0x01UL << HPTXSTS_PTXQSAV_Pos) // 0x00010000 */ -#define HPTXSTS_PTXQSAV_1 (0x02UL << HPTXSTS_PTXQSAV_Pos) // 0x00020000 */ -#define HPTXSTS_PTXQSAV_2 (0x04UL << HPTXSTS_PTXQSAV_Pos) // 0x00040000 */ -#define HPTXSTS_PTXQSAV_3 (0x08UL << HPTXSTS_PTXQSAV_Pos) // 0x00080000 */ -#define HPTXSTS_PTXQSAV_4 (0x10UL << HPTXSTS_PTXQSAV_Pos) // 0x00100000 */ -#define HPTXSTS_PTXQSAV_5 (0x20UL << HPTXSTS_PTXQSAV_Pos) // 0x00200000 */ -#define HPTXSTS_PTXQSAV_6 (0x40UL << HPTXSTS_PTXQSAV_Pos) // 0x00400000 */ -#define HPTXSTS_PTXQSAV_7 (0x80UL << HPTXSTS_PTXQSAV_Pos) // 0x00800000 */ +#define HPTXSTS_PTXQSAV_Msk (0xFFUL << HPTXSTS_PTXQSAV_Pos) // 0x00FF0000 +#define HPTXSTS_PTXQSAV HPTXSTS_PTXQSAV_Msk // Periodic transmit request queue space available +#define HPTXSTS_PTXQSAV_0 (0x01UL << HPTXSTS_PTXQSAV_Pos) // 0x00010000 +#define HPTXSTS_PTXQSAV_1 (0x02UL << HPTXSTS_PTXQSAV_Pos) // 0x00020000 +#define HPTXSTS_PTXQSAV_2 (0x04UL << HPTXSTS_PTXQSAV_Pos) // 0x00040000 +#define HPTXSTS_PTXQSAV_3 (0x08UL << HPTXSTS_PTXQSAV_Pos) // 0x00080000 +#define HPTXSTS_PTXQSAV_4 (0x10UL << HPTXSTS_PTXQSAV_Pos) // 0x00100000 +#define HPTXSTS_PTXQSAV_5 (0x20UL << HPTXSTS_PTXQSAV_Pos) // 0x00200000 +#define HPTXSTS_PTXQSAV_6 (0x40UL << HPTXSTS_PTXQSAV_Pos) // 0x00400000 +#define HPTXSTS_PTXQSAV_7 (0x80UL << HPTXSTS_PTXQSAV_Pos) // 0x00800000 #define HPTXSTS_PTXQTOP_Pos (24U) -#define HPTXSTS_PTXQTOP_Msk (0xFFUL << HPTXSTS_PTXQTOP_Pos) // 0xFF000000 */ -#define HPTXSTS_PTXQTOP HPTXSTS_PTXQTOP_Msk // Top of the periodic transmit request queue */ -#define HPTXSTS_PTXQTOP_0 (0x01UL << HPTXSTS_PTXQTOP_Pos) // 0x01000000 */ -#define HPTXSTS_PTXQTOP_1 (0x02UL << HPTXSTS_PTXQTOP_Pos) // 0x02000000 */ -#define HPTXSTS_PTXQTOP_2 (0x04UL << HPTXSTS_PTXQTOP_Pos) // 0x04000000 */ -#define HPTXSTS_PTXQTOP_3 (0x08UL << HPTXSTS_PTXQTOP_Pos) // 0x08000000 */ -#define HPTXSTS_PTXQTOP_4 (0x10UL << HPTXSTS_PTXQTOP_Pos) // 0x10000000 */ -#define HPTXSTS_PTXQTOP_5 (0x20UL << HPTXSTS_PTXQTOP_Pos) // 0x20000000 */ -#define HPTXSTS_PTXQTOP_6 (0x40UL << HPTXSTS_PTXQTOP_Pos) // 0x40000000 */ -#define HPTXSTS_PTXQTOP_7 (0x80UL << HPTXSTS_PTXQTOP_Pos) // 0x80000000 */ +#define HPTXSTS_PTXQTOP_Msk (0xFFUL << HPTXSTS_PTXQTOP_Pos) // 0xFF000000 +#define HPTXSTS_PTXQTOP HPTXSTS_PTXQTOP_Msk // Top of the periodic transmit request queue +#define HPTXSTS_PTXQTOP_0 (0x01UL << HPTXSTS_PTXQTOP_Pos) // 0x01000000 +#define HPTXSTS_PTXQTOP_1 (0x02UL << HPTXSTS_PTXQTOP_Pos) // 0x02000000 +#define HPTXSTS_PTXQTOP_2 (0x04UL << HPTXSTS_PTXQTOP_Pos) // 0x04000000 +#define HPTXSTS_PTXQTOP_3 (0x08UL << HPTXSTS_PTXQTOP_Pos) // 0x08000000 +#define HPTXSTS_PTXQTOP_4 (0x10UL << HPTXSTS_PTXQTOP_Pos) // 0x10000000 +#define HPTXSTS_PTXQTOP_5 (0x20UL << HPTXSTS_PTXQTOP_Pos) // 0x20000000 +#define HPTXSTS_PTXQTOP_6 (0x40UL << HPTXSTS_PTXQTOP_Pos) // 0x40000000 +#define HPTXSTS_PTXQTOP_7 (0x80UL << HPTXSTS_PTXQTOP_Pos) // 0x80000000 /******************** Bit definition for HAINT register ********************/ #define HAINT_HAINT_Pos (0U) -#define HAINT_HAINT_Msk (0xFFFFUL << HAINT_HAINT_Pos) // 0x0000FFFF */ -#define HAINT_HAINT HAINT_HAINT_Msk // Channel interrupts */ +#define HAINT_HAINT_Msk (0xFFFFUL << HAINT_HAINT_Pos) // 0x0000FFFF +#define HAINT_HAINT HAINT_HAINT_Msk // Channel interrupts /******************** Bit definition for DOEPMSK register ********************/ #define DOEPMSK_XFRCM_Pos (0U) -#define DOEPMSK_XFRCM_Msk (0x1UL << DOEPMSK_XFRCM_Pos) // 0x00000001 */ -#define DOEPMSK_XFRCM DOEPMSK_XFRCM_Msk // Transfer completed interrupt mask */ +#define DOEPMSK_XFRCM_Msk (0x1UL << DOEPMSK_XFRCM_Pos) // 0x00000001 +#define DOEPMSK_XFRCM DOEPMSK_XFRCM_Msk // Transfer completed interrupt mask #define DOEPMSK_EPDM_Pos (1U) -#define DOEPMSK_EPDM_Msk (0x1UL << DOEPMSK_EPDM_Pos) // 0x00000002 */ -#define DOEPMSK_EPDM DOEPMSK_EPDM_Msk // Endpoint disabled interrupt mask */ +#define DOEPMSK_EPDM_Msk (0x1UL << DOEPMSK_EPDM_Pos) // 0x00000002 +#define DOEPMSK_EPDM DOEPMSK_EPDM_Msk // Endpoint disabled interrupt mask #define DOEPMSK_AHBERRM_Pos (2U) -#define DOEPMSK_AHBERRM_Msk (0x1UL << DOEPMSK_AHBERRM_Pos) // 0x00000004 */ -#define DOEPMSK_AHBERRM DOEPMSK_AHBERRM_Msk // OUT transaction AHB Error interrupt mask */ +#define DOEPMSK_AHBERRM_Msk (0x1UL << DOEPMSK_AHBERRM_Pos) // 0x00000004 +#define DOEPMSK_AHBERRM DOEPMSK_AHBERRM_Msk // OUT transaction AHB Error interrupt mask #define DOEPMSK_STUPM_Pos (3U) -#define DOEPMSK_STUPM_Msk (0x1UL << DOEPMSK_STUPM_Pos) // 0x00000008 */ -#define DOEPMSK_STUPM DOEPMSK_STUPM_Msk // SETUP phase done mask */ +#define DOEPMSK_STUPM_Msk (0x1UL << DOEPMSK_STUPM_Pos) // 0x00000008 +#define DOEPMSK_STUPM DOEPMSK_STUPM_Msk // SETUP phase done mask #define DOEPMSK_OTEPDM_Pos (4U) -#define DOEPMSK_OTEPDM_Msk (0x1UL << DOEPMSK_OTEPDM_Pos) // 0x00000010 */ -#define DOEPMSK_OTEPDM DOEPMSK_OTEPDM_Msk // OUT token received when endpoint disabled mask */ +#define DOEPMSK_OTEPDM_Msk (0x1UL << DOEPMSK_OTEPDM_Pos) // 0x00000010 +#define DOEPMSK_OTEPDM DOEPMSK_OTEPDM_Msk // OUT token received when endpoint disabled mask #define DOEPMSK_OTEPSPRM_Pos (5U) -#define DOEPMSK_OTEPSPRM_Msk (0x1UL << DOEPMSK_OTEPSPRM_Pos) // 0x00000020 */ -#define DOEPMSK_OTEPSPRM DOEPMSK_OTEPSPRM_Msk // Status Phase Received mask */ +#define DOEPMSK_OTEPSPRM_Msk (0x1UL << DOEPMSK_OTEPSPRM_Pos) // 0x00000020 +#define DOEPMSK_OTEPSPRM DOEPMSK_OTEPSPRM_Msk // Status Phase Received mask #define DOEPMSK_B2BSTUP_Pos (6U) -#define DOEPMSK_B2BSTUP_Msk (0x1UL << DOEPMSK_B2BSTUP_Pos) // 0x00000040 */ -#define DOEPMSK_B2BSTUP DOEPMSK_B2BSTUP_Msk // Back-to-back SETUP packets received mask */ +#define DOEPMSK_B2BSTUP_Msk (0x1UL << DOEPMSK_B2BSTUP_Pos) // 0x00000040 +#define DOEPMSK_B2BSTUP DOEPMSK_B2BSTUP_Msk // Back-to-back SETUP packets received mask #define DOEPMSK_OPEM_Pos (8U) -#define DOEPMSK_OPEM_Msk (0x1UL << DOEPMSK_OPEM_Pos) // 0x00000100 */ -#define DOEPMSK_OPEM DOEPMSK_OPEM_Msk // OUT packet error mask */ +#define DOEPMSK_OPEM_Msk (0x1UL << DOEPMSK_OPEM_Pos) // 0x00000100 +#define DOEPMSK_OPEM DOEPMSK_OPEM_Msk // OUT packet error mask #define DOEPMSK_BOIM_Pos (9U) -#define DOEPMSK_BOIM_Msk (0x1UL << DOEPMSK_BOIM_Pos) // 0x00000200 */ -#define DOEPMSK_BOIM DOEPMSK_BOIM_Msk // BNA interrupt mask */ +#define DOEPMSK_BOIM_Msk (0x1UL << DOEPMSK_BOIM_Pos) // 0x00000200 +#define DOEPMSK_BOIM DOEPMSK_BOIM_Msk // BNA interrupt mask #define DOEPMSK_BERRM_Pos (12U) -#define DOEPMSK_BERRM_Msk (0x1UL << DOEPMSK_BERRM_Pos) // 0x00001000 */ -#define DOEPMSK_BERRM DOEPMSK_BERRM_Msk // Babble error interrupt mask */ +#define DOEPMSK_BERRM_Msk (0x1UL << DOEPMSK_BERRM_Pos) // 0x00001000 +#define DOEPMSK_BERRM DOEPMSK_BERRM_Msk // Babble error interrupt mask #define DOEPMSK_NAKM_Pos (13U) -#define DOEPMSK_NAKM_Msk (0x1UL << DOEPMSK_NAKM_Pos) // 0x00002000 */ -#define DOEPMSK_NAKM DOEPMSK_NAKM_Msk // OUT Packet NAK interrupt mask */ +#define DOEPMSK_NAKM_Msk (0x1UL << DOEPMSK_NAKM_Pos) // 0x00002000 +#define DOEPMSK_NAKM DOEPMSK_NAKM_Msk // OUT Packet NAK interrupt mask #define DOEPMSK_NYETM_Pos (14U) -#define DOEPMSK_NYETM_Msk (0x1UL << DOEPMSK_NYETM_Pos) // 0x00004000 */ -#define DOEPMSK_NYETM DOEPMSK_NYETM_Msk // NYET interrupt mask */ +#define DOEPMSK_NYETM_Msk (0x1UL << DOEPMSK_NYETM_Pos) // 0x00004000 +#define DOEPMSK_NYETM DOEPMSK_NYETM_Msk // NYET interrupt mask /******************** Bit definition for GINTSTS register ********************/ #define GINTSTS_CMOD_Pos (0U) -#define GINTSTS_CMOD_Msk (0x1UL << GINTSTS_CMOD_Pos) // 0x00000001 */ -#define GINTSTS_CMOD GINTSTS_CMOD_Msk // Current mode of operation */ +#define GINTSTS_CMOD_Msk (0x1UL << GINTSTS_CMOD_Pos) // 0x00000001 +#define GINTSTS_CMOD GINTSTS_CMOD_Msk // Current mode of operation #define GINTSTS_MMIS_Pos (1U) -#define GINTSTS_MMIS_Msk (0x1UL << GINTSTS_MMIS_Pos) // 0x00000002 */ -#define GINTSTS_MMIS GINTSTS_MMIS_Msk // Mode mismatch interrupt */ +#define GINTSTS_MMIS_Msk (0x1UL << GINTSTS_MMIS_Pos) // 0x00000002 +#define GINTSTS_MMIS GINTSTS_MMIS_Msk // Mode mismatch interrupt #define GINTSTS_OTGINT_Pos (2U) -#define GINTSTS_OTGINT_Msk (0x1UL << GINTSTS_OTGINT_Pos) // 0x00000004 */ -#define GINTSTS_OTGINT GINTSTS_OTGINT_Msk // OTG interrupt */ +#define GINTSTS_OTGINT_Msk (0x1UL << GINTSTS_OTGINT_Pos) // 0x00000004 +#define GINTSTS_OTGINT GINTSTS_OTGINT_Msk // OTG interrupt #define GINTSTS_SOF_Pos (3U) -#define GINTSTS_SOF_Msk (0x1UL << GINTSTS_SOF_Pos) // 0x00000008 */ -#define GINTSTS_SOF GINTSTS_SOF_Msk // Start of frame */ +#define GINTSTS_SOF_Msk (0x1UL << GINTSTS_SOF_Pos) // 0x00000008 +#define GINTSTS_SOF GINTSTS_SOF_Msk // Start of frame #define GINTSTS_RXFLVL_Pos (4U) -#define GINTSTS_RXFLVL_Msk (0x1UL << GINTSTS_RXFLVL_Pos) // 0x00000010 */ -#define GINTSTS_RXFLVL GINTSTS_RXFLVL_Msk // RxFIFO nonempty */ +#define GINTSTS_RXFLVL_Msk (0x1UL << GINTSTS_RXFLVL_Pos) // 0x00000010 +#define GINTSTS_RXFLVL GINTSTS_RXFLVL_Msk // RxFIFO nonempty #define GINTSTS_NPTXFE_Pos (5U) -#define GINTSTS_NPTXFE_Msk (0x1UL << GINTSTS_NPTXFE_Pos) // 0x00000020 */ -#define GINTSTS_NPTXFE GINTSTS_NPTXFE_Msk // Nonperiodic TxFIFO empty */ +#define GINTSTS_NPTXFE_Msk (0x1UL << GINTSTS_NPTXFE_Pos) // 0x00000020 +#define GINTSTS_NPTXFE GINTSTS_NPTXFE_Msk // Nonperiodic TxFIFO empty #define GINTSTS_GINAKEFF_Pos (6U) -#define GINTSTS_GINAKEFF_Msk (0x1UL << GINTSTS_GINAKEFF_Pos) // 0x00000040 */ -#define GINTSTS_GINAKEFF GINTSTS_GINAKEFF_Msk // Global IN nonperiodic NAK effective */ +#define GINTSTS_GINAKEFF_Msk (0x1UL << GINTSTS_GINAKEFF_Pos) // 0x00000040 +#define GINTSTS_GINAKEFF GINTSTS_GINAKEFF_Msk // Global IN nonperiodic NAK effective #define GINTSTS_BOUTNAKEFF_Pos (7U) -#define GINTSTS_BOUTNAKEFF_Msk (0x1UL << GINTSTS_BOUTNAKEFF_Pos) // 0x00000080 */ -#define GINTSTS_BOUTNAKEFF GINTSTS_BOUTNAKEFF_Msk // Global OUT NAK effective */ +#define GINTSTS_BOUTNAKEFF_Msk (0x1UL << GINTSTS_BOUTNAKEFF_Pos) // 0x00000080 +#define GINTSTS_BOUTNAKEFF GINTSTS_BOUTNAKEFF_Msk // Global OUT NAK effective #define GINTSTS_ESUSP_Pos (10U) -#define GINTSTS_ESUSP_Msk (0x1UL << GINTSTS_ESUSP_Pos) // 0x00000400 */ -#define GINTSTS_ESUSP GINTSTS_ESUSP_Msk // Early suspend */ +#define GINTSTS_ESUSP_Msk (0x1UL << GINTSTS_ESUSP_Pos) // 0x00000400 +#define GINTSTS_ESUSP GINTSTS_ESUSP_Msk // Early suspend #define GINTSTS_USBSUSP_Pos (11U) -#define GINTSTS_USBSUSP_Msk (0x1UL << GINTSTS_USBSUSP_Pos) // 0x00000800 */ -#define GINTSTS_USBSUSP GINTSTS_USBSUSP_Msk // USB suspend */ +#define GINTSTS_USBSUSP_Msk (0x1UL << GINTSTS_USBSUSP_Pos) // 0x00000800 +#define GINTSTS_USBSUSP GINTSTS_USBSUSP_Msk // USB suspend #define GINTSTS_USBRST_Pos (12U) -#define GINTSTS_USBRST_Msk (0x1UL << GINTSTS_USBRST_Pos) // 0x00001000 */ -#define GINTSTS_USBRST GINTSTS_USBRST_Msk // USB reset */ +#define GINTSTS_USBRST_Msk (0x1UL << GINTSTS_USBRST_Pos) // 0x00001000 +#define GINTSTS_USBRST GINTSTS_USBRST_Msk // USB reset #define GINTSTS_ENUMDNE_Pos (13U) -#define GINTSTS_ENUMDNE_Msk (0x1UL << GINTSTS_ENUMDNE_Pos) // 0x00002000 */ -#define GINTSTS_ENUMDNE GINTSTS_ENUMDNE_Msk // Enumeration done */ +#define GINTSTS_ENUMDNE_Msk (0x1UL << GINTSTS_ENUMDNE_Pos) // 0x00002000 +#define GINTSTS_ENUMDNE GINTSTS_ENUMDNE_Msk // Enumeration done #define GINTSTS_ISOODRP_Pos (14U) -#define GINTSTS_ISOODRP_Msk (0x1UL << GINTSTS_ISOODRP_Pos) // 0x00004000 */ -#define GINTSTS_ISOODRP GINTSTS_ISOODRP_Msk // Isochronous OUT packet dropped interrupt */ +#define GINTSTS_ISOODRP_Msk (0x1UL << GINTSTS_ISOODRP_Pos) // 0x00004000 +#define GINTSTS_ISOODRP GINTSTS_ISOODRP_Msk // Isochronous OUT packet dropped interrupt #define GINTSTS_EOPF_Pos (15U) -#define GINTSTS_EOPF_Msk (0x1UL << GINTSTS_EOPF_Pos) // 0x00008000 */ -#define GINTSTS_EOPF GINTSTS_EOPF_Msk // End of periodic frame interrupt */ +#define GINTSTS_EOPF_Msk (0x1UL << GINTSTS_EOPF_Pos) // 0x00008000 +#define GINTSTS_EOPF GINTSTS_EOPF_Msk // End of periodic frame interrupt #define GINTSTS_IEPINT_Pos (18U) -#define GINTSTS_IEPINT_Msk (0x1UL << GINTSTS_IEPINT_Pos) // 0x00040000 */ -#define GINTSTS_IEPINT GINTSTS_IEPINT_Msk // IN endpoint interrupt */ +#define GINTSTS_IEPINT_Msk (0x1UL << GINTSTS_IEPINT_Pos) // 0x00040000 +#define GINTSTS_IEPINT GINTSTS_IEPINT_Msk // IN endpoint interrupt #define GINTSTS_OEPINT_Pos (19U) -#define GINTSTS_OEPINT_Msk (0x1UL << GINTSTS_OEPINT_Pos) // 0x00080000 */ -#define GINTSTS_OEPINT GINTSTS_OEPINT_Msk // OUT endpoint interrupt */ +#define GINTSTS_OEPINT_Msk (0x1UL << GINTSTS_OEPINT_Pos) // 0x00080000 +#define GINTSTS_OEPINT GINTSTS_OEPINT_Msk // OUT endpoint interrupt #define GINTSTS_IISOIXFR_Pos (20U) -#define GINTSTS_IISOIXFR_Msk (0x1UL << GINTSTS_IISOIXFR_Pos) // 0x00100000 */ -#define GINTSTS_IISOIXFR GINTSTS_IISOIXFR_Msk // Incomplete isochronous IN transfer */ +#define GINTSTS_IISOIXFR_Msk (0x1UL << GINTSTS_IISOIXFR_Pos) // 0x00100000 +#define GINTSTS_IISOIXFR GINTSTS_IISOIXFR_Msk // Incomplete isochronous IN transfer #define GINTSTS_PXFR_INCOMPISOOUT_Pos (21U) -#define GINTSTS_PXFR_INCOMPISOOUT_Msk (0x1UL << GINTSTS_PXFR_INCOMPISOOUT_Pos) // 0x00200000 */ -#define GINTSTS_PXFR_INCOMPISOOUT GINTSTS_PXFR_INCOMPISOOUT_Msk // Incomplete periodic transfer */ +#define GINTSTS_PXFR_INCOMPISOOUT_Msk (0x1UL << GINTSTS_PXFR_INCOMPISOOUT_Pos) // 0x00200000 +#define GINTSTS_PXFR_INCOMPISOOUT GINTSTS_PXFR_INCOMPISOOUT_Msk // Incomplete periodic transfer #define GINTSTS_DATAFSUSP_Pos (22U) -#define GINTSTS_DATAFSUSP_Msk (0x1UL << GINTSTS_DATAFSUSP_Pos) // 0x00400000 */ -#define GINTSTS_DATAFSUSP GINTSTS_DATAFSUSP_Msk // Data fetch suspended */ +#define GINTSTS_DATAFSUSP_Msk (0x1UL << GINTSTS_DATAFSUSP_Pos) // 0x00400000 +#define GINTSTS_DATAFSUSP GINTSTS_DATAFSUSP_Msk // Data fetch suspended #define GINTSTS_RSTDET_Pos (23U) -#define GINTSTS_RSTDET_Msk (0x1UL << GINTSTS_RSTDET_Pos) // 0x00800000 */ -#define GINTSTS_RSTDET GINTSTS_RSTDET_Msk // Reset detected interrupt */ +#define GINTSTS_RSTDET_Msk (0x1UL << GINTSTS_RSTDET_Pos) // 0x00800000 +#define GINTSTS_RSTDET GINTSTS_RSTDET_Msk // Reset detected interrupt #define GINTSTS_HPRTINT_Pos (24U) -#define GINTSTS_HPRTINT_Msk (0x1UL << GINTSTS_HPRTINT_Pos) // 0x01000000 */ -#define GINTSTS_HPRTINT GINTSTS_HPRTINT_Msk // Host port interrupt */ +#define GINTSTS_HPRTINT_Msk (0x1UL << GINTSTS_HPRTINT_Pos) // 0x01000000 +#define GINTSTS_HPRTINT GINTSTS_HPRTINT_Msk // Host port interrupt #define GINTSTS_HCINT_Pos (25U) -#define GINTSTS_HCINT_Msk (0x1UL << GINTSTS_HCINT_Pos) // 0x02000000 */ -#define GINTSTS_HCINT GINTSTS_HCINT_Msk // Host channels interrupt */ +#define GINTSTS_HCINT_Msk (0x1UL << GINTSTS_HCINT_Pos) // 0x02000000 +#define GINTSTS_HCINT GINTSTS_HCINT_Msk // Host channels interrupt #define GINTSTS_PTXFE_Pos (26U) -#define GINTSTS_PTXFE_Msk (0x1UL << GINTSTS_PTXFE_Pos) // 0x04000000 */ -#define GINTSTS_PTXFE GINTSTS_PTXFE_Msk // Periodic TxFIFO empty */ +#define GINTSTS_PTXFE_Msk (0x1UL << GINTSTS_PTXFE_Pos) // 0x04000000 +#define GINTSTS_PTXFE GINTSTS_PTXFE_Msk // Periodic TxFIFO empty #define GINTSTS_LPMINT_Pos (27U) -#define GINTSTS_LPMINT_Msk (0x1UL << GINTSTS_LPMINT_Pos) // 0x08000000 */ -#define GINTSTS_LPMINT GINTSTS_LPMINT_Msk // LPM interrupt */ +#define GINTSTS_LPMINT_Msk (0x1UL << GINTSTS_LPMINT_Pos) // 0x08000000 +#define GINTSTS_LPMINT GINTSTS_LPMINT_Msk // LPM interrupt #define GINTSTS_CIDSCHG_Pos (28U) -#define GINTSTS_CIDSCHG_Msk (0x1UL << GINTSTS_CIDSCHG_Pos) // 0x10000000 */ -#define GINTSTS_CIDSCHG GINTSTS_CIDSCHG_Msk // Connector ID status change */ +#define GINTSTS_CIDSCHG_Msk (0x1UL << GINTSTS_CIDSCHG_Pos) // 0x10000000 +#define GINTSTS_CIDSCHG GINTSTS_CIDSCHG_Msk // Connector ID status change #define GINTSTS_DISCINT_Pos (29U) -#define GINTSTS_DISCINT_Msk (0x1UL << GINTSTS_DISCINT_Pos) // 0x20000000 */ -#define GINTSTS_DISCINT GINTSTS_DISCINT_Msk // Disconnect detected interrupt */ +#define GINTSTS_DISCINT_Msk (0x1UL << GINTSTS_DISCINT_Pos) // 0x20000000 +#define GINTSTS_DISCINT GINTSTS_DISCINT_Msk // Disconnect detected interrupt #define GINTSTS_SRQINT_Pos (30U) -#define GINTSTS_SRQINT_Msk (0x1UL << GINTSTS_SRQINT_Pos) // 0x40000000 */ -#define GINTSTS_SRQINT GINTSTS_SRQINT_Msk // Session request/new session detected interrupt */ +#define GINTSTS_SRQINT_Msk (0x1UL << GINTSTS_SRQINT_Pos) // 0x40000000 +#define GINTSTS_SRQINT GINTSTS_SRQINT_Msk // Session request/new session detected interrupt #define GINTSTS_WKUINT_Pos (31U) -#define GINTSTS_WKUINT_Msk (0x1UL << GINTSTS_WKUINT_Pos) // 0x80000000 */ -#define GINTSTS_WKUINT GINTSTS_WKUINT_Msk // Resume/remote wakeup detected interrupt */ +#define GINTSTS_WKUINT_Msk (0x1UL << GINTSTS_WKUINT_Pos) // 0x80000000 +#define GINTSTS_WKUINT GINTSTS_WKUINT_Msk // Resume/remote wakeup detected interrupt /******************** Bit definition for GINTMSK register ********************/ #define GINTMSK_MMISM_Pos (1U) -#define GINTMSK_MMISM_Msk (0x1UL << GINTMSK_MMISM_Pos) // 0x00000002 */ -#define GINTMSK_MMISM GINTMSK_MMISM_Msk // Mode mismatch interrupt mask */ +#define GINTMSK_MMISM_Msk (0x1UL << GINTMSK_MMISM_Pos) // 0x00000002 +#define GINTMSK_MMISM GINTMSK_MMISM_Msk // Mode mismatch interrupt mask #define GINTMSK_OTGINT_Pos (2U) -#define GINTMSK_OTGINT_Msk (0x1UL << GINTMSK_OTGINT_Pos) // 0x00000004 */ -#define GINTMSK_OTGINT GINTMSK_OTGINT_Msk // OTG interrupt mask */ +#define GINTMSK_OTGINT_Msk (0x1UL << GINTMSK_OTGINT_Pos) // 0x00000004 +#define GINTMSK_OTGINT GINTMSK_OTGINT_Msk // OTG interrupt mask #define GINTMSK_SOFM_Pos (3U) -#define GINTMSK_SOFM_Msk (0x1UL << GINTMSK_SOFM_Pos) // 0x00000008 */ -#define GINTMSK_SOFM GINTMSK_SOFM_Msk // Start of frame mask */ +#define GINTMSK_SOFM_Msk (0x1UL << GINTMSK_SOFM_Pos) // 0x00000008 +#define GINTMSK_SOFM GINTMSK_SOFM_Msk // Start of frame mask #define GINTMSK_RXFLVLM_Pos (4U) -#define GINTMSK_RXFLVLM_Msk (0x1UL << GINTMSK_RXFLVLM_Pos) // 0x00000010 */ -#define GINTMSK_RXFLVLM GINTMSK_RXFLVLM_Msk // Receive FIFO nonempty mask */ +#define GINTMSK_RXFLVLM_Msk (0x1UL << GINTMSK_RXFLVLM_Pos) // 0x00000010 +#define GINTMSK_RXFLVLM GINTMSK_RXFLVLM_Msk // Receive FIFO nonempty mask #define GINTMSK_NPTXFEM_Pos (5U) -#define GINTMSK_NPTXFEM_Msk (0x1UL << GINTMSK_NPTXFEM_Pos) // 0x00000020 */ -#define GINTMSK_NPTXFEM GINTMSK_NPTXFEM_Msk // Nonperiodic TxFIFO empty mask */ +#define GINTMSK_NPTXFEM_Msk (0x1UL << GINTMSK_NPTXFEM_Pos) // 0x00000020 +#define GINTMSK_NPTXFEM GINTMSK_NPTXFEM_Msk // Nonperiodic TxFIFO empty mask #define GINTMSK_GINAKEFFM_Pos (6U) -#define GINTMSK_GINAKEFFM_Msk (0x1UL << GINTMSK_GINAKEFFM_Pos) // 0x00000040 */ -#define GINTMSK_GINAKEFFM GINTMSK_GINAKEFFM_Msk // Global nonperiodic IN NAK effective mask */ +#define GINTMSK_GINAKEFFM_Msk (0x1UL << GINTMSK_GINAKEFFM_Pos) // 0x00000040 +#define GINTMSK_GINAKEFFM GINTMSK_GINAKEFFM_Msk // Global nonperiodic IN NAK effective mask #define GINTMSK_GONAKEFFM_Pos (7U) -#define GINTMSK_GONAKEFFM_Msk (0x1UL << GINTMSK_GONAKEFFM_Pos) // 0x00000080 */ -#define GINTMSK_GONAKEFFM GINTMSK_GONAKEFFM_Msk // Global OUT NAK effective mask */ +#define GINTMSK_GONAKEFFM_Msk (0x1UL << GINTMSK_GONAKEFFM_Pos) // 0x00000080 +#define GINTMSK_GONAKEFFM GINTMSK_GONAKEFFM_Msk // Global OUT NAK effective mask #define GINTMSK_ESUSPM_Pos (10U) -#define GINTMSK_ESUSPM_Msk (0x1UL << GINTMSK_ESUSPM_Pos) // 0x00000400 */ -#define GINTMSK_ESUSPM GINTMSK_ESUSPM_Msk // Early suspend mask */ +#define GINTMSK_ESUSPM_Msk (0x1UL << GINTMSK_ESUSPM_Pos) // 0x00000400 +#define GINTMSK_ESUSPM GINTMSK_ESUSPM_Msk // Early suspend mask #define GINTMSK_USBSUSPM_Pos (11U) -#define GINTMSK_USBSUSPM_Msk (0x1UL << GINTMSK_USBSUSPM_Pos) // 0x00000800 */ -#define GINTMSK_USBSUSPM GINTMSK_USBSUSPM_Msk // USB suspend mask */ +#define GINTMSK_USBSUSPM_Msk (0x1UL << GINTMSK_USBSUSPM_Pos) // 0x00000800 +#define GINTMSK_USBSUSPM GINTMSK_USBSUSPM_Msk // USB suspend mask #define GINTMSK_USBRST_Pos (12U) -#define GINTMSK_USBRST_Msk (0x1UL << GINTMSK_USBRST_Pos) // 0x00001000 */ -#define GINTMSK_USBRST GINTMSK_USBRST_Msk // USB reset mask */ +#define GINTMSK_USBRST_Msk (0x1UL << GINTMSK_USBRST_Pos) // 0x00001000 +#define GINTMSK_USBRST GINTMSK_USBRST_Msk // USB reset mask #define GINTMSK_ENUMDNEM_Pos (13U) -#define GINTMSK_ENUMDNEM_Msk (0x1UL << GINTMSK_ENUMDNEM_Pos) // 0x00002000 */ -#define GINTMSK_ENUMDNEM GINTMSK_ENUMDNEM_Msk // Enumeration done mask */ +#define GINTMSK_ENUMDNEM_Msk (0x1UL << GINTMSK_ENUMDNEM_Pos) // 0x00002000 +#define GINTMSK_ENUMDNEM GINTMSK_ENUMDNEM_Msk // Enumeration done mask #define GINTMSK_ISOODRPM_Pos (14U) -#define GINTMSK_ISOODRPM_Msk (0x1UL << GINTMSK_ISOODRPM_Pos) // 0x00004000 */ -#define GINTMSK_ISOODRPM GINTMSK_ISOODRPM_Msk // Isochronous OUT packet dropped interrupt mask */ +#define GINTMSK_ISOODRPM_Msk (0x1UL << GINTMSK_ISOODRPM_Pos) // 0x00004000 +#define GINTMSK_ISOODRPM GINTMSK_ISOODRPM_Msk // Isochronous OUT packet dropped interrupt mask #define GINTMSK_EOPFM_Pos (15U) -#define GINTMSK_EOPFM_Msk (0x1UL << GINTMSK_EOPFM_Pos) // 0x00008000 */ -#define GINTMSK_EOPFM GINTMSK_EOPFM_Msk // End of periodic frame interrupt mask */ +#define GINTMSK_EOPFM_Msk (0x1UL << GINTMSK_EOPFM_Pos) // 0x00008000 +#define GINTMSK_EOPFM GINTMSK_EOPFM_Msk // End of periodic frame interrupt mask #define GINTMSK_EPMISM_Pos (17U) -#define GINTMSK_EPMISM_Msk (0x1UL << GINTMSK_EPMISM_Pos) // 0x00020000 */ -#define GINTMSK_EPMISM GINTMSK_EPMISM_Msk // Endpoint mismatch interrupt mask */ +#define GINTMSK_EPMISM_Msk (0x1UL << GINTMSK_EPMISM_Pos) // 0x00020000 +#define GINTMSK_EPMISM GINTMSK_EPMISM_Msk // Endpoint mismatch interrupt mask #define GINTMSK_IEPINT_Pos (18U) -#define GINTMSK_IEPINT_Msk (0x1UL << GINTMSK_IEPINT_Pos) // 0x00040000 */ -#define GINTMSK_IEPINT GINTMSK_IEPINT_Msk // IN endpoints interrupt mask */ +#define GINTMSK_IEPINT_Msk (0x1UL << GINTMSK_IEPINT_Pos) // 0x00040000 +#define GINTMSK_IEPINT GINTMSK_IEPINT_Msk // IN endpoints interrupt mask #define GINTMSK_OEPINT_Pos (19U) -#define GINTMSK_OEPINT_Msk (0x1UL << GINTMSK_OEPINT_Pos) // 0x00080000 */ -#define GINTMSK_OEPINT GINTMSK_OEPINT_Msk // OUT endpoints interrupt mask */ +#define GINTMSK_OEPINT_Msk (0x1UL << GINTMSK_OEPINT_Pos) // 0x00080000 +#define GINTMSK_OEPINT GINTMSK_OEPINT_Msk // OUT endpoints interrupt mask #define GINTMSK_IISOIXFRM_Pos (20U) -#define GINTMSK_IISOIXFRM_Msk (0x1UL << GINTMSK_IISOIXFRM_Pos) // 0x00100000 */ -#define GINTMSK_IISOIXFRM GINTMSK_IISOIXFRM_Msk // Incomplete isochronous IN transfer mask */ +#define GINTMSK_IISOIXFRM_Msk (0x1UL << GINTMSK_IISOIXFRM_Pos) // 0x00100000 +#define GINTMSK_IISOIXFRM GINTMSK_IISOIXFRM_Msk // Incomplete isochronous IN transfer mask #define GINTMSK_PXFRM_IISOOXFRM_Pos (21U) -#define GINTMSK_PXFRM_IISOOXFRM_Msk (0x1UL << GINTMSK_PXFRM_IISOOXFRM_Pos) // 0x00200000 */ -#define GINTMSK_PXFRM_IISOOXFRM GINTMSK_PXFRM_IISOOXFRM_Msk // Incomplete periodic transfer mask */ +#define GINTMSK_PXFRM_IISOOXFRM_Msk (0x1UL << GINTMSK_PXFRM_IISOOXFRM_Pos) // 0x00200000 +#define GINTMSK_PXFRM_IISOOXFRM GINTMSK_PXFRM_IISOOXFRM_Msk // Incomplete periodic transfer mask #define GINTMSK_FSUSPM_Pos (22U) -#define GINTMSK_FSUSPM_Msk (0x1UL << GINTMSK_FSUSPM_Pos) // 0x00400000 */ -#define GINTMSK_FSUSPM GINTMSK_FSUSPM_Msk // Data fetch suspended mask */ +#define GINTMSK_FSUSPM_Msk (0x1UL << GINTMSK_FSUSPM_Pos) // 0x00400000 +#define GINTMSK_FSUSPM GINTMSK_FSUSPM_Msk // Data fetch suspended mask #define GINTMSK_RSTDEM_Pos (23U) -#define GINTMSK_RSTDEM_Msk (0x1UL << GINTMSK_RSTDEM_Pos) // 0x00800000 */ -#define GINTMSK_RSTDEM GINTMSK_RSTDEM_Msk // Reset detected interrupt mask */ +#define GINTMSK_RSTDEM_Msk (0x1UL << GINTMSK_RSTDEM_Pos) // 0x00800000 +#define GINTMSK_RSTDEM GINTMSK_RSTDEM_Msk // Reset detected interrupt mask #define GINTMSK_PRTIM_Pos (24U) -#define GINTMSK_PRTIM_Msk (0x1UL << GINTMSK_PRTIM_Pos) // 0x01000000 */ -#define GINTMSK_PRTIM GINTMSK_PRTIM_Msk // Host port interrupt mask */ +#define GINTMSK_PRTIM_Msk (0x1UL << GINTMSK_PRTIM_Pos) // 0x01000000 +#define GINTMSK_PRTIM GINTMSK_PRTIM_Msk // Host port interrupt mask #define GINTMSK_HCIM_Pos (25U) -#define GINTMSK_HCIM_Msk (0x1UL << GINTMSK_HCIM_Pos) // 0x02000000 */ -#define GINTMSK_HCIM GINTMSK_HCIM_Msk // Host channels interrupt mask */ +#define GINTMSK_HCIM_Msk (0x1UL << GINTMSK_HCIM_Pos) // 0x02000000 +#define GINTMSK_HCIM GINTMSK_HCIM_Msk // Host channels interrupt mask #define GINTMSK_PTXFEM_Pos (26U) -#define GINTMSK_PTXFEM_Msk (0x1UL << GINTMSK_PTXFEM_Pos) // 0x04000000 */ -#define GINTMSK_PTXFEM GINTMSK_PTXFEM_Msk // Periodic TxFIFO empty mask */ +#define GINTMSK_PTXFEM_Msk (0x1UL << GINTMSK_PTXFEM_Pos) // 0x04000000 +#define GINTMSK_PTXFEM GINTMSK_PTXFEM_Msk // Periodic TxFIFO empty mask #define GINTMSK_LPMINTM_Pos (27U) -#define GINTMSK_LPMINTM_Msk (0x1UL << GINTMSK_LPMINTM_Pos) // 0x08000000 */ -#define GINTMSK_LPMINTM GINTMSK_LPMINTM_Msk // LPM interrupt Mask */ +#define GINTMSK_LPMINTM_Msk (0x1UL << GINTMSK_LPMINTM_Pos) // 0x08000000 +#define GINTMSK_LPMINTM GINTMSK_LPMINTM_Msk // LPM interrupt Mask #define GINTMSK_CIDSCHGM_Pos (28U) -#define GINTMSK_CIDSCHGM_Msk (0x1UL << GINTMSK_CIDSCHGM_Pos) // 0x10000000 */ -#define GINTMSK_CIDSCHGM GINTMSK_CIDSCHGM_Msk // Connector ID status change mask */ +#define GINTMSK_CIDSCHGM_Msk (0x1UL << GINTMSK_CIDSCHGM_Pos) // 0x10000000 +#define GINTMSK_CIDSCHGM GINTMSK_CIDSCHGM_Msk // Connector ID status change mask #define GINTMSK_DISCINT_Pos (29U) -#define GINTMSK_DISCINT_Msk (0x1UL << GINTMSK_DISCINT_Pos) // 0x20000000 */ -#define GINTMSK_DISCINT GINTMSK_DISCINT_Msk // Disconnect detected interrupt mask */ +#define GINTMSK_DISCINT_Msk (0x1UL << GINTMSK_DISCINT_Pos) // 0x20000000 +#define GINTMSK_DISCINT GINTMSK_DISCINT_Msk // Disconnect detected interrupt mask #define GINTMSK_SRQIM_Pos (30U) -#define GINTMSK_SRQIM_Msk (0x1UL << GINTMSK_SRQIM_Pos) // 0x40000000 */ -#define GINTMSK_SRQIM GINTMSK_SRQIM_Msk // Session request/new session detected interrupt mask */ +#define GINTMSK_SRQIM_Msk (0x1UL << GINTMSK_SRQIM_Pos) // 0x40000000 +#define GINTMSK_SRQIM GINTMSK_SRQIM_Msk // Session request/new session detected interrupt mask #define GINTMSK_WUIM_Pos (31U) -#define GINTMSK_WUIM_Msk (0x1UL << GINTMSK_WUIM_Pos) // 0x80000000 */ -#define GINTMSK_WUIM GINTMSK_WUIM_Msk // Resume/remote wakeup detected interrupt mask */ +#define GINTMSK_WUIM_Msk (0x1UL << GINTMSK_WUIM_Pos) // 0x80000000 +#define GINTMSK_WUIM GINTMSK_WUIM_Msk // Resume/remote wakeup detected interrupt mask /******************** Bit definition for DAINT register ********************/ #define DAINT_IEPINT_Pos (0U) -#define DAINT_IEPINT_Msk (0xFFFFUL << DAINT_IEPINT_Pos) // 0x0000FFFF */ -#define DAINT_IEPINT DAINT_IEPINT_Msk // IN endpoint interrupt bits */ +#define DAINT_IEPINT_Msk (0xFFFFUL << DAINT_IEPINT_Pos) // 0x0000FFFF +#define DAINT_IEPINT DAINT_IEPINT_Msk // IN endpoint interrupt bits #define DAINT_OEPINT_Pos (16U) -#define DAINT_OEPINT_Msk (0xFFFFUL << DAINT_OEPINT_Pos) // 0xFFFF0000 */ -#define DAINT_OEPINT DAINT_OEPINT_Msk // OUT endpoint interrupt bits */ +#define DAINT_OEPINT_Msk (0xFFFFUL << DAINT_OEPINT_Pos) // 0xFFFF0000 +#define DAINT_OEPINT DAINT_OEPINT_Msk // OUT endpoint interrupt bits /******************** Bit definition for HAINTMSK register ********************/ #define HAINTMSK_HAINTM_Pos (0U) -#define HAINTMSK_HAINTM_Msk (0xFFFFUL << HAINTMSK_HAINTM_Pos) // 0x0000FFFF */ -#define HAINTMSK_HAINTM HAINTMSK_HAINTM_Msk // Channel interrupt mask */ +#define HAINTMSK_HAINTM_Msk (0xFFFFUL << HAINTMSK_HAINTM_Pos) // 0x0000FFFF +#define HAINTMSK_HAINTM HAINTMSK_HAINTM_Msk // Channel interrupt mask /******************** Bit definition for GRXSTSP register ********************/ #define GRXSTSP_EPNUM_Pos (0U) -#define GRXSTSP_EPNUM_Msk (0xFUL << GRXSTSP_EPNUM_Pos) // 0x0000000F */ -#define GRXSTSP_EPNUM GRXSTSP_EPNUM_Msk // IN EP interrupt mask bits */ +#define GRXSTSP_EPNUM_Msk (0xFUL << GRXSTSP_EPNUM_Pos) // 0x0000000F +#define GRXSTSP_EPNUM GRXSTSP_EPNUM_Msk // IN EP interrupt mask bits #define GRXSTSP_BCNT_Pos (4U) -#define GRXSTSP_BCNT_Msk (0x7FFUL << GRXSTSP_BCNT_Pos) // 0x00007FF0 */ -#define GRXSTSP_BCNT GRXSTSP_BCNT_Msk // OUT EP interrupt mask bits */ +#define GRXSTSP_BCNT_Msk (0x7FFUL << GRXSTSP_BCNT_Pos) // 0x00007FF0 +#define GRXSTSP_BCNT GRXSTSP_BCNT_Msk // OUT EP interrupt mask bits #define GRXSTSP_DPID_Pos (15U) -#define GRXSTSP_DPID_Msk (0x3UL << GRXSTSP_DPID_Pos) // 0x00018000 */ -#define GRXSTSP_DPID GRXSTSP_DPID_Msk // OUT EP interrupt mask bits */ +#define GRXSTSP_DPID_Msk (0x3UL << GRXSTSP_DPID_Pos) // 0x00018000 +#define GRXSTSP_DPID GRXSTSP_DPID_Msk // OUT EP interrupt mask bits #define GRXSTSP_PKTSTS_Pos (17U) -#define GRXSTSP_PKTSTS_Msk (0xFUL << GRXSTSP_PKTSTS_Pos) // 0x001E0000 */ -#define GRXSTSP_PKTSTS GRXSTSP_PKTSTS_Msk // OUT EP interrupt mask bits */ +#define GRXSTSP_PKTSTS_Msk (0xFUL << GRXSTSP_PKTSTS_Pos) // 0x001E0000 +#define GRXSTSP_PKTSTS GRXSTSP_PKTSTS_Msk // OUT EP interrupt mask bits #define GRXSTS_PKTSTS_GLOBALOUTNAK 1 #define GRXSTS_PKTSTS_OUTRX 2 @@ -933,773 +934,803 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); /******************** Bit definition for DAINTMSK register ********************/ #define DAINTMSK_IEPM_Pos (0U) -#define DAINTMSK_IEPM_Msk (0xFFFFUL << DAINTMSK_IEPM_Pos) // 0x0000FFFF */ -#define DAINTMSK_IEPM DAINTMSK_IEPM_Msk // IN EP interrupt mask bits */ +#define DAINTMSK_IEPM_Msk (0xFFFFUL << DAINTMSK_IEPM_Pos) // 0x0000FFFF +#define DAINTMSK_IEPM DAINTMSK_IEPM_Msk // IN EP interrupt mask bits #define DAINTMSK_OEPM_Pos (16U) -#define DAINTMSK_OEPM_Msk (0xFFFFUL << DAINTMSK_OEPM_Pos) // 0xFFFF0000 */ -#define DAINTMSK_OEPM DAINTMSK_OEPM_Msk // OUT EP interrupt mask bits */ +#define DAINTMSK_OEPM_Msk (0xFFFFUL << DAINTMSK_OEPM_Pos) // 0xFFFF0000 +#define DAINTMSK_OEPM DAINTMSK_OEPM_Msk // OUT EP interrupt mask bits #if 0 /******************** Bit definition for OTG register ********************/ #define CHNUM_Pos (0U) -#define CHNUM_Msk (0xFUL << CHNUM_Pos) // 0x0000000F */ -#define CHNUM CHNUM_Msk // Channel number */ -#define CHNUM_0 (0x1UL << CHNUM_Pos) // 0x00000001 */ -#define CHNUM_1 (0x2UL << CHNUM_Pos) // 0x00000002 */ -#define CHNUM_2 (0x4UL << CHNUM_Pos) // 0x00000004 */ -#define CHNUM_3 (0x8UL << CHNUM_Pos) // 0x00000008 */ +#define CHNUM_Msk (0xFUL << CHNUM_Pos) // 0x0000000F +#define CHNUM CHNUM_Msk // Channel number +#define CHNUM_0 (0x1UL << CHNUM_Pos) // 0x00000001 +#define CHNUM_1 (0x2UL << CHNUM_Pos) // 0x00000002 +#define CHNUM_2 (0x4UL << CHNUM_Pos) // 0x00000004 +#define CHNUM_3 (0x8UL << CHNUM_Pos) // 0x00000008 #define BCNT_Pos (4U) -#define BCNT_Msk (0x7FFUL << BCNT_Pos) // 0x00007FF0 */ -#define BCNT BCNT_Msk // Byte count */ +#define BCNT_Msk (0x7FFUL << BCNT_Pos) // 0x00007FF0 +#define BCNT BCNT_Msk // Byte count #define DPID_Pos (15U) -#define DPID_Msk (0x3UL << DPID_Pos) // 0x00018000 */ -#define DPID DPID_Msk // Data PID */ -#define DPID_0 (0x1UL << DPID_Pos) // 0x00008000 */ -#define DPID_1 (0x2UL << DPID_Pos) // 0x00010000 */ +#define DPID_Msk (0x3UL << DPID_Pos) // 0x00018000 +#define DPID DPID_Msk // Data PID +#define DPID_0 (0x1UL << DPID_Pos) // 0x00008000 +#define DPID_1 (0x2UL << DPID_Pos) // 0x00010000 #define PKTSTS_Pos (17U) -#define PKTSTS_Msk (0xFUL << PKTSTS_Pos) // 0x001E0000 */ -#define PKTSTS PKTSTS_Msk // Packet status */ -#define PKTSTS_0 (0x1UL << PKTSTS_Pos) // 0x00020000 */ -#define PKTSTS_1 (0x2UL << PKTSTS_Pos) // 0x00040000 */ -#define PKTSTS_2 (0x4UL << PKTSTS_Pos) // 0x00080000 */ -#define PKTSTS_3 (0x8UL << PKTSTS_Pos) // 0x00100000 */ +#define PKTSTS_Msk (0xFUL << PKTSTS_Pos) // 0x001E0000 +#define PKTSTS PKTSTS_Msk // Packet status +#define PKTSTS_0 (0x1UL << PKTSTS_Pos) // 0x00020000 +#define PKTSTS_1 (0x2UL << PKTSTS_Pos) // 0x00040000 +#define PKTSTS_2 (0x4UL << PKTSTS_Pos) // 0x00080000 +#define PKTSTS_3 (0x8UL << PKTSTS_Pos) // 0x00100000 #define EPNUM_Pos (0U) -#define EPNUM_Msk (0xFUL << EPNUM_Pos) // 0x0000000F */ -#define EPNUM EPNUM_Msk // Endpoint number */ -#define EPNUM_0 (0x1UL << EPNUM_Pos) // 0x00000001 */ -#define EPNUM_1 (0x2UL << EPNUM_Pos) // 0x00000002 */ -#define EPNUM_2 (0x4UL << EPNUM_Pos) // 0x00000004 */ -#define EPNUM_3 (0x8UL << EPNUM_Pos) // 0x00000008 */ +#define EPNUM_Msk (0xFUL << EPNUM_Pos) // 0x0000000F +#define EPNUM EPNUM_Msk // Endpoint number +#define EPNUM_0 (0x1UL << EPNUM_Pos) // 0x00000001 +#define EPNUM_1 (0x2UL << EPNUM_Pos) // 0x00000002 +#define EPNUM_2 (0x4UL << EPNUM_Pos) // 0x00000004 +#define EPNUM_3 (0x8UL << EPNUM_Pos) // 0x00000008 #define FRMNUM_Pos (21U) -#define FRMNUM_Msk (0xFUL << FRMNUM_Pos) // 0x01E00000 */ -#define FRMNUM FRMNUM_Msk // Frame number */ -#define FRMNUM_0 (0x1UL << FRMNUM_Pos) // 0x00200000 */ -#define FRMNUM_1 (0x2UL << FRMNUM_Pos) // 0x00400000 */ -#define FRMNUM_2 (0x4UL << FRMNUM_Pos) // 0x00800000 */ -#define FRMNUM_3 (0x8UL << FRMNUM_Pos) // 0x01000000 */ +#define FRMNUM_Msk (0xFUL << FRMNUM_Pos) // 0x01E00000 +#define FRMNUM FRMNUM_Msk // Frame number +#define FRMNUM_0 (0x1UL << FRMNUM_Pos) // 0x00200000 +#define FRMNUM_1 (0x2UL << FRMNUM_Pos) // 0x00400000 +#define FRMNUM_2 (0x4UL << FRMNUM_Pos) // 0x00800000 +#define FRMNUM_3 (0x8UL << FRMNUM_Pos) // 0x01000000 #endif /******************** Bit definition for GRXFSIZ register ********************/ #define GRXFSIZ_RXFD_Pos (0U) -#define GRXFSIZ_RXFD_Msk (0xFFFFUL << GRXFSIZ_RXFD_Pos) // 0x0000FFFF */ -#define GRXFSIZ_RXFD GRXFSIZ_RXFD_Msk // RxFIFO depth */ +#define GRXFSIZ_RXFD_Msk (0xFFFFUL << GRXFSIZ_RXFD_Pos) // 0x0000FFFF +#define GRXFSIZ_RXFD GRXFSIZ_RXFD_Msk // RxFIFO depth /******************** Bit definition for DVBUSDIS register ********************/ #define DVBUSDIS_VBUSDT_Pos (0U) -#define DVBUSDIS_VBUSDT_Msk (0xFFFFUL << DVBUSDIS_VBUSDT_Pos) // 0x0000FFFF */ -#define DVBUSDIS_VBUSDT DVBUSDIS_VBUSDT_Msk // Device VBUS discharge time */ +#define DVBUSDIS_VBUSDT_Msk (0xFFFFUL << DVBUSDIS_VBUSDT_Pos) // 0x0000FFFF +#define DVBUSDIS_VBUSDT DVBUSDIS_VBUSDT_Msk // Device VBUS discharge time /******************** Bit definition for OTG register ********************/ #define GNPTXFSIZ_NPTXFSA_Pos (0U) -#define GNPTXFSIZ_NPTXFSA_Msk (0xFFFFUL << GNPTXFSIZ_NPTXFSA_Pos) // 0x0000FFFF */ -#define GNPTXFSIZ_NPTXFSA GNPTXFSIZ_NPTXFSA_Msk // Nonperiodic transmit RAM start address */ +#define GNPTXFSIZ_NPTXFSA_Msk (0xFFFFUL << GNPTXFSIZ_NPTXFSA_Pos) // 0x0000FFFF +#define GNPTXFSIZ_NPTXFSA GNPTXFSIZ_NPTXFSA_Msk // Nonperiodic transmit RAM start address #define GNPTXFSIZ_NPTXFD_Pos (16U) -#define GNPTXFSIZ_NPTXFD_Msk (0xFFFFUL << GNPTXFSIZ_NPTXFD_Pos) // 0xFFFF0000 */ -#define GNPTXFSIZ_NPTXFD GNPTXFSIZ_NPTXFD_Msk // Nonperiodic TxFIFO depth */ +#define GNPTXFSIZ_NPTXFD_Msk (0xFFFFUL << GNPTXFSIZ_NPTXFD_Pos) // 0xFFFF0000 +#define GNPTXFSIZ_NPTXFD GNPTXFSIZ_NPTXFD_Msk // Nonperiodic TxFIFO depth #define DIEPTXF0_TX0FSA_Pos (0U) -#define DIEPTXF0_TX0FSA_Msk (0xFFFFUL << DIEPTXF0_TX0FSA_Pos) // 0x0000FFFF */ -#define DIEPTXF0_TX0FSA DIEPTXF0_TX0FSA_Msk // Endpoint 0 transmit RAM start address */ +#define DIEPTXF0_TX0FSA_Msk (0xFFFFUL << DIEPTXF0_TX0FSA_Pos) // 0x0000FFFF +#define DIEPTXF0_TX0FSA DIEPTXF0_TX0FSA_Msk // Endpoint 0 transmit RAM start address #define DIEPTXF0_TX0FD_Pos (16U) -#define DIEPTXF0_TX0FD_Msk (0xFFFFUL << DIEPTXF0_TX0FD_Pos) // 0xFFFF0000 */ -#define DIEPTXF0_TX0FD DIEPTXF0_TX0FD_Msk // Endpoint 0 TxFIFO depth */ +#define DIEPTXF0_TX0FD_Msk (0xFFFFUL << DIEPTXF0_TX0FD_Pos) // 0xFFFF0000 +#define DIEPTXF0_TX0FD DIEPTXF0_TX0FD_Msk // Endpoint 0 TxFIFO depth /******************** Bit definition for DVBUSPULSE register ********************/ #define DVBUSPULSE_DVBUSP_Pos (0U) -#define DVBUSPULSE_DVBUSP_Msk (0xFFFUL << DVBUSPULSE_DVBUSP_Pos) // 0x00000FFF */ -#define DVBUSPULSE_DVBUSP DVBUSPULSE_DVBUSP_Msk // Device VBUS pulsing time */ +#define DVBUSPULSE_DVBUSP_Msk (0xFFFUL << DVBUSPULSE_DVBUSP_Pos) // 0x00000FFF +#define DVBUSPULSE_DVBUSP DVBUSPULSE_DVBUSP_Msk // Device VBUS pulsing time /******************** Bit definition for GNPTXSTS register ********************/ #define GNPTXSTS_NPTXFSAV_Pos (0U) -#define GNPTXSTS_NPTXFSAV_Msk (0xFFFFUL << GNPTXSTS_NPTXFSAV_Pos) // 0x0000FFFF */ -#define GNPTXSTS_NPTXFSAV GNPTXSTS_NPTXFSAV_Msk // Nonperiodic TxFIFO space available */ +#define GNPTXSTS_NPTXFSAV_Msk (0xFFFFUL << GNPTXSTS_NPTXFSAV_Pos) // 0x0000FFFF +#define GNPTXSTS_NPTXFSAV GNPTXSTS_NPTXFSAV_Msk // Nonperiodic TxFIFO space available #define GNPTXSTS_NPTQXSAV_Pos (16U) -#define GNPTXSTS_NPTQXSAV_Msk (0xFFUL << GNPTXSTS_NPTQXSAV_Pos) // 0x00FF0000 */ -#define GNPTXSTS_NPTQXSAV GNPTXSTS_NPTQXSAV_Msk // Nonperiodic transmit request queue space available */ -#define GNPTXSTS_NPTQXSAV_0 (0x01UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00010000 */ -#define GNPTXSTS_NPTQXSAV_1 (0x02UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00020000 */ -#define GNPTXSTS_NPTQXSAV_2 (0x04UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00040000 */ -#define GNPTXSTS_NPTQXSAV_3 (0x08UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00080000 */ -#define GNPTXSTS_NPTQXSAV_4 (0x10UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00100000 */ -#define GNPTXSTS_NPTQXSAV_5 (0x20UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00200000 */ -#define GNPTXSTS_NPTQXSAV_6 (0x40UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00400000 */ -#define GNPTXSTS_NPTQXSAV_7 (0x80UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00800000 */ +#define GNPTXSTS_NPTQXSAV_Msk (0xFFUL << GNPTXSTS_NPTQXSAV_Pos) // 0x00FF0000 +#define GNPTXSTS_NPTQXSAV GNPTXSTS_NPTQXSAV_Msk // Nonperiodic transmit request queue space available +#define GNPTXSTS_NPTQXSAV_0 (0x01UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00010000 +#define GNPTXSTS_NPTQXSAV_1 (0x02UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00020000 +#define GNPTXSTS_NPTQXSAV_2 (0x04UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00040000 +#define GNPTXSTS_NPTQXSAV_3 (0x08UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00080000 +#define GNPTXSTS_NPTQXSAV_4 (0x10UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00100000 +#define GNPTXSTS_NPTQXSAV_5 (0x20UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00200000 +#define GNPTXSTS_NPTQXSAV_6 (0x40UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00400000 +#define GNPTXSTS_NPTQXSAV_7 (0x80UL << GNPTXSTS_NPTQXSAV_Pos) // 0x00800000 #define GNPTXSTS_NPTXQTOP_Pos (24U) -#define GNPTXSTS_NPTXQTOP_Msk (0x7FUL << GNPTXSTS_NPTXQTOP_Pos) // 0x7F000000 */ -#define GNPTXSTS_NPTXQTOP GNPTXSTS_NPTXQTOP_Msk // Top of the nonperiodic transmit request queue */ -#define GNPTXSTS_NPTXQTOP_0 (0x01UL << GNPTXSTS_NPTXQTOP_Pos) // 0x01000000 */ -#define GNPTXSTS_NPTXQTOP_1 (0x02UL << GNPTXSTS_NPTXQTOP_Pos) // 0x02000000 */ -#define GNPTXSTS_NPTXQTOP_2 (0x04UL << GNPTXSTS_NPTXQTOP_Pos) // 0x04000000 */ -#define GNPTXSTS_NPTXQTOP_3 (0x08UL << GNPTXSTS_NPTXQTOP_Pos) // 0x08000000 */ -#define GNPTXSTS_NPTXQTOP_4 (0x10UL << GNPTXSTS_NPTXQTOP_Pos) // 0x10000000 */ -#define GNPTXSTS_NPTXQTOP_5 (0x20UL << GNPTXSTS_NPTXQTOP_Pos) // 0x20000000 */ -#define GNPTXSTS_NPTXQTOP_6 (0x40UL << GNPTXSTS_NPTXQTOP_Pos) // 0x40000000 */ +#define GNPTXSTS_NPTXQTOP_Msk (0x7FUL << GNPTXSTS_NPTXQTOP_Pos) // 0x7F000000 +#define GNPTXSTS_NPTXQTOP GNPTXSTS_NPTXQTOP_Msk // Top of the nonperiodic transmit request queue +#define GNPTXSTS_NPTXQTOP_0 (0x01UL << GNPTXSTS_NPTXQTOP_Pos) // 0x01000000 +#define GNPTXSTS_NPTXQTOP_1 (0x02UL << GNPTXSTS_NPTXQTOP_Pos) // 0x02000000 +#define GNPTXSTS_NPTXQTOP_2 (0x04UL << GNPTXSTS_NPTXQTOP_Pos) // 0x04000000 +#define GNPTXSTS_NPTXQTOP_3 (0x08UL << GNPTXSTS_NPTXQTOP_Pos) // 0x08000000 +#define GNPTXSTS_NPTXQTOP_4 (0x10UL << GNPTXSTS_NPTXQTOP_Pos) // 0x10000000 +#define GNPTXSTS_NPTXQTOP_5 (0x20UL << GNPTXSTS_NPTXQTOP_Pos) // 0x20000000 +#define GNPTXSTS_NPTXQTOP_6 (0x40UL << GNPTXSTS_NPTXQTOP_Pos) // 0x40000000 /******************** Bit definition for DTHRCTL register ********************/ #define DTHRCTL_NONISOTHREN_Pos (0U) -#define DTHRCTL_NONISOTHREN_Msk (0x1UL << DTHRCTL_NONISOTHREN_Pos) // 0x00000001 */ -#define DTHRCTL_NONISOTHREN DTHRCTL_NONISOTHREN_Msk // Nonisochronous IN endpoints threshold enable */ +#define DTHRCTL_NONISOTHREN_Msk (0x1UL << DTHRCTL_NONISOTHREN_Pos) // 0x00000001 +#define DTHRCTL_NONISOTHREN DTHRCTL_NONISOTHREN_Msk // Nonisochronous IN endpoints threshold enable #define DTHRCTL_ISOTHREN_Pos (1U) -#define DTHRCTL_ISOTHREN_Msk (0x1UL << DTHRCTL_ISOTHREN_Pos) // 0x00000002 */ -#define DTHRCTL_ISOTHREN DTHRCTL_ISOTHREN_Msk // ISO IN endpoint threshold enable */ +#define DTHRCTL_ISOTHREN_Msk (0x1UL << DTHRCTL_ISOTHREN_Pos) // 0x00000002 +#define DTHRCTL_ISOTHREN DTHRCTL_ISOTHREN_Msk // ISO IN endpoint threshold enable #define DTHRCTL_TXTHRLEN_Pos (2U) -#define DTHRCTL_TXTHRLEN_Msk (0x1FFUL << DTHRCTL_TXTHRLEN_Pos) // 0x000007FC */ -#define DTHRCTL_TXTHRLEN DTHRCTL_TXTHRLEN_Msk // Transmit threshold length */ -#define DTHRCTL_TXTHRLEN_0 (0x001UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000004 */ -#define DTHRCTL_TXTHRLEN_1 (0x002UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000008 */ -#define DTHRCTL_TXTHRLEN_2 (0x004UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000010 */ -#define DTHRCTL_TXTHRLEN_3 (0x008UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000020 */ -#define DTHRCTL_TXTHRLEN_4 (0x010UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000040 */ -#define DTHRCTL_TXTHRLEN_5 (0x020UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000080 */ -#define DTHRCTL_TXTHRLEN_6 (0x040UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000100 */ -#define DTHRCTL_TXTHRLEN_7 (0x080UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000200 */ -#define DTHRCTL_TXTHRLEN_8 (0x100UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000400 */ +#define DTHRCTL_TXTHRLEN_Msk (0x1FFUL << DTHRCTL_TXTHRLEN_Pos) // 0x000007FC +#define DTHRCTL_TXTHRLEN DTHRCTL_TXTHRLEN_Msk // Transmit threshold length +#define DTHRCTL_TXTHRLEN_0 (0x001UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000004 +#define DTHRCTL_TXTHRLEN_1 (0x002UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000008 +#define DTHRCTL_TXTHRLEN_2 (0x004UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000010 +#define DTHRCTL_TXTHRLEN_3 (0x008UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000020 +#define DTHRCTL_TXTHRLEN_4 (0x010UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000040 +#define DTHRCTL_TXTHRLEN_5 (0x020UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000080 +#define DTHRCTL_TXTHRLEN_6 (0x040UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000100 +#define DTHRCTL_TXTHRLEN_7 (0x080UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000200 +#define DTHRCTL_TXTHRLEN_8 (0x100UL << DTHRCTL_TXTHRLEN_Pos) // 0x00000400 #define DTHRCTL_RXTHREN_Pos (16U) -#define DTHRCTL_RXTHREN_Msk (0x1UL << DTHRCTL_RXTHREN_Pos) // 0x00010000 */ -#define DTHRCTL_RXTHREN DTHRCTL_RXTHREN_Msk // Receive threshold enable */ +#define DTHRCTL_RXTHREN_Msk (0x1UL << DTHRCTL_RXTHREN_Pos) // 0x00010000 +#define DTHRCTL_RXTHREN DTHRCTL_RXTHREN_Msk // Receive threshold enable #define DTHRCTL_RXTHRLEN_Pos (17U) -#define DTHRCTL_RXTHRLEN_Msk (0x1FFUL << DTHRCTL_RXTHRLEN_Pos) // 0x03FE0000 */ -#define DTHRCTL_RXTHRLEN DTHRCTL_RXTHRLEN_Msk // Receive threshold length */ -#define DTHRCTL_RXTHRLEN_0 (0x001UL << DTHRCTL_RXTHRLEN_Pos) // 0x00020000 */ -#define DTHRCTL_RXTHRLEN_1 (0x002UL << DTHRCTL_RXTHRLEN_Pos) // 0x00040000 */ -#define DTHRCTL_RXTHRLEN_2 (0x004UL << DTHRCTL_RXTHRLEN_Pos) // 0x00080000 */ -#define DTHRCTL_RXTHRLEN_3 (0x008UL << DTHRCTL_RXTHRLEN_Pos) // 0x00100000 */ -#define DTHRCTL_RXTHRLEN_4 (0x010UL << DTHRCTL_RXTHRLEN_Pos) // 0x00200000 */ -#define DTHRCTL_RXTHRLEN_5 (0x020UL << DTHRCTL_RXTHRLEN_Pos) // 0x00400000 */ -#define DTHRCTL_RXTHRLEN_6 (0x040UL << DTHRCTL_RXTHRLEN_Pos) // 0x00800000 */ -#define DTHRCTL_RXTHRLEN_7 (0x080UL << DTHRCTL_RXTHRLEN_Pos) // 0x01000000 */ -#define DTHRCTL_RXTHRLEN_8 (0x100UL << DTHRCTL_RXTHRLEN_Pos) // 0x02000000 */ +#define DTHRCTL_RXTHRLEN_Msk (0x1FFUL << DTHRCTL_RXTHRLEN_Pos) // 0x03FE0000 +#define DTHRCTL_RXTHRLEN DTHRCTL_RXTHRLEN_Msk // Receive threshold length +#define DTHRCTL_RXTHRLEN_0 (0x001UL << DTHRCTL_RXTHRLEN_Pos) // 0x00020000 +#define DTHRCTL_RXTHRLEN_1 (0x002UL << DTHRCTL_RXTHRLEN_Pos) // 0x00040000 +#define DTHRCTL_RXTHRLEN_2 (0x004UL << DTHRCTL_RXTHRLEN_Pos) // 0x00080000 +#define DTHRCTL_RXTHRLEN_3 (0x008UL << DTHRCTL_RXTHRLEN_Pos) // 0x00100000 +#define DTHRCTL_RXTHRLEN_4 (0x010UL << DTHRCTL_RXTHRLEN_Pos) // 0x00200000 +#define DTHRCTL_RXTHRLEN_5 (0x020UL << DTHRCTL_RXTHRLEN_Pos) // 0x00400000 +#define DTHRCTL_RXTHRLEN_6 (0x040UL << DTHRCTL_RXTHRLEN_Pos) // 0x00800000 +#define DTHRCTL_RXTHRLEN_7 (0x080UL << DTHRCTL_RXTHRLEN_Pos) // 0x01000000 +#define DTHRCTL_RXTHRLEN_8 (0x100UL << DTHRCTL_RXTHRLEN_Pos) // 0x02000000 #define DTHRCTL_ARPEN_Pos (27U) -#define DTHRCTL_ARPEN_Msk (0x1UL << DTHRCTL_ARPEN_Pos) // 0x08000000 */ -#define DTHRCTL_ARPEN DTHRCTL_ARPEN_Msk // Arbiter parking enable */ +#define DTHRCTL_ARPEN_Msk (0x1UL << DTHRCTL_ARPEN_Pos) // 0x08000000 +#define DTHRCTL_ARPEN DTHRCTL_ARPEN_Msk // Arbiter parking enable /******************** Bit definition for DIEPEMPMSK register ********************/ #define DIEPEMPMSK_INEPTXFEM_Pos (0U) -#define DIEPEMPMSK_INEPTXFEM_Msk (0xFFFFUL << DIEPEMPMSK_INEPTXFEM_Pos) // 0x0000FFFF */ -#define DIEPEMPMSK_INEPTXFEM DIEPEMPMSK_INEPTXFEM_Msk // IN EP Tx FIFO empty interrupt mask bits */ +#define DIEPEMPMSK_INEPTXFEM_Msk (0xFFFFUL << DIEPEMPMSK_INEPTXFEM_Pos) // 0x0000FFFF +#define DIEPEMPMSK_INEPTXFEM DIEPEMPMSK_INEPTXFEM_Msk // IN EP Tx FIFO empty interrupt mask bits /******************** Bit definition for DEACHINT register ********************/ #define DEACHINT_IEP1INT_Pos (1U) -#define DEACHINT_IEP1INT_Msk (0x1UL << DEACHINT_IEP1INT_Pos) // 0x00000002 */ -#define DEACHINT_IEP1INT DEACHINT_IEP1INT_Msk // IN endpoint 1interrupt bit */ +#define DEACHINT_IEP1INT_Msk (0x1UL << DEACHINT_IEP1INT_Pos) // 0x00000002 +#define DEACHINT_IEP1INT DEACHINT_IEP1INT_Msk // IN endpoint 1interrupt bit #define DEACHINT_OEP1INT_Pos (17U) -#define DEACHINT_OEP1INT_Msk (0x1UL << DEACHINT_OEP1INT_Pos) // 0x00020000 */ -#define DEACHINT_OEP1INT DEACHINT_OEP1INT_Msk // OUT endpoint 1 interrupt bit */ +#define DEACHINT_OEP1INT_Msk (0x1UL << DEACHINT_OEP1INT_Pos) // 0x00020000 +#define DEACHINT_OEP1INT DEACHINT_OEP1INT_Msk // OUT endpoint 1 interrupt bit /******************** Bit definition for GCCFG register ********************/ #define STM32_GCCFG_DCDET_Pos (0U) -#define STM32_GCCFG_DCDET_Msk (0x1UL << STM32_GCCFG_DCDET_Pos) // 0x00000001 */ -#define STM32_GCCFG_DCDET STM32_GCCFG_DCDET_Msk // Data contact detection (DCD) status */ +#define STM32_GCCFG_DCDET_Msk (0x1UL << STM32_GCCFG_DCDET_Pos) // 0x00000001 +#define STM32_GCCFG_DCDET STM32_GCCFG_DCDET_Msk // Data contact detection (DCD) status + #define STM32_GCCFG_PDET_Pos (1U) -#define STM32_GCCFG_PDET_Msk (0x1UL << STM32_GCCFG_PDET_Pos) // 0x00000002 */ -#define STM32_GCCFG_PDET STM32_GCCFG_PDET_Msk // Primary detection (PD) status */ +#define STM32_GCCFG_PDET_Msk (0x1UL << STM32_GCCFG_PDET_Pos) // 0x00000002 +#define STM32_GCCFG_PDET STM32_GCCFG_PDET_Msk // Primary detection (PD) status + #define STM32_GCCFG_SDET_Pos (2U) -#define STM32_GCCFG_SDET_Msk (0x1UL << STM32_GCCFG_SDET_Pos) // 0x00000004 */ -#define STM32_GCCFG_SDET STM32_GCCFG_SDET_Msk // Secondary detection (SD) status */ +#define STM32_GCCFG_SDET_Msk (0x1UL << STM32_GCCFG_SDET_Pos) // 0x00000004 +#define STM32_GCCFG_SDET STM32_GCCFG_SDET_Msk // Secondary detection (SD) status + #define STM32_GCCFG_PS2DET_Pos (3U) -#define STM32_GCCFG_PS2DET_Msk (0x1UL << STM32_GCCFG_PS2DET_Pos) // 0x00000008 */ -#define STM32_GCCFG_PS2DET STM32_GCCFG_PS2DET_Msk // DM pull-up detection status */ +#define STM32_GCCFG_PS2DET_Msk (0x1UL << STM32_GCCFG_PS2DET_Pos) // 0x00000008 +#define STM32_GCCFG_PS2DET STM32_GCCFG_PS2DET_Msk // DM pull-up detection status + #define STM32_GCCFG_PWRDWN_Pos (16U) -#define STM32_GCCFG_PWRDWN_Msk (0x1UL << STM32_GCCFG_PWRDWN_Pos) // 0x00010000 */ -#define STM32_GCCFG_PWRDWN STM32_GCCFG_PWRDWN_Msk // Power down */ +#define STM32_GCCFG_PWRDWN_Msk (0x1UL << STM32_GCCFG_PWRDWN_Pos) // 0x00010000 +#define STM32_GCCFG_PWRDWN STM32_GCCFG_PWRDWN_Msk // Power down + #define STM32_GCCFG_BCDEN_Pos (17U) -#define STM32_GCCFG_BCDEN_Msk (0x1UL << STM32_GCCFG_BCDEN_Pos) // 0x00020000 */ -#define STM32_GCCFG_BCDEN STM32_GCCFG_BCDEN_Msk // Battery charging detector (BCD) enable */ +#define STM32_GCCFG_BCDEN_Msk (0x1UL << STM32_GCCFG_BCDEN_Pos) // 0x00020000 +#define STM32_GCCFG_BCDEN STM32_GCCFG_BCDEN_Msk // Battery charging detector (BCD) enable + #define STM32_GCCFG_DCDEN_Pos (18U) -#define STM32_GCCFG_DCDEN_Msk (0x1UL << STM32_GCCFG_DCDEN_Pos) // 0x00040000 */ +#define STM32_GCCFG_DCDEN_Msk (0x1UL << STM32_GCCFG_DCDEN_Pos) // 0x00040000 #define STM32_GCCFG_DCDEN STM32_GCCFG_DCDEN_Msk // Data contact detection (DCD) mode enable*/ + #define STM32_GCCFG_PDEN_Pos (19U) -#define STM32_GCCFG_PDEN_Msk (0x1UL << STM32_GCCFG_PDEN_Pos) // 0x00080000 */ +#define STM32_GCCFG_PDEN_Msk (0x1UL << STM32_GCCFG_PDEN_Pos) // 0x00080000 #define STM32_GCCFG_PDEN STM32_GCCFG_PDEN_Msk // Primary detection (PD) mode enable*/ + #define STM32_GCCFG_SDEN_Pos (20U) -#define STM32_GCCFG_SDEN_Msk (0x1UL << STM32_GCCFG_SDEN_Pos) // 0x00100000 */ -#define STM32_GCCFG_SDEN STM32_GCCFG_SDEN_Msk // Secondary detection (SD) mode enable */ +#define STM32_GCCFG_SDEN_Msk (0x1UL << STM32_GCCFG_SDEN_Pos) // 0x00100000 +#define STM32_GCCFG_SDEN STM32_GCCFG_SDEN_Msk // Secondary detection (SD) mode enable + #define STM32_GCCFG_VBDEN_Pos (21U) -#define STM32_GCCFG_VBDEN_Msk (0x1UL << STM32_GCCFG_VBDEN_Pos) // 0x00200000 */ -#define STM32_GCCFG_VBDEN STM32_GCCFG_VBDEN_Msk // VBUS mode enable */ +#define STM32_GCCFG_VBDEN_Msk (0x1UL << STM32_GCCFG_VBDEN_Pos) // 0x00200000 +#define STM32_GCCFG_VBDEN STM32_GCCFG_VBDEN_Msk // VBUS mode enable + #define STM32_GCCFG_OTGIDEN_Pos (22U) -#define STM32_GCCFG_OTGIDEN_Msk (0x1UL << STM32_GCCFG_OTGIDEN_Pos) // 0x00400000 */ -#define STM32_GCCFG_OTGIDEN STM32_GCCFG_OTGIDEN_Msk // OTG Id enable */ +#define STM32_GCCFG_OTGIDEN_Msk (0x1UL << STM32_GCCFG_OTGIDEN_Pos) // 0x00400000 +#define STM32_GCCFG_OTGIDEN STM32_GCCFG_OTGIDEN_Msk // OTG Id enable + #define STM32_GCCFG_PHYHSEN_Pos (23U) -#define STM32_GCCFG_PHYHSEN_Msk (0x1UL << STM32_GCCFG_PHYHSEN_Pos) // 0x00800000 */ -#define STM32_GCCFG_PHYHSEN STM32_GCCFG_PHYHSEN_Msk // HS PHY enable */ +#define STM32_GCCFG_PHYHSEN_Msk (0x1UL << STM32_GCCFG_PHYHSEN_Pos) // 0x00800000 +#define STM32_GCCFG_PHYHSEN STM32_GCCFG_PHYHSEN_Msk // HS PHY enable + +// TODO stm32u5a5 SDEN is 22nd bit, conflict with 20th bit above +//#define STM32_GCCFG_SDEN_Pos (22U) +//#define STM32_GCCFG_SDEN_Msk (0x1U << STM32_GCCFG_SDEN_Pos) // 0x00400000 +//#define STM32_GCCFG_SDEN STM32_GCCFG_SDEN_Msk // Secondary detection (PD) mode enable + +// TODO stm32u5a5 VBVALOVA is 23rd bit, conflict with PHYHSEN bit above +#define STM32_GCCFG_VBVALOVAL_Pos (23U) +#define STM32_GCCFG_VBVALOVAL_Msk (0x1U << STM32_GCCFG_VBVALOVAL_Pos) // 0x00800000 +#define STM32_GCCFG_VBVALOVAL STM32_GCCFG_VBVALOVAL_Msk // Value of VBUSVLDEXT0 femtoPHY input + +#define STM32_GCCFG_VBVALEXTOEN_Pos (24U) +#define STM32_GCCFG_VBVALEXTOEN_Msk (0x1U << STM32_GCCFG_VBVALEXTOEN_Pos) // 0x01000000 +#define STM32_GCCFG_VBVALEXTOEN STM32_GCCFG_VBVALEXTOEN_Msk // Enables of VBUSVLDEXT0 femtoPHY input override + +#define STM32_GCCFG_PULLDOWNEN_Pos (25U) +#define STM32_GCCFG_PULLDOWNEN_Msk (0x1U << STM32_GCCFG_PULLDOWNEN_Pos) // 0x02000000 +#define STM32_GCCFG_PULLDOWNEN STM32_GCCFG_PULLDOWNEN_Msk // Enables of femtoPHY pulldown resistors, used when ID PAD is disabled + /******************** Bit definition for DEACHINTMSK register ********************/ #define DEACHINTMSK_IEP1INTM_Pos (1U) -#define DEACHINTMSK_IEP1INTM_Msk (0x1UL << DEACHINTMSK_IEP1INTM_Pos) // 0x00000002 */ -#define DEACHINTMSK_IEP1INTM DEACHINTMSK_IEP1INTM_Msk // IN Endpoint 1 interrupt mask bit */ +#define DEACHINTMSK_IEP1INTM_Msk (0x1UL << DEACHINTMSK_IEP1INTM_Pos) // 0x00000002 +#define DEACHINTMSK_IEP1INTM DEACHINTMSK_IEP1INTM_Msk // IN Endpoint 1 interrupt mask bit #define DEACHINTMSK_OEP1INTM_Pos (17U) -#define DEACHINTMSK_OEP1INTM_Msk (0x1UL << DEACHINTMSK_OEP1INTM_Pos) // 0x00020000 */ -#define DEACHINTMSK_OEP1INTM DEACHINTMSK_OEP1INTM_Msk // OUT Endpoint 1 interrupt mask bit */ +#define DEACHINTMSK_OEP1INTM_Msk (0x1UL << DEACHINTMSK_OEP1INTM_Pos) // 0x00020000 +#define DEACHINTMSK_OEP1INTM DEACHINTMSK_OEP1INTM_Msk // OUT Endpoint 1 interrupt mask bit /******************** Bit definition for CID register ********************/ #define CID_PRODUCT_ID_Pos (0U) -#define CID_PRODUCT_ID_Msk (0xFFFFFFFFUL << CID_PRODUCT_ID_Pos) // 0xFFFFFFFF */ -#define CID_PRODUCT_ID CID_PRODUCT_ID_Msk // Product ID field */ +#define CID_PRODUCT_ID_Msk (0xFFFFFFFFUL << CID_PRODUCT_ID_Pos) // 0xFFFFFFFF +#define CID_PRODUCT_ID CID_PRODUCT_ID_Msk // Product ID field /******************** Bit definition for GLPMCFG register ********************/ #define GLPMCFG_LPMEN_Pos (0U) -#define GLPMCFG_LPMEN_Msk (0x1UL << GLPMCFG_LPMEN_Pos) // 0x00000001 */ -#define GLPMCFG_LPMEN GLPMCFG_LPMEN_Msk // LPM support enable */ +#define GLPMCFG_LPMEN_Msk (0x1UL << GLPMCFG_LPMEN_Pos) // 0x00000001 +#define GLPMCFG_LPMEN GLPMCFG_LPMEN_Msk // LPM support enable #define GLPMCFG_LPMACK_Pos (1U) -#define GLPMCFG_LPMACK_Msk (0x1UL << GLPMCFG_LPMACK_Pos) // 0x00000002 */ -#define GLPMCFG_LPMACK GLPMCFG_LPMACK_Msk // LPM Token acknowledge enable */ +#define GLPMCFG_LPMACK_Msk (0x1UL << GLPMCFG_LPMACK_Pos) // 0x00000002 +#define GLPMCFG_LPMACK GLPMCFG_LPMACK_Msk // LPM Token acknowledge enable #define GLPMCFG_BESL_Pos (2U) -#define GLPMCFG_BESL_Msk (0xFUL << GLPMCFG_BESL_Pos) // 0x0000003C */ -#define GLPMCFG_BESL GLPMCFG_BESL_Msk // BESL value received with last ACKed LPM Token */ +#define GLPMCFG_BESL_Msk (0xFUL << GLPMCFG_BESL_Pos) // 0x0000003C +#define GLPMCFG_BESL GLPMCFG_BESL_Msk // BESL value received with last ACKed LPM Token #define GLPMCFG_REMWAKE_Pos (6U) -#define GLPMCFG_REMWAKE_Msk (0x1UL << GLPMCFG_REMWAKE_Pos) // 0x00000040 */ -#define GLPMCFG_REMWAKE GLPMCFG_REMWAKE_Msk // bRemoteWake value received with last ACKed LPM Token */ +#define GLPMCFG_REMWAKE_Msk (0x1UL << GLPMCFG_REMWAKE_Pos) // 0x00000040 +#define GLPMCFG_REMWAKE GLPMCFG_REMWAKE_Msk // bRemoteWake value received with last ACKed LPM Token #define GLPMCFG_L1SSEN_Pos (7U) -#define GLPMCFG_L1SSEN_Msk (0x1UL << GLPMCFG_L1SSEN_Pos) // 0x00000080 */ -#define GLPMCFG_L1SSEN GLPMCFG_L1SSEN_Msk // L1 shallow sleep enable */ +#define GLPMCFG_L1SSEN_Msk (0x1UL << GLPMCFG_L1SSEN_Pos) // 0x00000080 +#define GLPMCFG_L1SSEN GLPMCFG_L1SSEN_Msk // L1 shallow sleep enable #define GLPMCFG_BESLTHRS_Pos (8U) -#define GLPMCFG_BESLTHRS_Msk (0xFUL << GLPMCFG_BESLTHRS_Pos) // 0x00000F00 */ -#define GLPMCFG_BESLTHRS GLPMCFG_BESLTHRS_Msk // BESL threshold */ +#define GLPMCFG_BESLTHRS_Msk (0xFUL << GLPMCFG_BESLTHRS_Pos) // 0x00000F00 +#define GLPMCFG_BESLTHRS GLPMCFG_BESLTHRS_Msk // BESL threshold #define GLPMCFG_L1DSEN_Pos (12U) -#define GLPMCFG_L1DSEN_Msk (0x1UL << GLPMCFG_L1DSEN_Pos) // 0x00001000 */ -#define GLPMCFG_L1DSEN GLPMCFG_L1DSEN_Msk // L1 deep sleep enable */ +#define GLPMCFG_L1DSEN_Msk (0x1UL << GLPMCFG_L1DSEN_Pos) // 0x00001000 +#define GLPMCFG_L1DSEN GLPMCFG_L1DSEN_Msk // L1 deep sleep enable #define GLPMCFG_LPMRSP_Pos (13U) -#define GLPMCFG_LPMRSP_Msk (0x3UL << GLPMCFG_LPMRSP_Pos) // 0x00006000 */ -#define GLPMCFG_LPMRSP GLPMCFG_LPMRSP_Msk // LPM response */ +#define GLPMCFG_LPMRSP_Msk (0x3UL << GLPMCFG_LPMRSP_Pos) // 0x00006000 +#define GLPMCFG_LPMRSP GLPMCFG_LPMRSP_Msk // LPM response #define GLPMCFG_SLPSTS_Pos (15U) -#define GLPMCFG_SLPSTS_Msk (0x1UL << GLPMCFG_SLPSTS_Pos) // 0x00008000 */ -#define GLPMCFG_SLPSTS GLPMCFG_SLPSTS_Msk // Port sleep status */ +#define GLPMCFG_SLPSTS_Msk (0x1UL << GLPMCFG_SLPSTS_Pos) // 0x00008000 +#define GLPMCFG_SLPSTS GLPMCFG_SLPSTS_Msk // Port sleep status #define GLPMCFG_L1RSMOK_Pos (16U) -#define GLPMCFG_L1RSMOK_Msk (0x1UL << GLPMCFG_L1RSMOK_Pos) // 0x00010000 */ -#define GLPMCFG_L1RSMOK GLPMCFG_L1RSMOK_Msk // Sleep State Resume OK */ +#define GLPMCFG_L1RSMOK_Msk (0x1UL << GLPMCFG_L1RSMOK_Pos) // 0x00010000 +#define GLPMCFG_L1RSMOK GLPMCFG_L1RSMOK_Msk // Sleep State Resume OK #define GLPMCFG_LPMCHIDX_Pos (17U) -#define GLPMCFG_LPMCHIDX_Msk (0xFUL << GLPMCFG_LPMCHIDX_Pos) // 0x001E0000 */ -#define GLPMCFG_LPMCHIDX GLPMCFG_LPMCHIDX_Msk // LPM Channel Index */ +#define GLPMCFG_LPMCHIDX_Msk (0xFUL << GLPMCFG_LPMCHIDX_Pos) // 0x001E0000 +#define GLPMCFG_LPMCHIDX GLPMCFG_LPMCHIDX_Msk // LPM Channel Index #define GLPMCFG_LPMRCNT_Pos (21U) -#define GLPMCFG_LPMRCNT_Msk (0x7UL << GLPMCFG_LPMRCNT_Pos) // 0x00E00000 */ -#define GLPMCFG_LPMRCNT GLPMCFG_LPMRCNT_Msk // LPM retry count */ +#define GLPMCFG_LPMRCNT_Msk (0x7UL << GLPMCFG_LPMRCNT_Pos) // 0x00E00000 +#define GLPMCFG_LPMRCNT GLPMCFG_LPMRCNT_Msk // LPM retry count #define GLPMCFG_SNDLPM_Pos (24U) -#define GLPMCFG_SNDLPM_Msk (0x1UL << GLPMCFG_SNDLPM_Pos) // 0x01000000 */ -#define GLPMCFG_SNDLPM GLPMCFG_SNDLPM_Msk // Send LPM transaction */ +#define GLPMCFG_SNDLPM_Msk (0x1UL << GLPMCFG_SNDLPM_Pos) // 0x01000000 +#define GLPMCFG_SNDLPM GLPMCFG_SNDLPM_Msk // Send LPM transaction #define GLPMCFG_LPMRCNTSTS_Pos (25U) -#define GLPMCFG_LPMRCNTSTS_Msk (0x7UL << GLPMCFG_LPMRCNTSTS_Pos) // 0x0E000000 */ -#define GLPMCFG_LPMRCNTSTS GLPMCFG_LPMRCNTSTS_Msk // LPM retry count status */ +#define GLPMCFG_LPMRCNTSTS_Msk (0x7UL << GLPMCFG_LPMRCNTSTS_Pos) // 0x0E000000 +#define GLPMCFG_LPMRCNTSTS GLPMCFG_LPMRCNTSTS_Msk // LPM retry count status #define GLPMCFG_ENBESL_Pos (28U) -#define GLPMCFG_ENBESL_Msk (0x1UL << GLPMCFG_ENBESL_Pos) // 0x10000000 */ -#define GLPMCFG_ENBESL GLPMCFG_ENBESL_Msk // Enable best effort service latency */ +#define GLPMCFG_ENBESL_Msk (0x1UL << GLPMCFG_ENBESL_Pos) // 0x10000000 +#define GLPMCFG_ENBESL GLPMCFG_ENBESL_Msk // Enable best effort service latency /******************** Bit definition for DIEPEACHMSK1 register ********************/ #define DIEPEACHMSK1_XFRCM_Pos (0U) -#define DIEPEACHMSK1_XFRCM_Msk (0x1UL << DIEPEACHMSK1_XFRCM_Pos) // 0x00000001 */ -#define DIEPEACHMSK1_XFRCM DIEPEACHMSK1_XFRCM_Msk // Transfer completed interrupt mask */ +#define DIEPEACHMSK1_XFRCM_Msk (0x1UL << DIEPEACHMSK1_XFRCM_Pos) // 0x00000001 +#define DIEPEACHMSK1_XFRCM DIEPEACHMSK1_XFRCM_Msk // Transfer completed interrupt mask #define DIEPEACHMSK1_EPDM_Pos (1U) -#define DIEPEACHMSK1_EPDM_Msk (0x1UL << DIEPEACHMSK1_EPDM_Pos) // 0x00000002 */ -#define DIEPEACHMSK1_EPDM DIEPEACHMSK1_EPDM_Msk // Endpoint disabled interrupt mask */ +#define DIEPEACHMSK1_EPDM_Msk (0x1UL << DIEPEACHMSK1_EPDM_Pos) // 0x00000002 +#define DIEPEACHMSK1_EPDM DIEPEACHMSK1_EPDM_Msk // Endpoint disabled interrupt mask #define DIEPEACHMSK1_TOM_Pos (3U) -#define DIEPEACHMSK1_TOM_Msk (0x1UL << DIEPEACHMSK1_TOM_Pos) // 0x00000008 */ -#define DIEPEACHMSK1_TOM DIEPEACHMSK1_TOM_Msk // Timeout condition mask (nonisochronous endpoints) */ +#define DIEPEACHMSK1_TOM_Msk (0x1UL << DIEPEACHMSK1_TOM_Pos) // 0x00000008 +#define DIEPEACHMSK1_TOM DIEPEACHMSK1_TOM_Msk // Timeout condition mask (nonisochronous endpoints) #define DIEPEACHMSK1_ITTXFEMSK_Pos (4U) -#define DIEPEACHMSK1_ITTXFEMSK_Msk (0x1UL << DIEPEACHMSK1_ITTXFEMSK_Pos) // 0x00000010 */ -#define DIEPEACHMSK1_ITTXFEMSK DIEPEACHMSK1_ITTXFEMSK_Msk // IN token received when TxFIFO empty mask */ +#define DIEPEACHMSK1_ITTXFEMSK_Msk (0x1UL << DIEPEACHMSK1_ITTXFEMSK_Pos) // 0x00000010 +#define DIEPEACHMSK1_ITTXFEMSK DIEPEACHMSK1_ITTXFEMSK_Msk // IN token received when TxFIFO empty mask #define DIEPEACHMSK1_INEPNMM_Pos (5U) -#define DIEPEACHMSK1_INEPNMM_Msk (0x1UL << DIEPEACHMSK1_INEPNMM_Pos) // 0x00000020 */ -#define DIEPEACHMSK1_INEPNMM DIEPEACHMSK1_INEPNMM_Msk // IN token received with EP mismatch mask */ +#define DIEPEACHMSK1_INEPNMM_Msk (0x1UL << DIEPEACHMSK1_INEPNMM_Pos) // 0x00000020 +#define DIEPEACHMSK1_INEPNMM DIEPEACHMSK1_INEPNMM_Msk // IN token received with EP mismatch mask #define DIEPEACHMSK1_INEPNEM_Pos (6U) -#define DIEPEACHMSK1_INEPNEM_Msk (0x1UL << DIEPEACHMSK1_INEPNEM_Pos) // 0x00000040 */ -#define DIEPEACHMSK1_INEPNEM DIEPEACHMSK1_INEPNEM_Msk // IN endpoint NAK effective mask */ +#define DIEPEACHMSK1_INEPNEM_Msk (0x1UL << DIEPEACHMSK1_INEPNEM_Pos) // 0x00000040 +#define DIEPEACHMSK1_INEPNEM DIEPEACHMSK1_INEPNEM_Msk // IN endpoint NAK effective mask #define DIEPEACHMSK1_TXFURM_Pos (8U) -#define DIEPEACHMSK1_TXFURM_Msk (0x1UL << DIEPEACHMSK1_TXFURM_Pos) // 0x00000100 */ -#define DIEPEACHMSK1_TXFURM DIEPEACHMSK1_TXFURM_Msk // FIFO underrun mask */ +#define DIEPEACHMSK1_TXFURM_Msk (0x1UL << DIEPEACHMSK1_TXFURM_Pos) // 0x00000100 +#define DIEPEACHMSK1_TXFURM DIEPEACHMSK1_TXFURM_Msk // FIFO underrun mask #define DIEPEACHMSK1_BIM_Pos (9U) -#define DIEPEACHMSK1_BIM_Msk (0x1UL << DIEPEACHMSK1_BIM_Pos) // 0x00000200 */ -#define DIEPEACHMSK1_BIM DIEPEACHMSK1_BIM_Msk // BNA interrupt mask */ +#define DIEPEACHMSK1_BIM_Msk (0x1UL << DIEPEACHMSK1_BIM_Pos) // 0x00000200 +#define DIEPEACHMSK1_BIM DIEPEACHMSK1_BIM_Msk // BNA interrupt mask #define DIEPEACHMSK1_NAKM_Pos (13U) -#define DIEPEACHMSK1_NAKM_Msk (0x1UL << DIEPEACHMSK1_NAKM_Pos) // 0x00002000 */ -#define DIEPEACHMSK1_NAKM DIEPEACHMSK1_NAKM_Msk // NAK interrupt mask */ +#define DIEPEACHMSK1_NAKM_Msk (0x1UL << DIEPEACHMSK1_NAKM_Pos) // 0x00002000 +#define DIEPEACHMSK1_NAKM DIEPEACHMSK1_NAKM_Msk // NAK interrupt mask /******************** Bit definition for HPRT register ********************/ #define HPRT_PCSTS_Pos (0U) -#define HPRT_PCSTS_Msk (0x1UL << HPRT_PCSTS_Pos) // 0x00000001 */ -#define HPRT_PCSTS HPRT_PCSTS_Msk // Port connect status */ +#define HPRT_PCSTS_Msk (0x1UL << HPRT_PCSTS_Pos) // 0x00000001 +#define HPRT_PCSTS HPRT_PCSTS_Msk // Port connect status #define HPRT_PCDET_Pos (1U) -#define HPRT_PCDET_Msk (0x1UL << HPRT_PCDET_Pos) // 0x00000002 */ -#define HPRT_PCDET HPRT_PCDET_Msk // Port connect detected */ +#define HPRT_PCDET_Msk (0x1UL << HPRT_PCDET_Pos) // 0x00000002 +#define HPRT_PCDET HPRT_PCDET_Msk // Port connect detected #define HPRT_PENA_Pos (2U) -#define HPRT_PENA_Msk (0x1UL << HPRT_PENA_Pos) // 0x00000004 */ -#define HPRT_PENA HPRT_PENA_Msk // Port enable */ +#define HPRT_PENA_Msk (0x1UL << HPRT_PENA_Pos) // 0x00000004 +#define HPRT_PENA HPRT_PENA_Msk // Port enable #define HPRT_PENCHNG_Pos (3U) -#define HPRT_PENCHNG_Msk (0x1UL << HPRT_PENCHNG_Pos) // 0x00000008 */ -#define HPRT_PENCHNG HPRT_PENCHNG_Msk // Port enable/disable change */ +#define HPRT_PENCHNG_Msk (0x1UL << HPRT_PENCHNG_Pos) // 0x00000008 +#define HPRT_PENCHNG HPRT_PENCHNG_Msk // Port enable/disable change #define HPRT_POCA_Pos (4U) -#define HPRT_POCA_Msk (0x1UL << HPRT_POCA_Pos) // 0x00000010 */ -#define HPRT_POCA HPRT_POCA_Msk // Port overcurrent active */ +#define HPRT_POCA_Msk (0x1UL << HPRT_POCA_Pos) // 0x00000010 +#define HPRT_POCA HPRT_POCA_Msk // Port overcurrent active #define HPRT_POCCHNG_Pos (5U) -#define HPRT_POCCHNG_Msk (0x1UL << HPRT_POCCHNG_Pos) // 0x00000020 */ -#define HPRT_POCCHNG HPRT_POCCHNG_Msk // Port overcurrent change */ +#define HPRT_POCCHNG_Msk (0x1UL << HPRT_POCCHNG_Pos) // 0x00000020 +#define HPRT_POCCHNG HPRT_POCCHNG_Msk // Port overcurrent change #define HPRT_PRES_Pos (6U) -#define HPRT_PRES_Msk (0x1UL << HPRT_PRES_Pos) // 0x00000040 */ -#define HPRT_PRES HPRT_PRES_Msk // Port resume */ +#define HPRT_PRES_Msk (0x1UL << HPRT_PRES_Pos) // 0x00000040 +#define HPRT_PRES HPRT_PRES_Msk // Port resume #define HPRT_PSUSP_Pos (7U) -#define HPRT_PSUSP_Msk (0x1UL << HPRT_PSUSP_Pos) // 0x00000080 */ -#define HPRT_PSUSP HPRT_PSUSP_Msk // Port suspend */ +#define HPRT_PSUSP_Msk (0x1UL << HPRT_PSUSP_Pos) // 0x00000080 +#define HPRT_PSUSP HPRT_PSUSP_Msk // Port suspend #define HPRT_PRST_Pos (8U) -#define HPRT_PRST_Msk (0x1UL << HPRT_PRST_Pos) // 0x00000100 */ -#define HPRT_PRST HPRT_PRST_Msk // Port reset */ +#define HPRT_PRST_Msk (0x1UL << HPRT_PRST_Pos) // 0x00000100 +#define HPRT_PRST HPRT_PRST_Msk // Port reset #define HPRT_PLSTS_Pos (10U) -#define HPRT_PLSTS_Msk (0x3UL << HPRT_PLSTS_Pos) // 0x00000C00 */ -#define HPRT_PLSTS HPRT_PLSTS_Msk // Port line status */ -#define HPRT_PLSTS_0 (0x1UL << HPRT_PLSTS_Pos) // 0x00000400 */ -#define HPRT_PLSTS_1 (0x2UL << HPRT_PLSTS_Pos) // 0x00000800 */ +#define HPRT_PLSTS_Msk (0x3UL << HPRT_PLSTS_Pos) // 0x00000C00 +#define HPRT_PLSTS HPRT_PLSTS_Msk // Port line status +#define HPRT_PLSTS_0 (0x1UL << HPRT_PLSTS_Pos) // 0x00000400 +#define HPRT_PLSTS_1 (0x2UL << HPRT_PLSTS_Pos) // 0x00000800 #define HPRT_PPWR_Pos (12U) -#define HPRT_PPWR_Msk (0x1UL << HPRT_PPWR_Pos) // 0x00001000 */ -#define HPRT_PPWR HPRT_PPWR_Msk // Port power */ +#define HPRT_PPWR_Msk (0x1UL << HPRT_PPWR_Pos) // 0x00001000 +#define HPRT_PPWR HPRT_PPWR_Msk // Port power #define HPRT_PTCTL_Pos (13U) -#define HPRT_PTCTL_Msk (0xFUL << HPRT_PTCTL_Pos) // 0x0001E000 */ -#define HPRT_PTCTL HPRT_PTCTL_Msk // Port test control */ -#define HPRT_PTCTL_0 (0x1UL << HPRT_PTCTL_Pos) // 0x00002000 */ -#define HPRT_PTCTL_1 (0x2UL << HPRT_PTCTL_Pos) // 0x00004000 */ -#define HPRT_PTCTL_2 (0x4UL << HPRT_PTCTL_Pos) // 0x00008000 */ -#define HPRT_PTCTL_3 (0x8UL << HPRT_PTCTL_Pos) // 0x00010000 */ +#define HPRT_PTCTL_Msk (0xFUL << HPRT_PTCTL_Pos) // 0x0001E000 +#define HPRT_PTCTL HPRT_PTCTL_Msk // Port test control +#define HPRT_PTCTL_0 (0x1UL << HPRT_PTCTL_Pos) // 0x00002000 +#define HPRT_PTCTL_1 (0x2UL << HPRT_PTCTL_Pos) // 0x00004000 +#define HPRT_PTCTL_2 (0x4UL << HPRT_PTCTL_Pos) // 0x00008000 +#define HPRT_PTCTL_3 (0x8UL << HPRT_PTCTL_Pos) // 0x00010000 #define HPRT_PSPD_Pos (17U) -#define HPRT_PSPD_Msk (0x3UL << HPRT_PSPD_Pos) // 0x00060000 */ -#define HPRT_PSPD HPRT_PSPD_Msk // Port speed */ -#define HPRT_PSPD_0 (0x1UL << HPRT_PSPD_Pos) // 0x00020000 */ -#define HPRT_PSPD_1 (0x2UL << HPRT_PSPD_Pos) // 0x00040000 */ +#define HPRT_PSPD_Msk (0x3UL << HPRT_PSPD_Pos) // 0x00060000 +#define HPRT_PSPD HPRT_PSPD_Msk // Port speed +#define HPRT_PSPD_0 (0x1UL << HPRT_PSPD_Pos) // 0x00020000 +#define HPRT_PSPD_1 (0x2UL << HPRT_PSPD_Pos) // 0x00040000 /******************** Bit definition for DOEPEACHMSK1 register ********************/ #define DOEPEACHMSK1_XFRCM_Pos (0U) -#define DOEPEACHMSK1_XFRCM_Msk (0x1UL << DOEPEACHMSK1_XFRCM_Pos) // 0x00000001 */ -#define DOEPEACHMSK1_XFRCM DOEPEACHMSK1_XFRCM_Msk // Transfer completed interrupt mask */ +#define DOEPEACHMSK1_XFRCM_Msk (0x1UL << DOEPEACHMSK1_XFRCM_Pos) // 0x00000001 +#define DOEPEACHMSK1_XFRCM DOEPEACHMSK1_XFRCM_Msk // Transfer completed interrupt mask #define DOEPEACHMSK1_EPDM_Pos (1U) -#define DOEPEACHMSK1_EPDM_Msk (0x1UL << DOEPEACHMSK1_EPDM_Pos) // 0x00000002 */ -#define DOEPEACHMSK1_EPDM DOEPEACHMSK1_EPDM_Msk // Endpoint disabled interrupt mask */ +#define DOEPEACHMSK1_EPDM_Msk (0x1UL << DOEPEACHMSK1_EPDM_Pos) // 0x00000002 +#define DOEPEACHMSK1_EPDM DOEPEACHMSK1_EPDM_Msk // Endpoint disabled interrupt mask #define DOEPEACHMSK1_TOM_Pos (3U) -#define DOEPEACHMSK1_TOM_Msk (0x1UL << DOEPEACHMSK1_TOM_Pos) // 0x00000008 */ -#define DOEPEACHMSK1_TOM DOEPEACHMSK1_TOM_Msk // Timeout condition mask */ +#define DOEPEACHMSK1_TOM_Msk (0x1UL << DOEPEACHMSK1_TOM_Pos) // 0x00000008 +#define DOEPEACHMSK1_TOM DOEPEACHMSK1_TOM_Msk // Timeout condition mask #define DOEPEACHMSK1_ITTXFEMSK_Pos (4U) -#define DOEPEACHMSK1_ITTXFEMSK_Msk (0x1UL << DOEPEACHMSK1_ITTXFEMSK_Pos) // 0x00000010 */ -#define DOEPEACHMSK1_ITTXFEMSK DOEPEACHMSK1_ITTXFEMSK_Msk // IN token received when TxFIFO empty mask */ +#define DOEPEACHMSK1_ITTXFEMSK_Msk (0x1UL << DOEPEACHMSK1_ITTXFEMSK_Pos) // 0x00000010 +#define DOEPEACHMSK1_ITTXFEMSK DOEPEACHMSK1_ITTXFEMSK_Msk // IN token received when TxFIFO empty mask #define DOEPEACHMSK1_INEPNMM_Pos (5U) -#define DOEPEACHMSK1_INEPNMM_Msk (0x1UL << DOEPEACHMSK1_INEPNMM_Pos) // 0x00000020 */ -#define DOEPEACHMSK1_INEPNMM DOEPEACHMSK1_INEPNMM_Msk // IN token received with EP mismatch mask */ +#define DOEPEACHMSK1_INEPNMM_Msk (0x1UL << DOEPEACHMSK1_INEPNMM_Pos) // 0x00000020 +#define DOEPEACHMSK1_INEPNMM DOEPEACHMSK1_INEPNMM_Msk // IN token received with EP mismatch mask #define DOEPEACHMSK1_INEPNEM_Pos (6U) -#define DOEPEACHMSK1_INEPNEM_Msk (0x1UL << DOEPEACHMSK1_INEPNEM_Pos) // 0x00000040 */ -#define DOEPEACHMSK1_INEPNEM DOEPEACHMSK1_INEPNEM_Msk // IN endpoint NAK effective mask */ +#define DOEPEACHMSK1_INEPNEM_Msk (0x1UL << DOEPEACHMSK1_INEPNEM_Pos) // 0x00000040 +#define DOEPEACHMSK1_INEPNEM DOEPEACHMSK1_INEPNEM_Msk // IN endpoint NAK effective mask #define DOEPEACHMSK1_TXFURM_Pos (8U) -#define DOEPEACHMSK1_TXFURM_Msk (0x1UL << DOEPEACHMSK1_TXFURM_Pos) // 0x00000100 */ -#define DOEPEACHMSK1_TXFURM DOEPEACHMSK1_TXFURM_Msk // OUT packet error mask */ +#define DOEPEACHMSK1_TXFURM_Msk (0x1UL << DOEPEACHMSK1_TXFURM_Pos) // 0x00000100 +#define DOEPEACHMSK1_TXFURM DOEPEACHMSK1_TXFURM_Msk // OUT packet error mask #define DOEPEACHMSK1_BIM_Pos (9U) -#define DOEPEACHMSK1_BIM_Msk (0x1UL << DOEPEACHMSK1_BIM_Pos) // 0x00000200 */ -#define DOEPEACHMSK1_BIM DOEPEACHMSK1_BIM_Msk // BNA interrupt mask */ +#define DOEPEACHMSK1_BIM_Msk (0x1UL << DOEPEACHMSK1_BIM_Pos) // 0x00000200 +#define DOEPEACHMSK1_BIM DOEPEACHMSK1_BIM_Msk // BNA interrupt mask #define DOEPEACHMSK1_BERRM_Pos (12U) -#define DOEPEACHMSK1_BERRM_Msk (0x1UL << DOEPEACHMSK1_BERRM_Pos) // 0x00001000 */ -#define DOEPEACHMSK1_BERRM DOEPEACHMSK1_BERRM_Msk // Bubble error interrupt mask */ +#define DOEPEACHMSK1_BERRM_Msk (0x1UL << DOEPEACHMSK1_BERRM_Pos) // 0x00001000 +#define DOEPEACHMSK1_BERRM DOEPEACHMSK1_BERRM_Msk // Bubble error interrupt mask #define DOEPEACHMSK1_NAKM_Pos (13U) -#define DOEPEACHMSK1_NAKM_Msk (0x1UL << DOEPEACHMSK1_NAKM_Pos) // 0x00002000 */ -#define DOEPEACHMSK1_NAKM DOEPEACHMSK1_NAKM_Msk // NAK interrupt mask */ +#define DOEPEACHMSK1_NAKM_Msk (0x1UL << DOEPEACHMSK1_NAKM_Pos) // 0x00002000 +#define DOEPEACHMSK1_NAKM DOEPEACHMSK1_NAKM_Msk // NAK interrupt mask #define DOEPEACHMSK1_NYETM_Pos (14U) -#define DOEPEACHMSK1_NYETM_Msk (0x1UL << DOEPEACHMSK1_NYETM_Pos) // 0x00004000 */ -#define DOEPEACHMSK1_NYETM DOEPEACHMSK1_NYETM_Msk // NYET interrupt mask */ +#define DOEPEACHMSK1_NYETM_Msk (0x1UL << DOEPEACHMSK1_NYETM_Pos) // 0x00004000 +#define DOEPEACHMSK1_NYETM DOEPEACHMSK1_NYETM_Msk // NYET interrupt mask /******************** Bit definition for HPTXFSIZ register ********************/ #define HPTXFSIZ_PTXSA_Pos (0U) -#define HPTXFSIZ_PTXSA_Msk (0xFFFFUL << HPTXFSIZ_PTXSA_Pos) // 0x0000FFFF */ -#define HPTXFSIZ_PTXSA HPTXFSIZ_PTXSA_Msk // Host periodic TxFIFO start address */ +#define HPTXFSIZ_PTXSA_Msk (0xFFFFUL << HPTXFSIZ_PTXSA_Pos) // 0x0000FFFF +#define HPTXFSIZ_PTXSA HPTXFSIZ_PTXSA_Msk // Host periodic TxFIFO start address #define HPTXFSIZ_PTXFD_Pos (16U) -#define HPTXFSIZ_PTXFD_Msk (0xFFFFUL << HPTXFSIZ_PTXFD_Pos) // 0xFFFF0000 */ -#define HPTXFSIZ_PTXFD HPTXFSIZ_PTXFD_Msk // Host periodic TxFIFO depth */ +#define HPTXFSIZ_PTXFD_Msk (0xFFFFUL << HPTXFSIZ_PTXFD_Pos) // 0xFFFF0000 +#define HPTXFSIZ_PTXFD HPTXFSIZ_PTXFD_Msk // Host periodic TxFIFO depth /******************** Bit definition for DIEPCTL register ********************/ #define DIEPCTL_MPSIZ_Pos (0U) -#define DIEPCTL_MPSIZ_Msk (0x7FFUL << DIEPCTL_MPSIZ_Pos) // 0x000007FF */ -#define DIEPCTL_MPSIZ DIEPCTL_MPSIZ_Msk // Maximum packet size */ +#define DIEPCTL_MPSIZ_Msk (0x7FFUL << DIEPCTL_MPSIZ_Pos) // 0x000007FF +#define DIEPCTL_MPSIZ DIEPCTL_MPSIZ_Msk // Maximum packet size #define DIEPCTL_USBAEP_Pos (15U) -#define DIEPCTL_USBAEP_Msk (0x1UL << DIEPCTL_USBAEP_Pos) // 0x00008000 */ -#define DIEPCTL_USBAEP DIEPCTL_USBAEP_Msk // USB active endpoint */ +#define DIEPCTL_USBAEP_Msk (0x1UL << DIEPCTL_USBAEP_Pos) // 0x00008000 +#define DIEPCTL_USBAEP DIEPCTL_USBAEP_Msk // USB active endpoint #define DIEPCTL_EONUM_DPID_Pos (16U) -#define DIEPCTL_EONUM_DPID_Msk (0x1UL << DIEPCTL_EONUM_DPID_Pos) // 0x00010000 */ -#define DIEPCTL_EONUM_DPID DIEPCTL_EONUM_DPID_Msk // Even/odd frame */ +#define DIEPCTL_EONUM_DPID_Msk (0x1UL << DIEPCTL_EONUM_DPID_Pos) // 0x00010000 +#define DIEPCTL_EONUM_DPID DIEPCTL_EONUM_DPID_Msk // Even/odd frame #define DIEPCTL_NAKSTS_Pos (17U) -#define DIEPCTL_NAKSTS_Msk (0x1UL << DIEPCTL_NAKSTS_Pos) // 0x00020000 */ -#define DIEPCTL_NAKSTS DIEPCTL_NAKSTS_Msk // NAK status */ +#define DIEPCTL_NAKSTS_Msk (0x1UL << DIEPCTL_NAKSTS_Pos) // 0x00020000 +#define DIEPCTL_NAKSTS DIEPCTL_NAKSTS_Msk // NAK status #define DIEPCTL_EPTYP_Pos (18U) -#define DIEPCTL_EPTYP_Msk (0x3UL << DIEPCTL_EPTYP_Pos) // 0x000C0000 */ -#define DIEPCTL_EPTYP DIEPCTL_EPTYP_Msk // Endpoint type */ -#define DIEPCTL_EPTYP_0 (0x1UL << DIEPCTL_EPTYP_Pos) // 0x00040000 */ -#define DIEPCTL_EPTYP_1 (0x2UL << DIEPCTL_EPTYP_Pos) // 0x00080000 */ +#define DIEPCTL_EPTYP_Msk (0x3UL << DIEPCTL_EPTYP_Pos) // 0x000C0000 +#define DIEPCTL_EPTYP DIEPCTL_EPTYP_Msk // Endpoint type +#define DIEPCTL_EPTYP_0 (0x1UL << DIEPCTL_EPTYP_Pos) // 0x00040000 +#define DIEPCTL_EPTYP_1 (0x2UL << DIEPCTL_EPTYP_Pos) // 0x00080000 #define DIEPCTL_STALL_Pos (21U) -#define DIEPCTL_STALL_Msk (0x1UL << DIEPCTL_STALL_Pos) // 0x00200000 */ -#define DIEPCTL_STALL DIEPCTL_STALL_Msk // STALL handshake */ +#define DIEPCTL_STALL_Msk (0x1UL << DIEPCTL_STALL_Pos) // 0x00200000 +#define DIEPCTL_STALL DIEPCTL_STALL_Msk // STALL handshake #define DIEPCTL_TXFNUM_Pos (22U) -#define DIEPCTL_TXFNUM_Msk (0xFUL << DIEPCTL_TXFNUM_Pos) // 0x03C00000 */ -#define DIEPCTL_TXFNUM DIEPCTL_TXFNUM_Msk // TxFIFO number */ -#define DIEPCTL_TXFNUM_0 (0x1UL << DIEPCTL_TXFNUM_Pos) // 0x00400000 */ -#define DIEPCTL_TXFNUM_1 (0x2UL << DIEPCTL_TXFNUM_Pos) // 0x00800000 */ -#define DIEPCTL_TXFNUM_2 (0x4UL << DIEPCTL_TXFNUM_Pos) // 0x01000000 */ -#define DIEPCTL_TXFNUM_3 (0x8UL << DIEPCTL_TXFNUM_Pos) // 0x02000000 */ +#define DIEPCTL_TXFNUM_Msk (0xFUL << DIEPCTL_TXFNUM_Pos) // 0x03C00000 +#define DIEPCTL_TXFNUM DIEPCTL_TXFNUM_Msk // TxFIFO number +#define DIEPCTL_TXFNUM_0 (0x1UL << DIEPCTL_TXFNUM_Pos) // 0x00400000 +#define DIEPCTL_TXFNUM_1 (0x2UL << DIEPCTL_TXFNUM_Pos) // 0x00800000 +#define DIEPCTL_TXFNUM_2 (0x4UL << DIEPCTL_TXFNUM_Pos) // 0x01000000 +#define DIEPCTL_TXFNUM_3 (0x8UL << DIEPCTL_TXFNUM_Pos) // 0x02000000 #define DIEPCTL_CNAK_Pos (26U) -#define DIEPCTL_CNAK_Msk (0x1UL << DIEPCTL_CNAK_Pos) // 0x04000000 */ -#define DIEPCTL_CNAK DIEPCTL_CNAK_Msk // Clear NAK */ +#define DIEPCTL_CNAK_Msk (0x1UL << DIEPCTL_CNAK_Pos) // 0x04000000 +#define DIEPCTL_CNAK DIEPCTL_CNAK_Msk // Clear NAK #define DIEPCTL_SNAK_Pos (27U) -#define DIEPCTL_SNAK_Msk (0x1UL << DIEPCTL_SNAK_Pos) // 0x08000000 */ -#define DIEPCTL_SNAK DIEPCTL_SNAK_Msk // Set NAK */ +#define DIEPCTL_SNAK_Msk (0x1UL << DIEPCTL_SNAK_Pos) // 0x08000000 +#define DIEPCTL_SNAK DIEPCTL_SNAK_Msk // Set NAK #define DIEPCTL_SD0PID_SEVNFRM_Pos (28U) -#define DIEPCTL_SD0PID_SEVNFRM_Msk (0x1UL << DIEPCTL_SD0PID_SEVNFRM_Pos) // 0x10000000 */ -#define DIEPCTL_SD0PID_SEVNFRM DIEPCTL_SD0PID_SEVNFRM_Msk // Set DATA0 PID */ +#define DIEPCTL_SD0PID_SEVNFRM_Msk (0x1UL << DIEPCTL_SD0PID_SEVNFRM_Pos) // 0x10000000 +#define DIEPCTL_SD0PID_SEVNFRM DIEPCTL_SD0PID_SEVNFRM_Msk // Set DATA0 PID #define DIEPCTL_SODDFRM_Pos (29U) -#define DIEPCTL_SODDFRM_Msk (0x1UL << DIEPCTL_SODDFRM_Pos) // 0x20000000 */ -#define DIEPCTL_SODDFRM DIEPCTL_SODDFRM_Msk // Set odd frame */ +#define DIEPCTL_SODDFRM_Msk (0x1UL << DIEPCTL_SODDFRM_Pos) // 0x20000000 +#define DIEPCTL_SODDFRM DIEPCTL_SODDFRM_Msk // Set odd frame #define DIEPCTL_EPDIS_Pos (30U) -#define DIEPCTL_EPDIS_Msk (0x1UL << DIEPCTL_EPDIS_Pos) // 0x40000000 */ -#define DIEPCTL_EPDIS DIEPCTL_EPDIS_Msk // Endpoint disable */ +#define DIEPCTL_EPDIS_Msk (0x1UL << DIEPCTL_EPDIS_Pos) // 0x40000000 +#define DIEPCTL_EPDIS DIEPCTL_EPDIS_Msk // Endpoint disable #define DIEPCTL_EPENA_Pos (31U) -#define DIEPCTL_EPENA_Msk (0x1UL << DIEPCTL_EPENA_Pos) // 0x80000000 */ -#define DIEPCTL_EPENA DIEPCTL_EPENA_Msk // Endpoint enable */ +#define DIEPCTL_EPENA_Msk (0x1UL << DIEPCTL_EPENA_Pos) // 0x80000000 +#define DIEPCTL_EPENA DIEPCTL_EPENA_Msk // Endpoint enable /******************** Bit definition for HCCHAR register ********************/ #define HCCHAR_MPSIZ_Pos (0U) -#define HCCHAR_MPSIZ_Msk (0x7FFUL << HCCHAR_MPSIZ_Pos) // 0x000007FF */ -#define HCCHAR_MPSIZ HCCHAR_MPSIZ_Msk // Maximum packet size */ +#define HCCHAR_MPSIZ_Msk (0x7FFUL << HCCHAR_MPSIZ_Pos) // 0x000007FF +#define HCCHAR_MPSIZ HCCHAR_MPSIZ_Msk // Maximum packet size #define HCCHAR_EPNUM_Pos (11U) -#define HCCHAR_EPNUM_Msk (0xFUL << HCCHAR_EPNUM_Pos) // 0x00007800 */ -#define HCCHAR_EPNUM HCCHAR_EPNUM_Msk // Endpoint number */ -#define HCCHAR_EPNUM_0 (0x1UL << HCCHAR_EPNUM_Pos) // 0x00000800 */ -#define HCCHAR_EPNUM_1 (0x2UL << HCCHAR_EPNUM_Pos) // 0x00001000 */ -#define HCCHAR_EPNUM_2 (0x4UL << HCCHAR_EPNUM_Pos) // 0x00002000 */ -#define HCCHAR_EPNUM_3 (0x8UL << HCCHAR_EPNUM_Pos) // 0x00004000 */ +#define HCCHAR_EPNUM_Msk (0xFUL << HCCHAR_EPNUM_Pos) // 0x00007800 +#define HCCHAR_EPNUM HCCHAR_EPNUM_Msk // Endpoint number +#define HCCHAR_EPNUM_0 (0x1UL << HCCHAR_EPNUM_Pos) // 0x00000800 +#define HCCHAR_EPNUM_1 (0x2UL << HCCHAR_EPNUM_Pos) // 0x00001000 +#define HCCHAR_EPNUM_2 (0x4UL << HCCHAR_EPNUM_Pos) // 0x00002000 +#define HCCHAR_EPNUM_3 (0x8UL << HCCHAR_EPNUM_Pos) // 0x00004000 #define HCCHAR_EPDIR_Pos (15U) -#define HCCHAR_EPDIR_Msk (0x1UL << HCCHAR_EPDIR_Pos) // 0x00008000 */ -#define HCCHAR_EPDIR HCCHAR_EPDIR_Msk // Endpoint direction */ +#define HCCHAR_EPDIR_Msk (0x1UL << HCCHAR_EPDIR_Pos) // 0x00008000 +#define HCCHAR_EPDIR HCCHAR_EPDIR_Msk // Endpoint direction #define HCCHAR_LSDEV_Pos (17U) -#define HCCHAR_LSDEV_Msk (0x1UL << HCCHAR_LSDEV_Pos) // 0x00020000 */ -#define HCCHAR_LSDEV HCCHAR_LSDEV_Msk // Low-speed device */ +#define HCCHAR_LSDEV_Msk (0x1UL << HCCHAR_LSDEV_Pos) // 0x00020000 +#define HCCHAR_LSDEV HCCHAR_LSDEV_Msk // Low-speed device #define HCCHAR_EPTYP_Pos (18U) -#define HCCHAR_EPTYP_Msk (0x3UL << HCCHAR_EPTYP_Pos) // 0x000C0000 */ -#define HCCHAR_EPTYP HCCHAR_EPTYP_Msk // Endpoint type */ -#define HCCHAR_EPTYP_0 (0x1UL << HCCHAR_EPTYP_Pos) // 0x00040000 */ -#define HCCHAR_EPTYP_1 (0x2UL << HCCHAR_EPTYP_Pos) // 0x00080000 */ +#define HCCHAR_EPTYP_Msk (0x3UL << HCCHAR_EPTYP_Pos) // 0x000C0000 +#define HCCHAR_EPTYP HCCHAR_EPTYP_Msk // Endpoint type +#define HCCHAR_EPTYP_0 (0x1UL << HCCHAR_EPTYP_Pos) // 0x00040000 +#define HCCHAR_EPTYP_1 (0x2UL << HCCHAR_EPTYP_Pos) // 0x00080000 #define HCCHAR_MC_Pos (20U) -#define HCCHAR_MC_Msk (0x3UL << HCCHAR_MC_Pos) // 0x00300000 */ -#define HCCHAR_MC HCCHAR_MC_Msk // Multi Count (MC) / Error Count (EC) */ -#define HCCHAR_MC_0 (0x1UL << HCCHAR_MC_Pos) // 0x00100000 */ -#define HCCHAR_MC_1 (0x2UL << HCCHAR_MC_Pos) // 0x00200000 */ +#define HCCHAR_MC_Msk (0x3UL << HCCHAR_MC_Pos) // 0x00300000 +#define HCCHAR_MC HCCHAR_MC_Msk // Multi Count (MC) / Error Count (EC) +#define HCCHAR_MC_0 (0x1UL << HCCHAR_MC_Pos) // 0x00100000 +#define HCCHAR_MC_1 (0x2UL << HCCHAR_MC_Pos) // 0x00200000 #define HCCHAR_DAD_Pos (22U) -#define HCCHAR_DAD_Msk (0x7FUL << HCCHAR_DAD_Pos) // 0x1FC00000 */ -#define HCCHAR_DAD HCCHAR_DAD_Msk // Device address */ -#define HCCHAR_DAD_0 (0x01UL << HCCHAR_DAD_Pos) // 0x00400000 */ -#define HCCHAR_DAD_1 (0x02UL << HCCHAR_DAD_Pos) // 0x00800000 */ -#define HCCHAR_DAD_2 (0x04UL << HCCHAR_DAD_Pos) // 0x01000000 */ -#define HCCHAR_DAD_3 (0x08UL << HCCHAR_DAD_Pos) // 0x02000000 */ -#define HCCHAR_DAD_4 (0x10UL << HCCHAR_DAD_Pos) // 0x04000000 */ -#define HCCHAR_DAD_5 (0x20UL << HCCHAR_DAD_Pos) // 0x08000000 */ -#define HCCHAR_DAD_6 (0x40UL << HCCHAR_DAD_Pos) // 0x10000000 */ +#define HCCHAR_DAD_Msk (0x7FUL << HCCHAR_DAD_Pos) // 0x1FC00000 +#define HCCHAR_DAD HCCHAR_DAD_Msk // Device address +#define HCCHAR_DAD_0 (0x01UL << HCCHAR_DAD_Pos) // 0x00400000 +#define HCCHAR_DAD_1 (0x02UL << HCCHAR_DAD_Pos) // 0x00800000 +#define HCCHAR_DAD_2 (0x04UL << HCCHAR_DAD_Pos) // 0x01000000 +#define HCCHAR_DAD_3 (0x08UL << HCCHAR_DAD_Pos) // 0x02000000 +#define HCCHAR_DAD_4 (0x10UL << HCCHAR_DAD_Pos) // 0x04000000 +#define HCCHAR_DAD_5 (0x20UL << HCCHAR_DAD_Pos) // 0x08000000 +#define HCCHAR_DAD_6 (0x40UL << HCCHAR_DAD_Pos) // 0x10000000 #define HCCHAR_ODDFRM_Pos (29U) -#define HCCHAR_ODDFRM_Msk (0x1UL << HCCHAR_ODDFRM_Pos) // 0x20000000 */ -#define HCCHAR_ODDFRM HCCHAR_ODDFRM_Msk // Odd frame */ +#define HCCHAR_ODDFRM_Msk (0x1UL << HCCHAR_ODDFRM_Pos) // 0x20000000 +#define HCCHAR_ODDFRM HCCHAR_ODDFRM_Msk // Odd frame #define HCCHAR_CHDIS_Pos (30U) -#define HCCHAR_CHDIS_Msk (0x1UL << HCCHAR_CHDIS_Pos) // 0x40000000 */ -#define HCCHAR_CHDIS HCCHAR_CHDIS_Msk // Channel disable */ +#define HCCHAR_CHDIS_Msk (0x1UL << HCCHAR_CHDIS_Pos) // 0x40000000 +#define HCCHAR_CHDIS HCCHAR_CHDIS_Msk // Channel disable #define HCCHAR_CHENA_Pos (31U) -#define HCCHAR_CHENA_Msk (0x1UL << HCCHAR_CHENA_Pos) // 0x80000000 */ -#define HCCHAR_CHENA HCCHAR_CHENA_Msk // Channel enable */ +#define HCCHAR_CHENA_Msk (0x1UL << HCCHAR_CHENA_Pos) // 0x80000000 +#define HCCHAR_CHENA HCCHAR_CHENA_Msk // Channel enable /******************** Bit definition for HCSPLT register ********************/ #define HCSPLT_PRTADDR_Pos (0U) -#define HCSPLT_PRTADDR_Msk (0x7FUL << HCSPLT_PRTADDR_Pos) // 0x0000007F */ -#define HCSPLT_PRTADDR HCSPLT_PRTADDR_Msk // Port address */ -#define HCSPLT_PRTADDR_0 (0x01UL << HCSPLT_PRTADDR_Pos) // 0x00000001 */ -#define HCSPLT_PRTADDR_1 (0x02UL << HCSPLT_PRTADDR_Pos) // 0x00000002 */ -#define HCSPLT_PRTADDR_2 (0x04UL << HCSPLT_PRTADDR_Pos) // 0x00000004 */ -#define HCSPLT_PRTADDR_3 (0x08UL << HCSPLT_PRTADDR_Pos) // 0x00000008 */ -#define HCSPLT_PRTADDR_4 (0x10UL << HCSPLT_PRTADDR_Pos) // 0x00000010 */ -#define HCSPLT_PRTADDR_5 (0x20UL << HCSPLT_PRTADDR_Pos) // 0x00000020 */ -#define HCSPLT_PRTADDR_6 (0x40UL << HCSPLT_PRTADDR_Pos) // 0x00000040 */ +#define HCSPLT_PRTADDR_Msk (0x7FUL << HCSPLT_PRTADDR_Pos) // 0x0000007F +#define HCSPLT_PRTADDR HCSPLT_PRTADDR_Msk // Port address +#define HCSPLT_PRTADDR_0 (0x01UL << HCSPLT_PRTADDR_Pos) // 0x00000001 +#define HCSPLT_PRTADDR_1 (0x02UL << HCSPLT_PRTADDR_Pos) // 0x00000002 +#define HCSPLT_PRTADDR_2 (0x04UL << HCSPLT_PRTADDR_Pos) // 0x00000004 +#define HCSPLT_PRTADDR_3 (0x08UL << HCSPLT_PRTADDR_Pos) // 0x00000008 +#define HCSPLT_PRTADDR_4 (0x10UL << HCSPLT_PRTADDR_Pos) // 0x00000010 +#define HCSPLT_PRTADDR_5 (0x20UL << HCSPLT_PRTADDR_Pos) // 0x00000020 +#define HCSPLT_PRTADDR_6 (0x40UL << HCSPLT_PRTADDR_Pos) // 0x00000040 #define HCSPLT_HUBADDR_Pos (7U) -#define HCSPLT_HUBADDR_Msk (0x7FUL << HCSPLT_HUBADDR_Pos) // 0x00003F80 */ -#define HCSPLT_HUBADDR HCSPLT_HUBADDR_Msk // Hub address */ -#define HCSPLT_HUBADDR_0 (0x01UL << HCSPLT_HUBADDR_Pos) // 0x00000080 */ -#define HCSPLT_HUBADDR_1 (0x02UL << HCSPLT_HUBADDR_Pos) // 0x00000100 */ -#define HCSPLT_HUBADDR_2 (0x04UL << HCSPLT_HUBADDR_Pos) // 0x00000200 */ -#define HCSPLT_HUBADDR_3 (0x08UL << HCSPLT_HUBADDR_Pos) // 0x00000400 */ -#define HCSPLT_HUBADDR_4 (0x10UL << HCSPLT_HUBADDR_Pos) // 0x00000800 */ -#define HCSPLT_HUBADDR_5 (0x20UL << HCSPLT_HUBADDR_Pos) // 0x00001000 */ -#define HCSPLT_HUBADDR_6 (0x40UL << HCSPLT_HUBADDR_Pos) // 0x00002000 */ +#define HCSPLT_HUBADDR_Msk (0x7FUL << HCSPLT_HUBADDR_Pos) // 0x00003F80 +#define HCSPLT_HUBADDR HCSPLT_HUBADDR_Msk // Hub address +#define HCSPLT_HUBADDR_0 (0x01UL << HCSPLT_HUBADDR_Pos) // 0x00000080 +#define HCSPLT_HUBADDR_1 (0x02UL << HCSPLT_HUBADDR_Pos) // 0x00000100 +#define HCSPLT_HUBADDR_2 (0x04UL << HCSPLT_HUBADDR_Pos) // 0x00000200 +#define HCSPLT_HUBADDR_3 (0x08UL << HCSPLT_HUBADDR_Pos) // 0x00000400 +#define HCSPLT_HUBADDR_4 (0x10UL << HCSPLT_HUBADDR_Pos) // 0x00000800 +#define HCSPLT_HUBADDR_5 (0x20UL << HCSPLT_HUBADDR_Pos) // 0x00001000 +#define HCSPLT_HUBADDR_6 (0x40UL << HCSPLT_HUBADDR_Pos) // 0x00002000 #define HCSPLT_XACTPOS_Pos (14U) -#define HCSPLT_XACTPOS_Msk (0x3UL << HCSPLT_XACTPOS_Pos) // 0x0000C000 */ -#define HCSPLT_XACTPOS HCSPLT_XACTPOS_Msk // XACTPOS */ -#define HCSPLT_XACTPOS_0 (0x1UL << HCSPLT_XACTPOS_Pos) // 0x00004000 */ -#define HCSPLT_XACTPOS_1 (0x2UL << HCSPLT_XACTPOS_Pos) // 0x00008000 */ +#define HCSPLT_XACTPOS_Msk (0x3UL << HCSPLT_XACTPOS_Pos) // 0x0000C000 +#define HCSPLT_XACTPOS HCSPLT_XACTPOS_Msk // XACTPOS +#define HCSPLT_XACTPOS_0 (0x1UL << HCSPLT_XACTPOS_Pos) // 0x00004000 +#define HCSPLT_XACTPOS_1 (0x2UL << HCSPLT_XACTPOS_Pos) // 0x00008000 #define HCSPLT_COMPLSPLT_Pos (16U) -#define HCSPLT_COMPLSPLT_Msk (0x1UL << HCSPLT_COMPLSPLT_Pos) // 0x00010000 */ -#define HCSPLT_COMPLSPLT HCSPLT_COMPLSPLT_Msk // Do complete split */ +#define HCSPLT_COMPLSPLT_Msk (0x1UL << HCSPLT_COMPLSPLT_Pos) // 0x00010000 +#define HCSPLT_COMPLSPLT HCSPLT_COMPLSPLT_Msk // Do complete split #define HCSPLT_SPLITEN_Pos (31U) -#define HCSPLT_SPLITEN_Msk (0x1UL << HCSPLT_SPLITEN_Pos) // 0x80000000 */ -#define HCSPLT_SPLITEN HCSPLT_SPLITEN_Msk // Split enable */ +#define HCSPLT_SPLITEN_Msk (0x1UL << HCSPLT_SPLITEN_Pos) // 0x80000000 +#define HCSPLT_SPLITEN HCSPLT_SPLITEN_Msk // Split enable /******************** Bit definition for HCINT register ********************/ #define HCINT_XFRC_Pos (0U) -#define HCINT_XFRC_Msk (0x1UL << HCINT_XFRC_Pos) // 0x00000001 */ -#define HCINT_XFRC HCINT_XFRC_Msk // Transfer completed */ +#define HCINT_XFRC_Msk (0x1UL << HCINT_XFRC_Pos) // 0x00000001 +#define HCINT_XFRC HCINT_XFRC_Msk // Transfer completed #define HCINT_CHH_Pos (1U) -#define HCINT_CHH_Msk (0x1UL << HCINT_CHH_Pos) // 0x00000002 */ -#define HCINT_CHH HCINT_CHH_Msk // Channel halted */ +#define HCINT_CHH_Msk (0x1UL << HCINT_CHH_Pos) // 0x00000002 +#define HCINT_CHH HCINT_CHH_Msk // Channel halted #define HCINT_AHBERR_Pos (2U) -#define HCINT_AHBERR_Msk (0x1UL << HCINT_AHBERR_Pos) // 0x00000004 */ -#define HCINT_AHBERR HCINT_AHBERR_Msk // AHB error */ +#define HCINT_AHBERR_Msk (0x1UL << HCINT_AHBERR_Pos) // 0x00000004 +#define HCINT_AHBERR HCINT_AHBERR_Msk // AHB error #define HCINT_STALL_Pos (3U) -#define HCINT_STALL_Msk (0x1UL << HCINT_STALL_Pos) // 0x00000008 */ -#define HCINT_STALL HCINT_STALL_Msk // STALL response received interrupt */ +#define HCINT_STALL_Msk (0x1UL << HCINT_STALL_Pos) // 0x00000008 +#define HCINT_STALL HCINT_STALL_Msk // STALL response received interrupt #define HCINT_NAK_Pos (4U) -#define HCINT_NAK_Msk (0x1UL << HCINT_NAK_Pos) // 0x00000010 */ -#define HCINT_NAK HCINT_NAK_Msk // NAK response received interrupt */ +#define HCINT_NAK_Msk (0x1UL << HCINT_NAK_Pos) // 0x00000010 +#define HCINT_NAK HCINT_NAK_Msk // NAK response received interrupt #define HCINT_ACK_Pos (5U) -#define HCINT_ACK_Msk (0x1UL << HCINT_ACK_Pos) // 0x00000020 */ -#define HCINT_ACK HCINT_ACK_Msk // ACK response received/transmitted interrupt */ +#define HCINT_ACK_Msk (0x1UL << HCINT_ACK_Pos) // 0x00000020 +#define HCINT_ACK HCINT_ACK_Msk // ACK response received/transmitted interrupt #define HCINT_NYET_Pos (6U) -#define HCINT_NYET_Msk (0x1UL << HCINT_NYET_Pos) // 0x00000040 */ -#define HCINT_NYET HCINT_NYET_Msk // Response received interrupt */ +#define HCINT_NYET_Msk (0x1UL << HCINT_NYET_Pos) // 0x00000040 +#define HCINT_NYET HCINT_NYET_Msk // Response received interrupt #define HCINT_TXERR_Pos (7U) -#define HCINT_TXERR_Msk (0x1UL << HCINT_TXERR_Pos) // 0x00000080 */ -#define HCINT_TXERR HCINT_TXERR_Msk // Transaction error */ +#define HCINT_TXERR_Msk (0x1UL << HCINT_TXERR_Pos) // 0x00000080 +#define HCINT_TXERR HCINT_TXERR_Msk // Transaction error #define HCINT_BBERR_Pos (8U) -#define HCINT_BBERR_Msk (0x1UL << HCINT_BBERR_Pos) // 0x00000100 */ -#define HCINT_BBERR HCINT_BBERR_Msk // Babble error */ +#define HCINT_BBERR_Msk (0x1UL << HCINT_BBERR_Pos) // 0x00000100 +#define HCINT_BBERR HCINT_BBERR_Msk // Babble error #define HCINT_FRMOR_Pos (9U) -#define HCINT_FRMOR_Msk (0x1UL << HCINT_FRMOR_Pos) // 0x00000200 */ -#define HCINT_FRMOR HCINT_FRMOR_Msk // Frame overrun */ +#define HCINT_FRMOR_Msk (0x1UL << HCINT_FRMOR_Pos) // 0x00000200 +#define HCINT_FRMOR HCINT_FRMOR_Msk // Frame overrun #define HCINT_DTERR_Pos (10U) -#define HCINT_DTERR_Msk (0x1UL << HCINT_DTERR_Pos) // 0x00000400 */ -#define HCINT_DTERR HCINT_DTERR_Msk // Data toggle error */ +#define HCINT_DTERR_Msk (0x1UL << HCINT_DTERR_Pos) // 0x00000400 +#define HCINT_DTERR HCINT_DTERR_Msk // Data toggle error /******************** Bit definition for DIEPINT register ********************/ #define DIEPINT_XFRC_Pos (0U) -#define DIEPINT_XFRC_Msk (0x1UL << DIEPINT_XFRC_Pos) // 0x00000001 */ -#define DIEPINT_XFRC DIEPINT_XFRC_Msk // Transfer completed interrupt */ +#define DIEPINT_XFRC_Msk (0x1UL << DIEPINT_XFRC_Pos) // 0x00000001 +#define DIEPINT_XFRC DIEPINT_XFRC_Msk // Transfer completed interrupt #define DIEPINT_EPDISD_Pos (1U) -#define DIEPINT_EPDISD_Msk (0x1UL << DIEPINT_EPDISD_Pos) // 0x00000002 */ -#define DIEPINT_EPDISD DIEPINT_EPDISD_Msk // Endpoint disabled interrupt */ +#define DIEPINT_EPDISD_Msk (0x1UL << DIEPINT_EPDISD_Pos) // 0x00000002 +#define DIEPINT_EPDISD DIEPINT_EPDISD_Msk // Endpoint disabled interrupt #define DIEPINT_AHBERR_Pos (2U) -#define DIEPINT_AHBERR_Msk (0x1UL << DIEPINT_AHBERR_Pos) // 0x00000004 */ -#define DIEPINT_AHBERR DIEPINT_AHBERR_Msk // AHB Error (AHBErr) during an IN transaction */ +#define DIEPINT_AHBERR_Msk (0x1UL << DIEPINT_AHBERR_Pos) // 0x00000004 +#define DIEPINT_AHBERR DIEPINT_AHBERR_Msk // AHB Error (AHBErr) during an IN transaction #define DIEPINT_TOC_Pos (3U) -#define DIEPINT_TOC_Msk (0x1UL << DIEPINT_TOC_Pos) // 0x00000008 */ -#define DIEPINT_TOC DIEPINT_TOC_Msk // Timeout condition */ +#define DIEPINT_TOC_Msk (0x1UL << DIEPINT_TOC_Pos) // 0x00000008 +#define DIEPINT_TOC DIEPINT_TOC_Msk // Timeout condition #define DIEPINT_ITTXFE_Pos (4U) -#define DIEPINT_ITTXFE_Msk (0x1UL << DIEPINT_ITTXFE_Pos) // 0x00000010 */ -#define DIEPINT_ITTXFE DIEPINT_ITTXFE_Msk // IN token received when TxFIFO is empty */ +#define DIEPINT_ITTXFE_Msk (0x1UL << DIEPINT_ITTXFE_Pos) // 0x00000010 +#define DIEPINT_ITTXFE DIEPINT_ITTXFE_Msk // IN token received when TxFIFO is empty #define DIEPINT_INEPNM_Pos (5U) -#define DIEPINT_INEPNM_Msk (0x1UL << DIEPINT_INEPNM_Pos) // 0x00000020 */ -#define DIEPINT_INEPNM DIEPINT_INEPNM_Msk // IN token received with EP mismatch */ +#define DIEPINT_INEPNM_Msk (0x1UL << DIEPINT_INEPNM_Pos) // 0x00000020 +#define DIEPINT_INEPNM DIEPINT_INEPNM_Msk // IN token received with EP mismatch #define DIEPINT_INEPNE_Pos (6U) -#define DIEPINT_INEPNE_Msk (0x1UL << DIEPINT_INEPNE_Pos) // 0x00000040 */ -#define DIEPINT_INEPNE DIEPINT_INEPNE_Msk // IN endpoint NAK effective */ +#define DIEPINT_INEPNE_Msk (0x1UL << DIEPINT_INEPNE_Pos) // 0x00000040 +#define DIEPINT_INEPNE DIEPINT_INEPNE_Msk // IN endpoint NAK effective #define DIEPINT_TXFE_Pos (7U) -#define DIEPINT_TXFE_Msk (0x1UL << DIEPINT_TXFE_Pos) // 0x00000080 */ -#define DIEPINT_TXFE DIEPINT_TXFE_Msk // Transmit FIFO empty */ +#define DIEPINT_TXFE_Msk (0x1UL << DIEPINT_TXFE_Pos) // 0x00000080 +#define DIEPINT_TXFE DIEPINT_TXFE_Msk // Transmit FIFO empty #define DIEPINT_TXFIFOUDRN_Pos (8U) -#define DIEPINT_TXFIFOUDRN_Msk (0x1UL << DIEPINT_TXFIFOUDRN_Pos) // 0x00000100 */ -#define DIEPINT_TXFIFOUDRN DIEPINT_TXFIFOUDRN_Msk // Transmit Fifo Underrun */ +#define DIEPINT_TXFIFOUDRN_Msk (0x1UL << DIEPINT_TXFIFOUDRN_Pos) // 0x00000100 +#define DIEPINT_TXFIFOUDRN DIEPINT_TXFIFOUDRN_Msk // Transmit Fifo Underrun #define DIEPINT_BNA_Pos (9U) -#define DIEPINT_BNA_Msk (0x1UL << DIEPINT_BNA_Pos) // 0x00000200 */ -#define DIEPINT_BNA DIEPINT_BNA_Msk // Buffer not available interrupt */ +#define DIEPINT_BNA_Msk (0x1UL << DIEPINT_BNA_Pos) // 0x00000200 +#define DIEPINT_BNA DIEPINT_BNA_Msk // Buffer not available interrupt #define DIEPINT_PKTDRPSTS_Pos (11U) -#define DIEPINT_PKTDRPSTS_Msk (0x1UL << DIEPINT_PKTDRPSTS_Pos) // 0x00000800 */ -#define DIEPINT_PKTDRPSTS DIEPINT_PKTDRPSTS_Msk // Packet dropped status */ +#define DIEPINT_PKTDRPSTS_Msk (0x1UL << DIEPINT_PKTDRPSTS_Pos) // 0x00000800 +#define DIEPINT_PKTDRPSTS DIEPINT_PKTDRPSTS_Msk // Packet dropped status #define DIEPINT_BERR_Pos (12U) -#define DIEPINT_BERR_Msk (0x1UL << DIEPINT_BERR_Pos) // 0x00001000 */ -#define DIEPINT_BERR DIEPINT_BERR_Msk // Babble error interrupt */ +#define DIEPINT_BERR_Msk (0x1UL << DIEPINT_BERR_Pos) // 0x00001000 +#define DIEPINT_BERR DIEPINT_BERR_Msk // Babble error interrupt #define DIEPINT_NAK_Pos (13U) -#define DIEPINT_NAK_Msk (0x1UL << DIEPINT_NAK_Pos) // 0x00002000 */ -#define DIEPINT_NAK DIEPINT_NAK_Msk // NAK interrupt */ +#define DIEPINT_NAK_Msk (0x1UL << DIEPINT_NAK_Pos) // 0x00002000 +#define DIEPINT_NAK DIEPINT_NAK_Msk // NAK interrupt /******************** Bit definition for HCINTMSK register ********************/ #define HCINTMSK_XFRCM_Pos (0U) -#define HCINTMSK_XFRCM_Msk (0x1UL << HCINTMSK_XFRCM_Pos) // 0x00000001 */ -#define HCINTMSK_XFRCM HCINTMSK_XFRCM_Msk // Transfer completed mask */ +#define HCINTMSK_XFRCM_Msk (0x1UL << HCINTMSK_XFRCM_Pos) // 0x00000001 +#define HCINTMSK_XFRCM HCINTMSK_XFRCM_Msk // Transfer completed mask #define HCINTMSK_CHHM_Pos (1U) -#define HCINTMSK_CHHM_Msk (0x1UL << HCINTMSK_CHHM_Pos) // 0x00000002 */ -#define HCINTMSK_CHHM HCINTMSK_CHHM_Msk // Channel halted mask */ +#define HCINTMSK_CHHM_Msk (0x1UL << HCINTMSK_CHHM_Pos) // 0x00000002 +#define HCINTMSK_CHHM HCINTMSK_CHHM_Msk // Channel halted mask #define HCINTMSK_AHBERR_Pos (2U) -#define HCINTMSK_AHBERR_Msk (0x1UL << HCINTMSK_AHBERR_Pos) // 0x00000004 */ -#define HCINTMSK_AHBERR HCINTMSK_AHBERR_Msk // AHB error */ +#define HCINTMSK_AHBERR_Msk (0x1UL << HCINTMSK_AHBERR_Pos) // 0x00000004 +#define HCINTMSK_AHBERR HCINTMSK_AHBERR_Msk // AHB error #define HCINTMSK_STALLM_Pos (3U) -#define HCINTMSK_STALLM_Msk (0x1UL << HCINTMSK_STALLM_Pos) // 0x00000008 */ -#define HCINTMSK_STALLM HCINTMSK_STALLM_Msk // STALL response received interrupt mask */ +#define HCINTMSK_STALLM_Msk (0x1UL << HCINTMSK_STALLM_Pos) // 0x00000008 +#define HCINTMSK_STALLM HCINTMSK_STALLM_Msk // STALL response received interrupt mask #define HCINTMSK_NAKM_Pos (4U) -#define HCINTMSK_NAKM_Msk (0x1UL << HCINTMSK_NAKM_Pos) // 0x00000010 */ -#define HCINTMSK_NAKM HCINTMSK_NAKM_Msk // NAK response received interrupt mask */ +#define HCINTMSK_NAKM_Msk (0x1UL << HCINTMSK_NAKM_Pos) // 0x00000010 +#define HCINTMSK_NAKM HCINTMSK_NAKM_Msk // NAK response received interrupt mask #define HCINTMSK_ACKM_Pos (5U) -#define HCINTMSK_ACKM_Msk (0x1UL << HCINTMSK_ACKM_Pos) // 0x00000020 */ -#define HCINTMSK_ACKM HCINTMSK_ACKM_Msk // ACK response received/transmitted interrupt mask */ +#define HCINTMSK_ACKM_Msk (0x1UL << HCINTMSK_ACKM_Pos) // 0x00000020 +#define HCINTMSK_ACKM HCINTMSK_ACKM_Msk // ACK response received/transmitted interrupt mask #define HCINTMSK_NYET_Pos (6U) -#define HCINTMSK_NYET_Msk (0x1UL << HCINTMSK_NYET_Pos) // 0x00000040 */ -#define HCINTMSK_NYET HCINTMSK_NYET_Msk // response received interrupt mask */ +#define HCINTMSK_NYET_Msk (0x1UL << HCINTMSK_NYET_Pos) // 0x00000040 +#define HCINTMSK_NYET HCINTMSK_NYET_Msk // response received interrupt mask #define HCINTMSK_TXERRM_Pos (7U) -#define HCINTMSK_TXERRM_Msk (0x1UL << HCINTMSK_TXERRM_Pos) // 0x00000080 */ -#define HCINTMSK_TXERRM HCINTMSK_TXERRM_Msk // Transaction error mask */ +#define HCINTMSK_TXERRM_Msk (0x1UL << HCINTMSK_TXERRM_Pos) // 0x00000080 +#define HCINTMSK_TXERRM HCINTMSK_TXERRM_Msk // Transaction error mask #define HCINTMSK_BBERRM_Pos (8U) -#define HCINTMSK_BBERRM_Msk (0x1UL << HCINTMSK_BBERRM_Pos) // 0x00000100 */ -#define HCINTMSK_BBERRM HCINTMSK_BBERRM_Msk // Babble error mask */ +#define HCINTMSK_BBERRM_Msk (0x1UL << HCINTMSK_BBERRM_Pos) // 0x00000100 +#define HCINTMSK_BBERRM HCINTMSK_BBERRM_Msk // Babble error mask #define HCINTMSK_FRMORM_Pos (9U) -#define HCINTMSK_FRMORM_Msk (0x1UL << HCINTMSK_FRMORM_Pos) // 0x00000200 */ -#define HCINTMSK_FRMORM HCINTMSK_FRMORM_Msk // Frame overrun mask */ +#define HCINTMSK_FRMORM_Msk (0x1UL << HCINTMSK_FRMORM_Pos) // 0x00000200 +#define HCINTMSK_FRMORM HCINTMSK_FRMORM_Msk // Frame overrun mask #define HCINTMSK_DTERRM_Pos (10U) -#define HCINTMSK_DTERRM_Msk (0x1UL << HCINTMSK_DTERRM_Pos) // 0x00000400 */ -#define HCINTMSK_DTERRM HCINTMSK_DTERRM_Msk // Data toggle error mask */ +#define HCINTMSK_DTERRM_Msk (0x1UL << HCINTMSK_DTERRM_Pos) // 0x00000400 +#define HCINTMSK_DTERRM HCINTMSK_DTERRM_Msk // Data toggle error mask /******************** Bit definition for DIEPTSIZ register ********************/ #define DIEPTSIZ_XFRSIZ_Pos (0U) -#define DIEPTSIZ_XFRSIZ_Msk (0x7FFFFUL << DIEPTSIZ_XFRSIZ_Pos) // 0x0007FFFF */ -#define DIEPTSIZ_XFRSIZ DIEPTSIZ_XFRSIZ_Msk // Transfer size */ +#define DIEPTSIZ_XFRSIZ_Msk (0x7FFFFUL << DIEPTSIZ_XFRSIZ_Pos) // 0x0007FFFF +#define DIEPTSIZ_XFRSIZ DIEPTSIZ_XFRSIZ_Msk // Transfer size #define DIEPTSIZ_PKTCNT_Pos (19U) -#define DIEPTSIZ_PKTCNT_Msk (0x3FFUL << DIEPTSIZ_PKTCNT_Pos) // 0x1FF80000 */ -#define DIEPTSIZ_PKTCNT DIEPTSIZ_PKTCNT_Msk // Packet count */ +#define DIEPTSIZ_PKTCNT_Msk (0x3FFUL << DIEPTSIZ_PKTCNT_Pos) // 0x1FF80000 +#define DIEPTSIZ_PKTCNT DIEPTSIZ_PKTCNT_Msk // Packet count #define DIEPTSIZ_MULCNT_Pos (29U) -#define DIEPTSIZ_MULCNT_Msk (0x3UL << DIEPTSIZ_MULCNT_Pos) // 0x60000000 */ -#define DIEPTSIZ_MULCNT DIEPTSIZ_MULCNT_Msk // Packet count */ +#define DIEPTSIZ_MULCNT_Msk (0x3UL << DIEPTSIZ_MULCNT_Pos) // 0x60000000 +#define DIEPTSIZ_MULCNT DIEPTSIZ_MULCNT_Msk // Packet count /******************** Bit definition for HCTSIZ register ********************/ #define HCTSIZ_XFRSIZ_Pos (0U) -#define HCTSIZ_XFRSIZ_Msk (0x7FFFFUL << HCTSIZ_XFRSIZ_Pos) // 0x0007FFFF */ -#define HCTSIZ_XFRSIZ HCTSIZ_XFRSIZ_Msk // Transfer size */ +#define HCTSIZ_XFRSIZ_Msk (0x7FFFFUL << HCTSIZ_XFRSIZ_Pos) // 0x0007FFFF +#define HCTSIZ_XFRSIZ HCTSIZ_XFRSIZ_Msk // Transfer size #define HCTSIZ_PKTCNT_Pos (19U) -#define HCTSIZ_PKTCNT_Msk (0x3FFUL << HCTSIZ_PKTCNT_Pos) // 0x1FF80000 */ -#define HCTSIZ_PKTCNT HCTSIZ_PKTCNT_Msk // Packet count */ +#define HCTSIZ_PKTCNT_Msk (0x3FFUL << HCTSIZ_PKTCNT_Pos) // 0x1FF80000 +#define HCTSIZ_PKTCNT HCTSIZ_PKTCNT_Msk // Packet count #define HCTSIZ_DOPING_Pos (31U) -#define HCTSIZ_DOPING_Msk (0x1UL << HCTSIZ_DOPING_Pos) // 0x80000000 */ -#define HCTSIZ_DOPING HCTSIZ_DOPING_Msk // Do PING */ +#define HCTSIZ_DOPING_Msk (0x1UL << HCTSIZ_DOPING_Pos) // 0x80000000 +#define HCTSIZ_DOPING HCTSIZ_DOPING_Msk // Do PING #define HCTSIZ_DPID_Pos (29U) -#define HCTSIZ_DPID_Msk (0x3UL << HCTSIZ_DPID_Pos) // 0x60000000 */ -#define HCTSIZ_DPID HCTSIZ_DPID_Msk // Data PID */ -#define HCTSIZ_DPID_0 (0x1UL << HCTSIZ_DPID_Pos) // 0x20000000 */ -#define HCTSIZ_DPID_1 (0x2UL << HCTSIZ_DPID_Pos) // 0x40000000 */ +#define HCTSIZ_DPID_Msk (0x3UL << HCTSIZ_DPID_Pos) // 0x60000000 +#define HCTSIZ_DPID HCTSIZ_DPID_Msk // Data PID +#define HCTSIZ_DPID_0 (0x1UL << HCTSIZ_DPID_Pos) // 0x20000000 +#define HCTSIZ_DPID_1 (0x2UL << HCTSIZ_DPID_Pos) // 0x40000000 /******************** Bit definition for DIEPDMA register ********************/ #define DIEPDMA_DMAADDR_Pos (0U) -#define DIEPDMA_DMAADDR_Msk (0xFFFFFFFFUL << DIEPDMA_DMAADDR_Pos) // 0xFFFFFFFF */ -#define DIEPDMA_DMAADDR DIEPDMA_DMAADDR_Msk // DMA address */ +#define DIEPDMA_DMAADDR_Msk (0xFFFFFFFFUL << DIEPDMA_DMAADDR_Pos) // 0xFFFFFFFF +#define DIEPDMA_DMAADDR DIEPDMA_DMAADDR_Msk // DMA address /******************** Bit definition for HCDMA register ********************/ #define HCDMA_DMAADDR_Pos (0U) -#define HCDMA_DMAADDR_Msk (0xFFFFFFFFUL << HCDMA_DMAADDR_Pos) // 0xFFFFFFFF */ -#define HCDMA_DMAADDR HCDMA_DMAADDR_Msk // DMA address */ +#define HCDMA_DMAADDR_Msk (0xFFFFFFFFUL << HCDMA_DMAADDR_Pos) // 0xFFFFFFFF +#define HCDMA_DMAADDR HCDMA_DMAADDR_Msk // DMA address /******************** Bit definition for DTXFSTS register ********************/ #define DTXFSTS_INEPTFSAV_Pos (0U) -#define DTXFSTS_INEPTFSAV_Msk (0xFFFFUL << DTXFSTS_INEPTFSAV_Pos) // 0x0000FFFF */ -#define DTXFSTS_INEPTFSAV DTXFSTS_INEPTFSAV_Msk // IN endpoint TxFIFO space available */ +#define DTXFSTS_INEPTFSAV_Msk (0xFFFFUL << DTXFSTS_INEPTFSAV_Pos) // 0x0000FFFF +#define DTXFSTS_INEPTFSAV DTXFSTS_INEPTFSAV_Msk // IN endpoint TxFIFO space available /******************** Bit definition for DIEPTXF register ********************/ #define DIEPTXF_INEPTXSA_Pos (0U) -#define DIEPTXF_INEPTXSA_Msk (0xFFFFUL << DIEPTXF_INEPTXSA_Pos) // 0x0000FFFF */ -#define DIEPTXF_INEPTXSA DIEPTXF_INEPTXSA_Msk // IN endpoint FIFOx transmit RAM start address */ +#define DIEPTXF_INEPTXSA_Msk (0xFFFFUL << DIEPTXF_INEPTXSA_Pos) // 0x0000FFFF +#define DIEPTXF_INEPTXSA DIEPTXF_INEPTXSA_Msk // IN endpoint FIFOx transmit RAM start address #define DIEPTXF_INEPTXFD_Pos (16U) -#define DIEPTXF_INEPTXFD_Msk (0xFFFFUL << DIEPTXF_INEPTXFD_Pos) // 0xFFFF0000 */ -#define DIEPTXF_INEPTXFD DIEPTXF_INEPTXFD_Msk // IN endpoint TxFIFO depth */ +#define DIEPTXF_INEPTXFD_Msk (0xFFFFUL << DIEPTXF_INEPTXFD_Pos) // 0xFFFF0000 +#define DIEPTXF_INEPTXFD DIEPTXF_INEPTXFD_Msk // IN endpoint TxFIFO depth /******************** Bit definition for DOEPCTL register ********************/ #define DOEPCTL_MPSIZ_Pos (0U) -#define DOEPCTL_MPSIZ_Msk (0x7FFUL << DOEPCTL_MPSIZ_Pos) // 0x000007FF */ -#define DOEPCTL_MPSIZ DOEPCTL_MPSIZ_Msk // Maximum packet size */ //Bit 1 */ +#define DOEPCTL_MPSIZ_Msk (0x7FFUL << DOEPCTL_MPSIZ_Pos) // 0x000007FF +#define DOEPCTL_MPSIZ DOEPCTL_MPSIZ_Msk // Maximum packet size //Bit 1 #define DOEPCTL_USBAEP_Pos (15U) -#define DOEPCTL_USBAEP_Msk (0x1UL << DOEPCTL_USBAEP_Pos) // 0x00008000 */ -#define DOEPCTL_USBAEP DOEPCTL_USBAEP_Msk // USB active endpoint */ +#define DOEPCTL_USBAEP_Msk (0x1UL << DOEPCTL_USBAEP_Pos) // 0x00008000 +#define DOEPCTL_USBAEP DOEPCTL_USBAEP_Msk // USB active endpoint #define DOEPCTL_NAKSTS_Pos (17U) -#define DOEPCTL_NAKSTS_Msk (0x1UL << DOEPCTL_NAKSTS_Pos) // 0x00020000 */ -#define DOEPCTL_NAKSTS DOEPCTL_NAKSTS_Msk // NAK status */ +#define DOEPCTL_NAKSTS_Msk (0x1UL << DOEPCTL_NAKSTS_Pos) // 0x00020000 +#define DOEPCTL_NAKSTS DOEPCTL_NAKSTS_Msk // NAK status #define DOEPCTL_SD0PID_SEVNFRM_Pos (28U) -#define DOEPCTL_SD0PID_SEVNFRM_Msk (0x1UL << DOEPCTL_SD0PID_SEVNFRM_Pos) // 0x10000000 */ -#define DOEPCTL_SD0PID_SEVNFRM DOEPCTL_SD0PID_SEVNFRM_Msk // Set DATA0 PID */ +#define DOEPCTL_SD0PID_SEVNFRM_Msk (0x1UL << DOEPCTL_SD0PID_SEVNFRM_Pos) // 0x10000000 +#define DOEPCTL_SD0PID_SEVNFRM DOEPCTL_SD0PID_SEVNFRM_Msk // Set DATA0 PID #define DOEPCTL_SODDFRM_Pos (29U) -#define DOEPCTL_SODDFRM_Msk (0x1UL << DOEPCTL_SODDFRM_Pos) // 0x20000000 */ -#define DOEPCTL_SODDFRM DOEPCTL_SODDFRM_Msk // Set odd frame */ +#define DOEPCTL_SODDFRM_Msk (0x1UL << DOEPCTL_SODDFRM_Pos) // 0x20000000 +#define DOEPCTL_SODDFRM DOEPCTL_SODDFRM_Msk // Set odd frame #define DOEPCTL_EPTYP_Pos (18U) -#define DOEPCTL_EPTYP_Msk (0x3UL << DOEPCTL_EPTYP_Pos) // 0x000C0000 */ -#define DOEPCTL_EPTYP DOEPCTL_EPTYP_Msk // Endpoint type */ -#define DOEPCTL_EPTYP_0 (0x1UL << DOEPCTL_EPTYP_Pos) // 0x00040000 */ -#define DOEPCTL_EPTYP_1 (0x2UL << DOEPCTL_EPTYP_Pos) // 0x00080000 */ +#define DOEPCTL_EPTYP_Msk (0x3UL << DOEPCTL_EPTYP_Pos) // 0x000C0000 +#define DOEPCTL_EPTYP DOEPCTL_EPTYP_Msk // Endpoint type +#define DOEPCTL_EPTYP_0 (0x1UL << DOEPCTL_EPTYP_Pos) // 0x00040000 +#define DOEPCTL_EPTYP_1 (0x2UL << DOEPCTL_EPTYP_Pos) // 0x00080000 #define DOEPCTL_SNPM_Pos (20U) -#define DOEPCTL_SNPM_Msk (0x1UL << DOEPCTL_SNPM_Pos) // 0x00100000 */ -#define DOEPCTL_SNPM DOEPCTL_SNPM_Msk // Snoop mode */ +#define DOEPCTL_SNPM_Msk (0x1UL << DOEPCTL_SNPM_Pos) // 0x00100000 +#define DOEPCTL_SNPM DOEPCTL_SNPM_Msk // Snoop mode #define DOEPCTL_STALL_Pos (21U) -#define DOEPCTL_STALL_Msk (0x1UL << DOEPCTL_STALL_Pos) // 0x00200000 */ -#define DOEPCTL_STALL DOEPCTL_STALL_Msk // STALL handshake */ +#define DOEPCTL_STALL_Msk (0x1UL << DOEPCTL_STALL_Pos) // 0x00200000 +#define DOEPCTL_STALL DOEPCTL_STALL_Msk // STALL handshake #define DOEPCTL_CNAK_Pos (26U) -#define DOEPCTL_CNAK_Msk (0x1UL << DOEPCTL_CNAK_Pos) // 0x04000000 */ -#define DOEPCTL_CNAK DOEPCTL_CNAK_Msk // Clear NAK */ +#define DOEPCTL_CNAK_Msk (0x1UL << DOEPCTL_CNAK_Pos) // 0x04000000 +#define DOEPCTL_CNAK DOEPCTL_CNAK_Msk // Clear NAK #define DOEPCTL_SNAK_Pos (27U) -#define DOEPCTL_SNAK_Msk (0x1UL << DOEPCTL_SNAK_Pos) // 0x08000000 */ -#define DOEPCTL_SNAK DOEPCTL_SNAK_Msk // Set NAK */ +#define DOEPCTL_SNAK_Msk (0x1UL << DOEPCTL_SNAK_Pos) // 0x08000000 +#define DOEPCTL_SNAK DOEPCTL_SNAK_Msk // Set NAK #define DOEPCTL_EPDIS_Pos (30U) -#define DOEPCTL_EPDIS_Msk (0x1UL << DOEPCTL_EPDIS_Pos) // 0x40000000 */ -#define DOEPCTL_EPDIS DOEPCTL_EPDIS_Msk // Endpoint disable */ +#define DOEPCTL_EPDIS_Msk (0x1UL << DOEPCTL_EPDIS_Pos) // 0x40000000 +#define DOEPCTL_EPDIS DOEPCTL_EPDIS_Msk // Endpoint disable #define DOEPCTL_EPENA_Pos (31U) -#define DOEPCTL_EPENA_Msk (0x1UL << DOEPCTL_EPENA_Pos) // 0x80000000 */ -#define DOEPCTL_EPENA DOEPCTL_EPENA_Msk // Endpoint enable */ +#define DOEPCTL_EPENA_Msk (0x1UL << DOEPCTL_EPENA_Pos) // 0x80000000 +#define DOEPCTL_EPENA DOEPCTL_EPENA_Msk // Endpoint enable /******************** Bit definition for DOEPINT register ********************/ #define DOEPINT_XFRC_Pos (0U) -#define DOEPINT_XFRC_Msk (0x1UL << DOEPINT_XFRC_Pos) // 0x00000001 */ -#define DOEPINT_XFRC DOEPINT_XFRC_Msk // Transfer completed interrupt */ +#define DOEPINT_XFRC_Msk (0x1UL << DOEPINT_XFRC_Pos) // 0x00000001 +#define DOEPINT_XFRC DOEPINT_XFRC_Msk // Transfer completed interrupt #define DOEPINT_EPDISD_Pos (1U) -#define DOEPINT_EPDISD_Msk (0x1UL << DOEPINT_EPDISD_Pos) // 0x00000002 */ -#define DOEPINT_EPDISD DOEPINT_EPDISD_Msk // Endpoint disabled interrupt */ +#define DOEPINT_EPDISD_Msk (0x1UL << DOEPINT_EPDISD_Pos) // 0x00000002 +#define DOEPINT_EPDISD DOEPINT_EPDISD_Msk // Endpoint disabled interrupt #define DOEPINT_AHBERR_Pos (2U) -#define DOEPINT_AHBERR_Msk (0x1UL << DOEPINT_AHBERR_Pos) // 0x00000004 */ -#define DOEPINT_AHBERR DOEPINT_AHBERR_Msk // AHB Error (AHBErr) during an OUT transaction */ +#define DOEPINT_AHBERR_Msk (0x1UL << DOEPINT_AHBERR_Pos) // 0x00000004 +#define DOEPINT_AHBERR DOEPINT_AHBERR_Msk // AHB Error (AHBErr) during an OUT transaction #define DOEPINT_STUP_Pos (3U) -#define DOEPINT_STUP_Msk (0x1UL << DOEPINT_STUP_Pos) // 0x00000008 */ -#define DOEPINT_STUP DOEPINT_STUP_Msk // SETUP phase done */ +#define DOEPINT_STUP_Msk (0x1UL << DOEPINT_STUP_Pos) // 0x00000008 +#define DOEPINT_STUP DOEPINT_STUP_Msk // SETUP phase done #define DOEPINT_OTEPDIS_Pos (4U) -#define DOEPINT_OTEPDIS_Msk (0x1UL << DOEPINT_OTEPDIS_Pos) // 0x00000010 */ -#define DOEPINT_OTEPDIS DOEPINT_OTEPDIS_Msk // OUT token received when endpoint disabled */ +#define DOEPINT_OTEPDIS_Msk (0x1UL << DOEPINT_OTEPDIS_Pos) // 0x00000010 +#define DOEPINT_OTEPDIS DOEPINT_OTEPDIS_Msk // OUT token received when endpoint disabled #define DOEPINT_OTEPSPR_Pos (5U) -#define DOEPINT_OTEPSPR_Msk (0x1UL << DOEPINT_OTEPSPR_Pos) // 0x00000020 */ -#define DOEPINT_OTEPSPR DOEPINT_OTEPSPR_Msk // Status Phase Received For Control Write */ +#define DOEPINT_OTEPSPR_Msk (0x1UL << DOEPINT_OTEPSPR_Pos) // 0x00000020 +#define DOEPINT_OTEPSPR DOEPINT_OTEPSPR_Msk // Status Phase Received For Control Write #define DOEPINT_B2BSTUP_Pos (6U) -#define DOEPINT_B2BSTUP_Msk (0x1UL << DOEPINT_B2BSTUP_Pos) // 0x00000040 */ -#define DOEPINT_B2BSTUP DOEPINT_B2BSTUP_Msk // Back-to-back SETUP packets received */ +#define DOEPINT_B2BSTUP_Msk (0x1UL << DOEPINT_B2BSTUP_Pos) // 0x00000040 +#define DOEPINT_B2BSTUP DOEPINT_B2BSTUP_Msk // Back-to-back SETUP packets received #define DOEPINT_OUTPKTERR_Pos (8U) -#define DOEPINT_OUTPKTERR_Msk (0x1UL << DOEPINT_OUTPKTERR_Pos) // 0x00000100 */ -#define DOEPINT_OUTPKTERR DOEPINT_OUTPKTERR_Msk // OUT packet error */ +#define DOEPINT_OUTPKTERR_Msk (0x1UL << DOEPINT_OUTPKTERR_Pos) // 0x00000100 +#define DOEPINT_OUTPKTERR DOEPINT_OUTPKTERR_Msk // OUT packet error #define DOEPINT_NAK_Pos (13U) -#define DOEPINT_NAK_Msk (0x1UL << DOEPINT_NAK_Pos) // 0x00002000 */ -#define DOEPINT_NAK DOEPINT_NAK_Msk // NAK Packet is transmitted by the device */ +#define DOEPINT_NAK_Msk (0x1UL << DOEPINT_NAK_Pos) // 0x00002000 +#define DOEPINT_NAK DOEPINT_NAK_Msk // NAK Packet is transmitted by the device #define DOEPINT_NYET_Pos (14U) -#define DOEPINT_NYET_Msk (0x1UL << DOEPINT_NYET_Pos) // 0x00004000 */ -#define DOEPINT_NYET DOEPINT_NYET_Msk // NYET interrupt */ +#define DOEPINT_NYET_Msk (0x1UL << DOEPINT_NYET_Pos) // 0x00004000 +#define DOEPINT_NYET DOEPINT_NYET_Msk // NYET interrupt #define DOEPINT_STPKTRX_Pos (15U) -#define DOEPINT_STPKTRX_Msk (0x1UL << DOEPINT_STPKTRX_Pos) // 0x00008000 */ -#define DOEPINT_STPKTRX DOEPINT_STPKTRX_Msk // Setup Packet Received */ +#define DOEPINT_STPKTRX_Msk (0x1UL << DOEPINT_STPKTRX_Pos) // 0x00008000 +#define DOEPINT_STPKTRX DOEPINT_STPKTRX_Msk // Setup Packet Received /******************** Bit definition for DOEPTSIZ register ********************/ #define DOEPTSIZ_XFRSIZ_Pos (0U) -#define DOEPTSIZ_XFRSIZ_Msk (0x7FFFFUL << DOEPTSIZ_XFRSIZ_Pos) // 0x0007FFFF */ -#define DOEPTSIZ_XFRSIZ DOEPTSIZ_XFRSIZ_Msk // Transfer size */ +#define DOEPTSIZ_XFRSIZ_Msk (0x7FFFFUL << DOEPTSIZ_XFRSIZ_Pos) // 0x0007FFFF +#define DOEPTSIZ_XFRSIZ DOEPTSIZ_XFRSIZ_Msk // Transfer size #define DOEPTSIZ_PKTCNT_Pos (19U) -#define DOEPTSIZ_PKTCNT_Msk (0x3FFUL << DOEPTSIZ_PKTCNT_Pos) // 0x1FF80000 */ -#define DOEPTSIZ_PKTCNT DOEPTSIZ_PKTCNT_Msk // Packet count */ +#define DOEPTSIZ_PKTCNT_Msk (0x3FFUL << DOEPTSIZ_PKTCNT_Pos) // 0x1FF80000 +#define DOEPTSIZ_PKTCNT DOEPTSIZ_PKTCNT_Msk // Packet count #define DOEPTSIZ_STUPCNT_Pos (29U) -#define DOEPTSIZ_STUPCNT_Msk (0x3UL << DOEPTSIZ_STUPCNT_Pos) // 0x60000000 */ -#define DOEPTSIZ_STUPCNT DOEPTSIZ_STUPCNT_Msk // SETUP packet count */ -#define DOEPTSIZ_STUPCNT_0 (0x1UL << DOEPTSIZ_STUPCNT_Pos) // 0x20000000 */ -#define DOEPTSIZ_STUPCNT_1 (0x2UL << DOEPTSIZ_STUPCNT_Pos) // 0x40000000 */ +#define DOEPTSIZ_STUPCNT_Msk (0x3UL << DOEPTSIZ_STUPCNT_Pos) // 0x60000000 +#define DOEPTSIZ_STUPCNT DOEPTSIZ_STUPCNT_Msk // SETUP packet count +#define DOEPTSIZ_STUPCNT_0 (0x1UL << DOEPTSIZ_STUPCNT_Pos) // 0x20000000 +#define DOEPTSIZ_STUPCNT_1 (0x2UL << DOEPTSIZ_STUPCNT_Pos) // 0x40000000 /******************** Bit definition for PCGCTL register ********************/ #define PCGCTL_IF_DEV_MODE TU_BIT(31) diff --git a/src/portable/synopsys/dwc2/hwcfg_list.md b/src/portable/synopsys/dwc2/hwcfg_list.md deleted file mode 100644 index b5590da00..000000000 --- a/src/portable/synopsys/dwc2/hwcfg_list.md +++ /dev/null @@ -1,777 +0,0 @@ -# DWC2 Hardware Configuration Registers - -## Broadcom BCM2711 (Pi4) - -dwc2->guid = 2708A000 -dwc2->gsnpsid = 4F54280A -dwc2->ghwcfg1 = 0 - -dwc2->ghwcfg2 = 228DDD50 -hw_cfg2->op_mode = 0 -hw_cfg2->arch = 2 -hw_cfg2->point2point = 0 -hw_cfg2->hs_phy_type = 1 -hw_cfg2->fs_phy_type = 1 -hw_cfg2->num_dev_ep = 7 -hw_cfg2->num_host_ch = 7 -hw_cfg2->period_channel_support = 1 -hw_cfg2->enable_dynamic_fifo = 1 -hw_cfg2->mul_cpu_int = 0 -hw_cfg2->nperiod_tx_q_depth = 2 -hw_cfg2->host_period_tx_q_depth = 2 -hw_cfg2->dev_token_q_depth = 8 -hw_cfg2->otg_enable_ic_usb = 0 - -dwc2->ghwcfg3 = FF000E8 -hw_cfg3->xfer_size_width = 8 -hw_cfg3->packet_size_width = 6 -hw_cfg3->otg_enable = 1 -hw_cfg3->i2c_enable = 0 -hw_cfg3->vendor_ctrl_itf = 0 -hw_cfg3->optional_feature_removed = 0 -hw_cfg3->synch_reset = 0 -hw_cfg3->otg_adp_support = 0 -hw_cfg3->otg_enable_hsic = 0 -hw_cfg3->battery_charger_support = 0 -hw_cfg3->lpm_mode = 0 -hw_cfg3->total_fifo_size = 4080 - -dwc2->ghwcfg4 = 1FF00020 -hw_cfg4->num_dev_period_in_ep = 0 -hw_cfg4->power_optimized = 0 -hw_cfg4->ahb_freq_min = 1 -hw_cfg4->hibernation = 0 -hw_cfg4->service_interval_mode = 0 -hw_cfg4->ipg_isoc_en = 0 -hw_cfg4->acg_enable = 0 -hw_cfg4->utmi_phy_data_width = 0 -hw_cfg4->dev_ctrl_ep_num = 0 -hw_cfg4->iddg_filter_enabled = 1 -hw_cfg4->vbus_valid_filter_enabled = 1 -hw_cfg4->a_valid_filter_enabled = 1 -hw_cfg4->b_valid_filter_enabled = 1 -hw_cfg4->dedicated_fifos = 1 -hw_cfg4->num_dev_in_eps = 15 -hw_cfg4->dma_desc_enable = 0 -hw_cfg4->dma_dynamic = 0 - -## EFM32GG FS - -dwc2->guid = 0 -dwc2->gsnpsid = 4F54330A -dwc2->ghwcfg1 = 0 - -dwc2->ghwcfg2 = 228F5910 -hw_cfg2->op_mode = 0 -hw_cfg2->arch = 2 -hw_cfg2->point2point = 0 -hw_cfg2->hs_phy_type = 0 -hw_cfg2->fs_phy_type = 1 -hw_cfg2->num_dev_ep = 6 -hw_cfg2->num_host_ch = 13 -hw_cfg2->period_channel_support = 1 -hw_cfg2->enable_dynamic_fifo = 1 -hw_cfg2->mul_cpu_int = 0 -hw_cfg2->nperiod_tx_q_depth = 2 -hw_cfg2->host_period_tx_q_depth = 2 -hw_cfg2->dev_token_q_depth = 8 -hw_cfg2->otg_enable_ic_usb = 0 - -dwc2->ghwcfg3 = 1F204E8 -hw_cfg3->xfer_size_width = 8 -hw_cfg3->packet_size_width = 6 -hw_cfg3->otg_enable = 1 -hw_cfg3->i2c_enable = 0 -hw_cfg3->vendor_ctrl_itf = 0 -hw_cfg3->optional_feature_removed = 1 -hw_cfg3->synch_reset = 0 -hw_cfg3->otg_adp_support = 0 -hw_cfg3->otg_enable_hsic = 0 -hw_cfg3->battery_charger_support = 0 -hw_cfg3->lpm_mode = 0 -hw_cfg3->total_fifo_size = 498 - -dwc2->ghwcfg4 = 1BF08030 -hw_cfg4->num_dev_period_in_ep = 0 -hw_cfg4->power_optimized = 1 -hw_cfg4->ahb_freq_min = 1 -hw_cfg4->hibernation = 0 -hw_cfg4->service_interval_mode = 0 -hw_cfg4->ipg_isoc_en = 0 -hw_cfg4->acg_enable = 0 -hw_cfg4->utmi_phy_data_width = 2 -hw_cfg4->dev_ctrl_ep_num = 0 -hw_cfg4->iddg_filter_enabled = 1 -hw_cfg4->vbus_valid_filter_enabled = 1 -hw_cfg4->a_valid_filter_enabled = 1 -hw_cfg4->b_valid_filter_enabled = 1 -hw_cfg4->dedicated_fifos = 1 -hw_cfg4->num_dev_in_eps = 13 -hw_cfg4->dma_desc_enable = 0 -hw_cfg4->dma_dynamic = 0 - -## ESP32-S2 Fullspeed - -dwc2->guid = 0 -dwc2->gsnpsid = 4F54400A -dwc2->ghwcfg1 = 0 - -dwc2->ghwcfg2 = 224DD930 -hw_cfg2->op_mode = 2 -hw_cfg2->arch = 3 -hw_cfg2->point2point = 0 -hw_cfg2->hs_phy_type = 1 -hw_cfg2->fs_phy_type = 2 -hw_cfg2->num_dev_ep = 6 -hw_cfg2->num_host_ch = 9 -hw_cfg2->period_channel_support = 0 -hw_cfg2->enable_dynamic_fifo = 1 -hw_cfg2->mul_cpu_int = 1 -hw_cfg2->nperiod_tx_q_depth = 1 -hw_cfg2->host_period_tx_q_depth = 2 -hw_cfg2->dev_token_q_depth = 22 -hw_cfg2->otg_enable_ic_usb = 0 - -dwc2->ghwcfg3 = C804B5 -hw_cfg3->xfer_size_width = 10 -hw_cfg3->packet_size_width = 5 -hw_cfg3->otg_enable = 0 -hw_cfg3->i2c_enable = 0 -hw_cfg3->vendor_ctrl_itf = 1 -hw_cfg3->optional_feature_removed = 0 -hw_cfg3->synch_reset = 1 -hw_cfg3->otg_adp_support = 1 -hw_cfg3->otg_enable_hsic = 0 -hw_cfg3->battery_charger_support = 1 -hw_cfg3->lpm_mode = 0 -hw_cfg3->total_fifo_size = 23130 - -dwc2->ghwcfg4 = D3F0A030 -hw_cfg4->num_dev_period_in_ep = 10 -hw_cfg4->power_optimized = 1 -hw_cfg4->ahb_freq_min = 0 -hw_cfg4->hibernation = 1 -hw_cfg4->service_interval_mode = 0 -hw_cfg4->ipg_isoc_en = 1 -hw_cfg4->acg_enable = 1 -hw_cfg4->utmi_phy_data_width = 1 -hw_cfg4->dev_ctrl_ep_num = 10 -hw_cfg4->iddg_filter_enabled = 1 -hw_cfg4->vbus_valid_filter_enabled = 0 -hw_cfg4->a_valid_filter_enabled = 1 -hw_cfg4->b_valid_filter_enabled = 0 -hw_cfg4->dedicated_fifos = 0 -hw_cfg4->num_dev_in_eps = 13 -hw_cfg4->dma_desc_enable = 0 -hw_cfg4->dma_dynamic = 1 - -## STM32F407 and STM32F207 - -STM32F407 and STM32F207 are exactly the same - -### STM32F407 Fullspeed - -dwc2->guid = 1200 -dwc2->gsnpsid = 4F54281A -dwc2->ghwcfg1 = 0 - -dwc2->ghwcfg2 = 229DCD20 -hw_cfg2->op_mode = 0 -hw_cfg2->arch = 0 -hw_cfg2->point2point = 1 -hw_cfg2->hs_phy_type = 0 -hw_cfg2->fs_phy_type = 1 -hw_cfg2->num_dev_ep = 3 -hw_cfg2->num_host_ch = 7 -hw_cfg2->period_channel_support = 1 -hw_cfg2->enable_dynamic_fifo = 1 -hw_cfg2->mul_cpu_int = 1 -hw_cfg2->nperiod_tx_q_depth = 2 -hw_cfg2->host_period_tx_q_depth = 2 -hw_cfg2->dev_token_q_depth = 8 -hw_cfg2->otg_enable_ic_usb = 0 - -dwc2->ghwcfg3 = 20001E8 -hw_cfg3->xfer_size_width = 8 -hw_cfg3->packet_size_width = 6 -hw_cfg3->otg_enable = 1 -hw_cfg3->i2c_enable = 1 -hw_cfg3->vendor_ctrl_itf = 0 -hw_cfg3->optional_feature_removed = 0 -hw_cfg3->synch_reset = 0 -hw_cfg3->otg_adp_support = 0 -hw_cfg3->otg_enable_hsic = 0 -hw_cfg3->battery_charger_support = 0 -hw_cfg3->lpm_mode = 0 -hw_cfg3->total_fifo_size = 512 - -dwc2->ghwcfg4 = FF08030 -hw_cfg4->num_dev_period_in_ep = 0 -hw_cfg4->power_optimized = 1 -hw_cfg4->ahb_freq_min = 1 -hw_cfg4->hibernation = 0 -hw_cfg4->service_interval_mode = 0 -hw_cfg4->ipg_isoc_en = 0 -hw_cfg4->acg_enable = 0 -hw_cfg4->utmi_phy_data_width = 2 -hw_cfg4->dev_ctrl_ep_num = 0 -hw_cfg4->iddg_filter_enabled = 1 -hw_cfg4->vbus_valid_filter_enabled = 1 -hw_cfg4->a_valid_filter_enabled = 1 -hw_cfg4->b_valid_filter_enabled = 1 -hw_cfg4->dedicated_fifos = 1 -hw_cfg4->num_dev_in_eps = 7 -hw_cfg4->dma_desc_enable = 0 -hw_cfg4->dma_dynamic = 0 - -### STM32F407 Highspeed - -dwc2->guid = 1100 -dwc2->gsnpsid = 4F54281A -dwc2->ghwcfg1 = 0 - -dwc2->ghwcfg2 = 229ED590 -hw_cfg2->op_mode = 0 -hw_cfg2->arch = 2 -hw_cfg2->point2point = 0 -hw_cfg2->hs_phy_type = 2 -hw_cfg2->fs_phy_type = 1 -hw_cfg2->num_dev_ep = 5 -hw_cfg2->num_host_ch = 11 -hw_cfg2->period_channel_support = 1 -hw_cfg2->enable_dynamic_fifo = 1 -hw_cfg2->mul_cpu_int = 1 -hw_cfg2->nperiod_tx_q_depth = 2 -hw_cfg2->host_period_tx_q_depth = 2 -hw_cfg2->dev_token_q_depth = 8 -hw_cfg2->otg_enable_ic_usb = 0 - -dwc2->ghwcfg3 = 3F403E8 -hw_cfg3->xfer_size_width = 8 -hw_cfg3->packet_size_width = 6 -hw_cfg3->otg_enable = 1 -hw_cfg3->i2c_enable = 1 -hw_cfg3->vendor_ctrl_itf = 1 -hw_cfg3->optional_feature_removed = 0 -hw_cfg3->synch_reset = 0 -hw_cfg3->otg_adp_support = 0 -hw_cfg3->otg_enable_hsic = 0 -hw_cfg3->battery_charger_support = 0 -hw_cfg3->lpm_mode = 0 -hw_cfg3->total_fifo_size = 1012 - -dwc2->ghwcfg4 = 17F00030 -hw_cfg4->num_dev_period_in_ep = 0 -hw_cfg4->power_optimized = 1 -hw_cfg4->ahb_freq_min = 1 -hw_cfg4->hibernation = 0 -hw_cfg4->service_interval_mode = 0 -hw_cfg4->ipg_isoc_en = 0 -hw_cfg4->acg_enable = 0 -hw_cfg4->utmi_phy_data_width = 0 -hw_cfg4->dev_ctrl_ep_num = 0 -hw_cfg4->iddg_filter_enabled = 1 -hw_cfg4->vbus_valid_filter_enabled = 1 -hw_cfg4->a_valid_filter_enabled = 1 -hw_cfg4->b_valid_filter_enabled = 1 -hw_cfg4->dedicated_fifos = 1 -hw_cfg4->num_dev_in_eps = 11 -hw_cfg4->dma_desc_enable = 0 -hw_cfg4->dma_dynamic = 0 - -## STM32F411 Fullspeed - -dwc2->guid = 1200 -dwc2->gsnpsid = 4F54281A -dwc2->ghwcfg1 = 0 - -dwc2->ghwcfg2 = 229DCD20 -hw_cfg2->op_mode = 0 -hw_cfg2->arch = 0 -hw_cfg2->point2point = 1 -hw_cfg2->hs_phy_type = 0 -hw_cfg2->fs_phy_type = 1 -hw_cfg2->num_dev_ep = 3 -hw_cfg2->num_host_ch = 7 -hw_cfg2->period_channel_support = 1 -hw_cfg2->enable_dynamic_fifo = 1 -hw_cfg2->mul_cpu_int = 1 -hw_cfg2->nperiod_tx_q_depth = 2 -hw_cfg2->host_period_tx_q_depth = 2 -hw_cfg2->dev_token_q_depth = 8 -hw_cfg2->otg_enable_ic_usb = 0 - -dwc2->ghwcfg3 = 20001E8 -hw_cfg3->xfer_size_width = 8 -hw_cfg3->packet_size_width = 6 -hw_cfg3->otg_enable = 1 -hw_cfg3->i2c_enable = 1 -hw_cfg3->vendor_ctrl_itf = 0 -hw_cfg3->optional_feature_removed = 0 -hw_cfg3->synch_reset = 0 -hw_cfg3->otg_adp_support = 0 -hw_cfg3->otg_enable_hsic = 0 -hw_cfg3->battery_charger_support = 0 -hw_cfg3->lpm_mode = 0 -hw_cfg3->total_fifo_size = 512 - -dwc2->ghwcfg4 = FF08030 -hw_cfg4->num_dev_period_in_ep = 0 -hw_cfg4->power_optimized = 1 -hw_cfg4->ahb_freq_min = 1 -hw_cfg4->hibernation = 0 -hw_cfg4->service_interval_mode = 0 -hw_cfg4->ipg_isoc_en = 0 -hw_cfg4->acg_enable = 0 -hw_cfg4->utmi_phy_data_width = 2 -hw_cfg4->dev_ctrl_ep_num = 0 -hw_cfg4->iddg_filter_enabled = 1 -hw_cfg4->vbus_valid_filter_enabled = 1 -hw_cfg4->a_valid_filter_enabled = 1 -hw_cfg4->b_valid_filter_enabled = 1 -hw_cfg4->dedicated_fifos = 1 -hw_cfg4->num_dev_in_eps = 7 -hw_cfg4->dma_desc_enable = 0 -hw_cfg4->dma_dynamic = 0 - -## STM32F412 FS - -dwc2->guid = 2000 -dwc2->gsnpsid = 4F54320A -dwc2->ghwcfg1 = 0 - -dwc2->ghwcfg2 = 229ED520 -hw_cfg2->op_mode = 0 -hw_cfg2->arch = 0 -hw_cfg2->point2point = 1 -hw_cfg2->hs_phy_type = 0 -hw_cfg2->fs_phy_type = 1 -hw_cfg2->num_dev_ep = 5 -hw_cfg2->num_host_ch = 11 -hw_cfg2->period_channel_support = 1 -hw_cfg2->enable_dynamic_fifo = 1 -hw_cfg2->mul_cpu_int = 1 -hw_cfg2->nperiod_tx_q_depth = 2 -hw_cfg2->host_period_tx_q_depth = 2 -hw_cfg2->dev_token_q_depth = 8 -hw_cfg2->otg_enable_ic_usb = 0 - -dwc2->ghwcfg3 = 200D1E8 -hw_cfg3->xfer_size_width = 8 -hw_cfg3->packet_size_width = 6 -hw_cfg3->otg_enable = 1 -hw_cfg3->i2c_enable = 1 -hw_cfg3->vendor_ctrl_itf = 0 -hw_cfg3->optional_feature_removed = 0 -hw_cfg3->synch_reset = 0 -hw_cfg3->otg_adp_support = 1 -hw_cfg3->otg_enable_hsic = 0 -hw_cfg3->battery_charger_support = 1 -hw_cfg3->lpm_mode = 1 -hw_cfg3->total_fifo_size = 512 - -dwc2->ghwcfg4 = 17F08030 -hw_cfg4->num_dev_period_in_ep = 0 -hw_cfg4->power_optimized = 1 -hw_cfg4->ahb_freq_min = 1 -hw_cfg4->hibernation = 0 -hw_cfg4->service_interval_mode = 0 -hw_cfg4->ipg_isoc_en = 0 -hw_cfg4->acg_enable = 0 -hw_cfg4->utmi_phy_data_width = 2 -hw_cfg4->dev_ctrl_ep_num = 0 -hw_cfg4->iddg_filter_enabled = 1 -hw_cfg4->vbus_valid_filter_enabled = 1 -hw_cfg4->a_valid_filter_enabled = 1 -hw_cfg4->b_valid_filter_enabled = 1 -hw_cfg4->dedicated_fifos = 1 -hw_cfg4->num_dev_in_eps = 11 -hw_cfg4->dma_desc_enable = 0 -hw_cfg4->dma_dynamic = 0 - -## STM32F723 - -### STM32F723 HighSpeed - -dwc2->guid = 3100 -dwc2->gsnpsid = 4F54330A -dwc2->ghwcfg1 = 0 - -dwc2->ghwcfg2 = 229FE1D0 -hw_cfg2->op_mode = 0 -hw_cfg2->arch = 2 -hw_cfg2->point2point = 0 -hw_cfg2->hs_phy_type = 3 -hw_cfg2->fs_phy_type = 1 -hw_cfg2->num_dev_ep = 8 -hw_cfg2->num_host_ch = 15 -hw_cfg2->period_channel_support = 1 -hw_cfg2->enable_dynamic_fifo = 1 -hw_cfg2->mul_cpu_int = 1 -hw_cfg2->nperiod_tx_q_depth = 2 -hw_cfg2->host_period_tx_q_depth = 2 -hw_cfg2->dev_token_q_depth = 8 -hw_cfg2->otg_enable_ic_usb = 0 - -dwc2->ghwcfg3 = 3EED2E8 -hw_cfg3->xfer_size_width = 8 -hw_cfg3->packet_size_width = 6 -hw_cfg3->otg_enable = 1 -hw_cfg3->i2c_enable = 0 -hw_cfg3->vendor_ctrl_itf = 1 -hw_cfg3->optional_feature_removed = 0 -hw_cfg3->synch_reset = 0 -hw_cfg3->otg_adp_support = 1 -hw_cfg3->otg_enable_hsic = 0 -hw_cfg3->battery_charger_support = 1 -hw_cfg3->lpm_mode = 1 -hw_cfg3->total_fifo_size = 1006 - -dwc2->ghwcfg4 = 23F00030 -hw_cfg4->num_dev_period_in_ep = 0 -hw_cfg4->power_optimized = 1 -hw_cfg4->ahb_freq_min = 1 -hw_cfg4->hibernation = 0 -hw_cfg4->service_interval_mode = 0 -hw_cfg4->ipg_isoc_en = 0 -hw_cfg4->acg_enable = 0 -hw_cfg4->utmi_phy_data_width = 0 -hw_cfg4->dev_ctrl_ep_num = 0 -hw_cfg4->iddg_filter_enabled = 1 -hw_cfg4->vbus_valid_filter_enabled = 1 -hw_cfg4->a_valid_filter_enabled = 1 -hw_cfg4->b_valid_filter_enabled = 1 -hw_cfg4->dedicated_fifos = 1 -hw_cfg4->num_dev_in_eps = 1 -hw_cfg4->dma_desc_enable = 1 -hw_cfg4->dma_dynamic = 0 - -### STM32F723 Fullspeed - -dwc2->guid = 3000 -dwc2->gsnpsid = 4F54330A -dwc2->ghwcfg1 = 0 - -dwc2->ghwcfg2 = 229ED520 -hw_cfg2->op_mode = 0 -hw_cfg2->arch = 0 -hw_cfg2->point2point = 1 -hw_cfg2->hs_phy_type = 0 -hw_cfg2->fs_phy_type = 1 -hw_cfg2->num_dev_ep = 5 -hw_cfg2->num_host_ch = 11 -hw_cfg2->period_channel_support = 1 -hw_cfg2->enable_dynamic_fifo = 1 -hw_cfg2->mul_cpu_int = 1 -hw_cfg2->nperiod_tx_q_depth = 2 -hw_cfg2->host_period_tx_q_depth = 2 -hw_cfg2->dev_token_q_depth = 8 -hw_cfg2->otg_enable_ic_usb = 0 - -dwc2->ghwcfg3 = 200D1E8 -hw_cfg3->xfer_size_width = 8 -hw_cfg3->packet_size_width = 6 -hw_cfg3->otg_enable = 1 -hw_cfg3->i2c_enable = 1 -hw_cfg3->vendor_ctrl_itf = 0 -hw_cfg3->optional_feature_removed = 0 -hw_cfg3->synch_reset = 0 -hw_cfg3->otg_adp_support = 1 -hw_cfg3->otg_enable_hsic = 0 -hw_cfg3->battery_charger_support = 1 -hw_cfg3->lpm_mode = 1 -hw_cfg3->total_fifo_size = 512 - -dwc2->ghwcfg4 = 17F08030 -hw_cfg4->num_dev_period_in_ep = 0 -hw_cfg4->power_optimized = 1 -hw_cfg4->ahb_freq_min = 1 -hw_cfg4->hibernation = 0 -hw_cfg4->service_interval_mode = 0 -hw_cfg4->ipg_isoc_en = 0 -hw_cfg4->acg_enable = 0 -hw_cfg4->utmi_phy_data_width = 2 -hw_cfg4->dev_ctrl_ep_num = 0 -hw_cfg4->iddg_filter_enabled = 1 -hw_cfg4->vbus_valid_filter_enabled = 1 -hw_cfg4->a_valid_filter_enabled = 1 -hw_cfg4->b_valid_filter_enabled = 1 -hw_cfg4->dedicated_fifos = 1 -hw_cfg4->num_dev_in_eps = 11 -hw_cfg4->dma_desc_enable = 0 -hw_cfg4->dma_dynamic = 0 - -## STM32F767 FS - -dwc2->guid = 2000 -dwc2->gsnpsid = 4F54320A -dwc2->ghwcfg1 = 0 - -dwc2->ghwcfg2 = 229ED520 -hw_cfg2->op_mode = 0 -hw_cfg2->arch = 0 -hw_cfg2->point2point = 1 -hw_cfg2->hs_phy_type = 0 -hw_cfg2->fs_phy_type = 1 -hw_cfg2->num_dev_ep = 5 -hw_cfg2->num_host_ch = 11 -hw_cfg2->period_channel_support = 1 -hw_cfg2->enable_dynamic_fifo = 1 -hw_cfg2->mul_cpu_int = 1 -hw_cfg2->nperiod_tx_q_depth = 2 -hw_cfg2->host_period_tx_q_depth = 2 -hw_cfg2->dev_token_q_depth = 8 -hw_cfg2->otg_enable_ic_usb = 0 - -dwc2->ghwcfg3 = 200D1E8 -hw_cfg3->xfer_size_width = 8 -hw_cfg3->packet_size_width = 6 -hw_cfg3->otg_enable = 1 -hw_cfg3->i2c_enable = 1 -hw_cfg3->vendor_ctrl_itf = 0 -hw_cfg3->optional_feature_removed = 0 -hw_cfg3->synch_reset = 0 -hw_cfg3->otg_adp_support = 1 -hw_cfg3->otg_enable_hsic = 0 -hw_cfg3->battery_charger_support = 1 -hw_cfg3->lpm_mode = 1 -hw_cfg3->total_fifo_size = 512 - -dwc2->ghwcfg4 = 17F08030 -hw_cfg4->num_dev_period_in_ep = 0 -hw_cfg4->power_optimized = 1 -hw_cfg4->ahb_freq_min = 1 -hw_cfg4->hibernation = 0 -hw_cfg4->service_interval_mode = 0 -hw_cfg4->ipg_isoc_en = 0 -hw_cfg4->acg_enable = 0 -hw_cfg4->utmi_phy_data_width = 2 -hw_cfg4->dev_ctrl_ep_num = 0 -hw_cfg4->iddg_filter_enabled = 1 -hw_cfg4->vbus_valid_filter_enabled = 1 -hw_cfg4->a_valid_filter_enabled = 1 -hw_cfg4->b_valid_filter_enabled = 1 -hw_cfg4->dedicated_fifos = 1 -hw_cfg4->num_dev_in_eps = 11 -hw_cfg4->dma_desc_enable = 0 -hw_cfg4->dma_dynamic = 0 - -## STM32H743 (both cores HS) - -dwc2->guid = 2300 -dwc2->gsnpsid = 4F54330A -dwc2->ghwcfg1 = 0 - -dwc2->ghwcfg2 = 229FE190 -hw_cfg2->op_mode = 0 -hw_cfg2->arch = 2 -hw_cfg2->point2point = 0 -hw_cfg2->hs_phy_type = 2 -hw_cfg2->fs_phy_type = 1 -hw_cfg2->num_dev_ep = 8 -hw_cfg2->num_host_ch = 15 -hw_cfg2->period_channel_support = 1 -hw_cfg2->enable_dynamic_fifo = 1 -hw_cfg2->mul_cpu_int = 1 -hw_cfg2->nperiod_tx_q_depth = 2 -hw_cfg2->host_period_tx_q_depth = 2 -hw_cfg2->dev_token_q_depth = 8 -hw_cfg2->otg_enable_ic_usb = 0 - -dwc2->ghwcfg3 = 3B8D2E8 -hw_cfg3->xfer_size_width = 8 -hw_cfg3->packet_size_width = 6 -hw_cfg3->otg_enable = 1 -hw_cfg3->i2c_enable = 0 -hw_cfg3->vendor_ctrl_itf = 1 -hw_cfg3->optional_feature_removed = 0 -hw_cfg3->synch_reset = 0 -hw_cfg3->otg_adp_support = 1 -hw_cfg3->otg_enable_hsic = 0 -hw_cfg3->battery_charger_support = 1 -hw_cfg3->lpm_mode = 1 -hw_cfg3->total_fifo_size = 952 - -dwc2->ghwcfg4 = E3F00030 -hw_cfg4->num_dev_period_in_ep = 0 -hw_cfg4->power_optimized = 1 -hw_cfg4->ahb_freq_min = 1 -hw_cfg4->hibernation = 0 -hw_cfg4->service_interval_mode = 0 -hw_cfg4->ipg_isoc_en = 0 -hw_cfg4->acg_enable = 0 -hw_cfg4->utmi_phy_data_width = 0 -hw_cfg4->dev_ctrl_ep_num = 0 -hw_cfg4->iddg_filter_enabled = 1 -hw_cfg4->vbus_valid_filter_enabled = 1 -hw_cfg4->a_valid_filter_enabled = 1 -hw_cfg4->b_valid_filter_enabled = 1 -hw_cfg4->dedicated_fifos = 1 -hw_cfg4->num_dev_in_eps = 1 -hw_cfg4->dma_desc_enable = 1 -hw_cfg4->dma_dynamic = 1 - -## STM32L476 FS - -dwc2->guid = 2000 -dwc2->gsnpsid = 4F54310A -dwc2->ghwcfg1 = 0 - -dwc2->ghwcfg2 = 229ED520 -hw_cfg2->op_mode = 0 -hw_cfg2->arch = 0 -hw_cfg2->point2point = 1 -hw_cfg2->hs_phy_type = 0 -hw_cfg2->fs_phy_type = 1 -hw_cfg2->num_dev_ep = 5 -hw_cfg2->num_host_ch = 11 -hw_cfg2->period_channel_support = 1 -hw_cfg2->enable_dynamic_fifo = 1 -hw_cfg2->mul_cpu_int = 1 -hw_cfg2->nperiod_tx_q_depth = 2 -hw_cfg2->host_period_tx_q_depth = 2 -hw_cfg2->dev_token_q_depth = 8 -hw_cfg2->otg_enable_ic_usb = 0 - -dwc2->ghwcfg3 = 200D1E8 -hw_cfg3->xfer_size_width = 8 -hw_cfg3->packet_size_width = 6 -hw_cfg3->otg_enable = 1 -hw_cfg3->i2c_enable = 1 -hw_cfg3->vendor_ctrl_itf = 0 -hw_cfg3->optional_feature_removed = 0 -hw_cfg3->synch_reset = 0 -hw_cfg3->otg_adp_support = 1 -hw_cfg3->otg_enable_hsic = 0 -hw_cfg3->battery_charger_support = 1 -hw_cfg3->lpm_mode = 1 -hw_cfg3->total_fifo_size = 512 - -dwc2->ghwcfg4 = 17F08030 -hw_cfg4->num_dev_period_in_ep = 0 -hw_cfg4->power_optimized = 1 -hw_cfg4->ahb_freq_min = 1 -hw_cfg4->hibernation = 0 -hw_cfg4->service_interval_mode = 0 -hw_cfg4->ipg_isoc_en = 0 -hw_cfg4->acg_enable = 0 -hw_cfg4->utmi_phy_data_width = 2 -hw_cfg4->dev_ctrl_ep_num = 0 -hw_cfg4->iddg_filter_enabled = 1 -hw_cfg4->vbus_valid_filter_enabled = 1 -hw_cfg4->a_valid_filter_enabled = 1 -hw_cfg4->b_valid_filter_enabled = 1 -hw_cfg4->dedicated_fifos = 1 -hw_cfg4->num_dev_in_eps = 11 -hw_cfg4->dma_desc_enable = 0 -hw_cfg4->dma_dynamic = 0 - -## GD32VF103 Fullspeed - -dwc2->guid = 1000 -dwc2->gsnpsid = 0 -dwc2->ghwcfg1 = 0 - -dwc2->ghwcfg2 = 0 -hw_cfg2->op_mode = 0 -hw_cfg2->arch = 0 -hw_cfg2->point2point = 0 -hw_cfg2->hs_phy_type = 0 -hw_cfg2->fs_phy_type = 0 -hw_cfg2->num_dev_ep = 0 -hw_cfg2->num_host_ch = 0 -hw_cfg2->period_channel_support = 0 -hw_cfg2->enable_dynamic_fifo = 0 -hw_cfg2->mul_cpu_int = 0 -hw_cfg2->nperiod_tx_q_depth = 0 -hw_cfg2->host_period_tx_q_depth = 0 -hw_cfg2->dev_token_q_depth = 0 -hw_cfg2->otg_enable_ic_usb = 0 - -dwc2->ghwcfg3 = 0 -hw_cfg3->xfer_size_width = 0 -hw_cfg3->packet_size_width = 0 -hw_cfg3->otg_enable = 0 -hw_cfg3->i2c_enable = 0 -hw_cfg3->vendor_ctrl_itf = 0 -hw_cfg3->optional_feature_removed = 0 -hw_cfg3->synch_reset = 0 -hw_cfg3->otg_adp_support = 0 -hw_cfg3->otg_enable_hsic = 0 -hw_cfg3->battery_charger_support = 0 -hw_cfg3->lpm_mode = 0 -hw_cfg3->total_fifo_size = 0 - -dwc2->ghwcfg4 = 0 -hw_cfg4->num_dev_period_in_ep = 0 -hw_cfg4->power_optimized = 0 -hw_cfg4->ahb_freq_min = 0 -hw_cfg4->hibernation = 0 -hw_cfg4->service_interval_mode = 0 -hw_cfg4->ipg_isoc_en = 0 -hw_cfg4->acg_enable = 0 -hw_cfg4->utmi_phy_data_width = 0 -hw_cfg4->dev_ctrl_ep_num = 0 -hw_cfg4->iddg_filter_enabled = 0 -hw_cfg4->vbus_valid_filter_enabled = 0 -hw_cfg4->a_valid_filter_enabled = 0 -hw_cfg4->b_valid_filter_enabled = 0 -hw_cfg4->dedicated_fifos = 0 -hw_cfg4->num_dev_in_eps = 0 -hw_cfg4->dma_desc_enable = 0 -hw_cfg4->dma_dynamic = 0 - -## XMC4500 - -dwc2->guid = AEC000 -dwc2->gsnpsid = 4F54292A -dwc2->ghwcfg1 = 0 - -dwc2->ghwcfg2 = 228F5930 -hw_cfg2->op_mode = 0 -hw_cfg2->arch = 2 -hw_cfg2->point2point = 1 -hw_cfg2->hs_phy_type = 0 -hw_cfg2->fs_phy_type = 1 -hw_cfg2->num_dev_ep = 6 -hw_cfg2->num_host_ch = 13 -hw_cfg2->period_channel_support = 1 -hw_cfg2->enable_dynamic_fifo = 1 -hw_cfg2->mul_cpu_int = 0 -hw_cfg2->nperiod_tx_q_depth = 2 -hw_cfg2->host_period_tx_q_depth = 2 -hw_cfg2->dev_token_q_depth = 8 -hw_cfg2->otg_enable_ic_usb = 0 - -dwc2->ghwcfg3 = 27A01E5 -hw_cfg3->xfer_size_width = 5 -hw_cfg3->packet_size_width = 6 -hw_cfg3->otg_enable = 1 -hw_cfg3->i2c_enable = 1 -hw_cfg3->vendor_ctrl_itf = 0 -hw_cfg3->optional_feature_removed = 0 -hw_cfg3->synch_reset = 0 -hw_cfg3->otg_adp_support = 0 -hw_cfg3->otg_enable_hsic = 0 -hw_cfg3->battery_charger_support = 0 -hw_cfg3->lpm_mode = 0 -hw_cfg3->total_fifo_size = 634 - -dwc2->ghwcfg4 = DBF08030 -hw_cfg4->num_dev_period_in_ep = 0 -hw_cfg4->power_optimized = 1 -hw_cfg4->ahb_freq_min = 1 -hw_cfg4->hibernation = 0 -hw_cfg4->service_interval_mode = 0 -hw_cfg4->ipg_isoc_en = 0 -hw_cfg4->acg_enable = 0 -hw_cfg4->utmi_phy_data_width = 2 -hw_cfg4->dev_ctrl_ep_num = 0 -hw_cfg4->iddg_filter_enabled = 1 -hw_cfg4->vbus_valid_filter_enabled = 1 -hw_cfg4->a_valid_filter_enabled = 1 -hw_cfg4->b_valid_filter_enabled = 1 -hw_cfg4->dedicated_fifos = 1 -hw_cfg4->num_dev_in_eps = 13 -hw_cfg4->dma_desc_enable = 0 -hw_cfg4->dma_dynamic = 1 diff --git a/src/portable/template/dcd_template.c b/src/portable/template/dcd_template.c index 590dd9fcf..12d610bd6 100644 --- a/src/portable/template/dcd_template.c +++ b/src/portable/template/dcd_template.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if CFG_TUSB_MCU == OPT_MCU_NONE +#if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_NONE #include "device/dcd.h" @@ -141,4 +141,6 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) (void) ep_addr; } + + #endif diff --git a/src/portable/template/hcd_template.c b/src/portable/template/hcd_template.c new file mode 100644 index 000000000..b073d6057 --- /dev/null +++ b/src/portable/template/hcd_template.c @@ -0,0 +1,163 @@ +/* + * 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. + */ + +#include "tusb_option.h" + +#if CFG_TUH_ENABLED && CFG_TUSB_MCU == OPT_MCU_NONE + +#include "host/hcd.h" + +//--------------------------------------------------------------------+ +// Controller API +//--------------------------------------------------------------------+ + +// optional hcd configuration, called by tuh_configure() +bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { + (void) rhport; + (void) cfg_id; + (void) cfg_param; + + return false; +} + +// Initialize controller to host mode +bool hcd_init(uint8_t rhport) { + (void) rhport; + + return false; +} + +// Interrupt Handler +void hcd_int_handler(uint8_t rhport, bool in_isr) { + (void) rhport; + (void) in_isr; +} + +// Enable USB interrupt +void hcd_int_enable (uint8_t rhport) { + (void) rhport; +} + +// Disable USB interrupt +void hcd_int_disable(uint8_t rhport) { + (void) rhport; +} + +// Get frame number (1ms) +uint32_t hcd_frame_number(uint8_t rhport) { + (void) rhport; + + return 0; +} + +//--------------------------------------------------------------------+ +// Port API +//--------------------------------------------------------------------+ + +// Get the current connect status of roothub port +bool hcd_port_connect_status(uint8_t rhport) { + (void) rhport; + + return false; +} + +// Reset USB bus on the port. Return immediately, bus reset sequence may not be complete. +// Some port would require hcd_port_reset_end() to be invoked after 10ms to complete the reset sequence. +void hcd_port_reset(uint8_t rhport) { + (void) rhport; +} + +// Complete bus reset sequence, may be required by some controllers +void hcd_port_reset_end(uint8_t rhport) { + (void) rhport; +} + +// Get port link speed +tusb_speed_t hcd_port_speed_get(uint8_t rhport) { + (void) rhport; + + return TUSB_SPEED_FULL; +} + +// HCD closes all opened endpoints belong to this device +void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { + (void) rhport; + (void) dev_addr; +} + +//--------------------------------------------------------------------+ +// Endpoints API +//--------------------------------------------------------------------+ + +// Open an endpoint +bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc) { + (void) rhport; + (void) dev_addr; + (void) ep_desc; + + return false; +} + +// 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) { + (void) rhport; + (void) dev_addr; + (void) ep_addr; + (void) buffer; + (void) buflen; + + return false; +} + +// 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) { + (void) rhport; + (void) dev_addr; + (void) ep_addr; + + return false; +} + +// 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]) { + (void) rhport; + (void) dev_addr; + (void) setup_packet; + + return false; +} + +// clear stall, data toggle is also reset to DATA0 +bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { + (void) rhport; + (void) dev_addr; + (void) ep_addr; + + return false; +} + +#endif diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index b4dfda575..8005f5f7b 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -94,7 +94,8 @@ static void bus_reset(void) USBOEPCNT_0 &= ~NAK; USBIEPCNT_0 &= ~NAK; - USBCTL |= FEN; // Enable responding to packets. + // Enable responding to packets. + USBCTL |= FEN; // Dedicated buffers in hardware for SETUP and EP0, no setup needed. // Now safe to respond to SETUP packets. @@ -103,6 +104,28 @@ static void bus_reset(void) USBKEYPID = 0; } +// Controls reset behavior of the USB module on receipt of a bus reset event. +// - enable: When true, bus reset events will cause a reset the USB module. +static void enable_functional_reset(const bool enable) +{ + // Check whether or not the USB configuration registers were + // locked prior to this function being called so that, if + // necessary, the lock state can be restored on exit. + bool unlocked = (USBKEYPID == 0xA528) ? true : false; + + if(!unlocked) USBKEYPID = USBKEY; + + if(enable) + { + USBCTL |= FRSTE; + } + else + { + USBCTL &= ~FRSTE; + } + + if(!unlocked) USBKEYPID = 0; +} /*------------------------------------------------------------------*/ /* Controller API @@ -131,11 +154,14 @@ void dcd_init (uint8_t rhport) USBVECINT = 0; - // Enable reset and wait for it before continuing. - USBIE |= RSTRIE; - - // Enable pullup. - USBCNF |= PUR_EN; + if(USBPWRCTL & USBBGVBV) {// Bus power detected? + USBPWRCTL |= VBOFFIE; // Enable bus-power-removed interrupt. + USBIE |= RSTRIE; // Enable reset and wait for it before continuing. + USBCNF |= PUR_EN; // Enable pullup. + } else { + USBPWRCTL |= VBONIE; // Enable bus-power-applied interrupt. + USBCNF &= ~USB_EN; // Disable USB module until bus power is detected. + } USBKEYPID = 0; } @@ -610,14 +636,76 @@ static void handle_setup_packet(void) _setup_packet[i] = setup_buf[i]; } - // Clearing SETUPIFG by reading USBVECINT does not set NAK, so now that we - // have a SETUP packet, force NAKs until tinyusb can handle the SETUP - // packet and prepare for a new xfer. + // Force NAKs until tinyusb can handle the SETUP packet and prepare for a new xfer. USBIEPCNT_0 |= NAK; USBOEPCNT_0 |= NAK; + + // Clear SETUPIFG to avoid handling in the USBVECINT switch statement. + // When handled there the NAKs applied to the endpoints above are + // cleared by hardware and the host will receive stale/duplicate data. + // + // Excerpt from MSP430x5xx and MSP430x6xx Family User's Guide: + // + // "...the SETUPIFG is cleared upon reading USBIV. In addition, the NAK on + // input endpoint 0 and output endpoint 0 is also cleared." + USBIEPCNF_0 &= ~UBME; // Errata USB10 workaround. + USBOEPCNF_0 &= ~UBME; // Errata USB10 workaround. + USBIFG &= ~SETUPIFG; + USBIEPCNF_0 |= UBME; // Errata USB10 workaround. + USBOEPCNF_0 |= UBME; // Errata USB10 workaround. dcd_event_setup_received(0, (uint8_t*) &_setup_packet[0], true); } +#if CFG_TUSB_OS == OPT_OS_NONE +TU_ATTR_ALWAYS_INLINE static inline void tu_delay(uint32_t ms) { + // msp430 can run up to 25Mhz -> 40ns per cycle. 1 ms = 25000 cycles + // each loop need 4 cycle: 1 sub, 1 cmp, 1 jump, 1 nop + volatile uint32_t cycles = (25000 * ms) >> 2; + while (cycles > 0) { + cycles--; + asm("nop"); + } +} +#else +#define tu_delay(ms) osal_task_delay(ms) +#endif + +static void handle_bus_power_event(void *param) { + (void) param; + + tu_delay(5); // Bus power settling delay. + + USBKEYPID = USBKEY; + + if(USBPWRCTL & USBBGVBV) { // Event caused by application of bus power. + USBPWRCTL |= VBOFFIE; // Enable bus-power-removed interrupt. + USBPLLDIVB = USBPLLDIVB; // For some reason the PLL will *NOT* lock unless the divider + // register is re-written. The assumption here is that this + // register was already properly configured during board-level + // initialization. + USBPLLCTL |= (UPLLEN | UPFDEN); // Enable the PLL. + + uint16_t attempts = 0; + do { // Poll the PLL, checking for a successful lock. + USBPLLIR = 0; + tu_delay(1); + attempts++; + } while ((attempts < 10) && (USBPLLIR != 0)); + + // A successful lock is indicated by all PLL-related interrupt flags being cleared. + if(!USBPLLIR) { + dcd_init(0); // Re-initialize the USB module. + } + } else { // Event caused by removal of bus power. + USBPWRCTL |= VBONIE; // Enable bus-power-applied interrupt. + USBPLLCTL &= ~(UPLLEN | UPFDEN); // Disable the PLL. + USBCNF = 0; // Disable the USB module. + dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, false); + } + + USBKEYPID = 0; +} + void dcd_int_handler(uint8_t rhport) { (void) rhport; @@ -628,6 +716,7 @@ void dcd_int_handler(uint8_t rhport) if(setup_status) { + enable_functional_reset(true); handle_setup_packet(); } @@ -646,11 +735,32 @@ void dcd_int_handler(uint8_t rhport) switch(curr_vector) { + case USBVECINT_NONE: + break; + case USBVECINT_RSTR: + enable_functional_reset(false); // Errata USB4 workaround. bus_reset(); dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); break; + case USBVECINT_PWR_VBUSOn: + case USBVECINT_PWR_VBUSOff: { + USBKEYPID = USBKEY; + // Prevent (possibly) unstable power from generating spurious interrupts. + USBPWRCTL &= ~(VBONIE | VBOFFIE); + USBKEYPID = 0; + + dcd_event_t event; + + event.rhport = 0; + event.event_id = USBD_EVENT_FUNC_CALL; + event.func_call.func = handle_bus_power_event; + + dcd_event_handler(&event, true); + } + break; + // Clear the (hardware-enforced) NAK on EP 0 after a SETUP packet // is received. At this point, even though the hardware is no longer // forcing NAKs, the EP0 NAK bits should still be set to avoid @@ -675,10 +785,12 @@ void dcd_int_handler(uint8_t rhport) break; case USBVECINT_INPUT_ENDPOINT0: + enable_functional_reset(true); transmit_packet(0); break; case USBVECINT_OUTPUT_ENDPOINT0: + enable_functional_reset(true); receive_packet(0); break; @@ -710,7 +822,6 @@ void dcd_int_handler(uint8_t rhport) default: while(true); - break; } } diff --git a/src/portable/wch/ch32v307/ch32_usbhs_reg.h b/src/portable/wch/ch32_usbhs_reg.h similarity index 98% rename from src/portable/wch/ch32v307/ch32_usbhs_reg.h rename to src/portable/wch/ch32_usbhs_reg.h index 5a2c1fbc9..9b956231f 100644 --- a/src/portable/wch/ch32v307/ch32_usbhs_reg.h +++ b/src/portable/wch/ch32_usbhs_reg.h @@ -1,7 +1,11 @@ #ifndef _USB_CH32_USBHS_REG_H #define _USB_CH32_USBHS_REG_H +#if (CFG_TUSB_MCU == OPT_MCU_CH32V307) #include +#elif (CFG_TUSB_MCU == OPT_MCU_CH32F20X) +#include +#endif /******************* GLOBAL ******************/ diff --git a/src/portable/wch/ch32v307/dcd_usbhs.c b/src/portable/wch/dcd_ch32_usbhs.c similarity index 96% rename from src/portable/wch/ch32v307/dcd_usbhs.c rename to src/portable/wch/dcd_ch32_usbhs.c index 3ad011cff..68e2179e9 100644 --- a/src/portable/wch/ch32v307/dcd_usbhs.c +++ b/src/portable/wch/dcd_ch32_usbhs.c @@ -26,11 +26,11 @@ #include "tusb_option.h" -#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_CH32V307) +#if CFG_TUD_ENABLED && ((CFG_TUSB_MCU == OPT_MCU_CH32V307) || (CFG_TUSB_MCU == OPT_MCU_CH32F20X)) #include "device/dcd.h" #include "ch32_usbhs_reg.h" -#include "core_riscv.h" + // Max number of bi-directional endpoints including EP0 #define EP_MAX 16 @@ -73,7 +73,7 @@ void dcd_init(uint8_t rhport) { #if TUD_OPT_HIGH_SPEED USBHSD->CONTROL = USBHS_DMA_EN | USBHS_INT_BUSY_EN | USBHS_HIGH_SPEED; #else - #error OPT_MODE_FULL_SPEED not currently supported on CH32V307 + #error OPT_MODE_FULL_SPEED not currently supported on CH32 USBHSD->CONTROL = USBHS_DMA_EN | USBHS_INT_BUSY_EN | USBHS_FULL_SPEED; #endif @@ -135,6 +135,16 @@ void dcd_remote_wakeup(uint8_t rhport) (void) rhport; } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + if (en) { + USBHSD->INT_EN |= USBHS_SOF_ACT_EN; + } else { + USBHSD->INT_EN &= ~(USBHS_SOF_ACT_EN); + } +} + void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request) { (void)rhport; @@ -332,7 +342,10 @@ void dcd_int_handler(uint8_t rhport) { xfer_ctl_t *xfer = XFER_CTL_BASE(end_num, tu_edpt_dir(endp)); - if (rx_token == PID_OUT) { + if (rx_token == PID_SOF) { + dcd_event_sof(rhport, USBHSD->FRAME_NO, true); + + } else if (rx_token == PID_OUT) { uint16_t rx_len = USBHSD->RX_LEN; receive_packet(xfer, rx_len); diff --git a/src/tinyusb.mk b/src/tinyusb.mk index 85052f90f..89ea0212c 100644 --- a/src/tinyusb.mk +++ b/src/tinyusb.mk @@ -17,3 +17,10 @@ TINYUSB_SRC_C += \ src/class/usbtmc/usbtmc_device.c \ src/class/video/video_device.c \ src/class/vendor/vendor_device.c \ + src/host/usbh.c \ + src/host/hub.c \ + src/class/cdc/cdc_host.c \ + src/class/hid/hid_host.c \ + src/class/msc/msc_host.c \ + src/class/vendor/vendor_host.c \ + src/typec/usbc.c \ diff --git a/src/tusb.c b/src/tusb.c index 465b608b0..0092267a1 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -36,39 +36,37 @@ #endif #if CFG_TUH_ENABLED -#include "host/usbh_classdriver.h" +#include "host/usbh_pvt.h" #endif //--------------------------------------------------------------------+ // Public API //--------------------------------------------------------------------+ -bool tusb_init(void) -{ -#if CFG_TUD_ENABLED && defined(TUD_OPT_RHPORT) +bool tusb_init(void) { + #if CFG_TUD_ENABLED && defined(TUD_OPT_RHPORT) // init device stack CFG_TUSB_RHPORTx_MODE must be defined TU_ASSERT ( tud_init(TUD_OPT_RHPORT) ); -#endif + #endif -#if CFG_TUH_ENABLED && defined(TUH_OPT_RHPORT) + #if CFG_TUH_ENABLED && defined(TUH_OPT_RHPORT) // init host stack CFG_TUSB_RHPORTx_MODE must be defined TU_ASSERT( tuh_init(TUH_OPT_RHPORT) ); -#endif + #endif return true; } -bool tusb_inited(void) -{ +bool tusb_inited(void) { bool ret = false; -#if CFG_TUD_ENABLED + #if CFG_TUD_ENABLED ret = ret || tud_inited(); -#endif + #endif -#if CFG_TUH_ENABLED + #if CFG_TUH_ENABLED ret = ret || tuh_inited(); -#endif + #endif return ret; } @@ -77,43 +75,35 @@ bool tusb_inited(void) // Descriptor helper //--------------------------------------------------------------------+ -uint8_t const * tu_desc_find(uint8_t const* desc, uint8_t const* end, uint8_t byte1) -{ - while(desc+1 < end) - { - if ( desc[1] == byte1 ) return desc; +uint8_t const* tu_desc_find(uint8_t const* desc, uint8_t const* end, uint8_t byte1) { + while (desc + 1 < end) { + if (desc[1] == byte1) return desc; desc += desc[DESC_OFFSET_LEN]; } return NULL; } -uint8_t const * tu_desc_find2(uint8_t const* desc, uint8_t const* end, uint8_t byte1, uint8_t byte2) -{ - while(desc+2 < end) - { - if ( desc[1] == byte1 && desc[2] == byte2) return desc; +uint8_t const* tu_desc_find2(uint8_t const* desc, uint8_t const* end, uint8_t byte1, uint8_t byte2) { + while (desc + 2 < end) { + if (desc[1] == byte1 && desc[2] == byte2) return desc; desc += desc[DESC_OFFSET_LEN]; } return NULL; } -uint8_t const * tu_desc_find3(uint8_t const* desc, uint8_t const* end, uint8_t byte1, uint8_t byte2, uint8_t byte3) -{ - while(desc+3 < end) - { +uint8_t const* tu_desc_find3(uint8_t const* desc, uint8_t const* end, uint8_t byte1, uint8_t byte2, uint8_t byte3) { + while (desc + 3 < end) { if (desc[1] == byte1 && desc[2] == byte2 && desc[3] == byte3) return desc; desc += desc[DESC_OFFSET_LEN]; } return NULL; } - //--------------------------------------------------------------------+ // Endpoint Helper for both Host and Device stack //--------------------------------------------------------------------+ -bool tu_edpt_claim(tu_edpt_state_t* ep_state, osal_mutex_t mutex) -{ +bool tu_edpt_claim(tu_edpt_state_t* ep_state, osal_mutex_t mutex) { (void) mutex; // pre-check to help reducing mutex lock @@ -122,111 +112,93 @@ bool tu_edpt_claim(tu_edpt_state_t* ep_state, osal_mutex_t mutex) // can only claim the endpoint if it is not busy and not claimed yet. bool const available = (ep_state->busy == 0) && (ep_state->claimed == 0); - if (available) - { + if (available) { ep_state->claimed = 1; } (void) osal_mutex_unlock(mutex); - return available; } -bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex) -{ +bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex) { (void) mutex; - (void) osal_mutex_lock(mutex, OSAL_TIMEOUT_WAIT_FOREVER); // can only release the endpoint if it is claimed and not busy bool const ret = (ep_state->claimed == 1) && (ep_state->busy == 0); - if (ret) - { + if (ret) { ep_state->claimed = 0; } (void) osal_mutex_unlock(mutex); - return ret; } -bool tu_edpt_validate(tusb_desc_endpoint_t const * desc_ep, tusb_speed_t speed) -{ +bool tu_edpt_validate(tusb_desc_endpoint_t const* desc_ep, tusb_speed_t speed) { uint16_t const max_packet_size = tu_edpt_packet_size(desc_ep); TU_LOG2(" Open EP %02X with Size = %u\r\n", desc_ep->bEndpointAddress, max_packet_size); - switch (desc_ep->bmAttributes.xfer) - { - case TUSB_XFER_ISOCHRONOUS: - { + switch (desc_ep->bmAttributes.xfer) { + case TUSB_XFER_ISOCHRONOUS: { uint16_t const spec_size = (speed == TUSB_SPEED_HIGH ? 1024 : 1023); TU_ASSERT(max_packet_size <= spec_size); + break; } - break; case TUSB_XFER_BULK: - if (speed == TUSB_SPEED_HIGH) - { + if (speed == TUSB_SPEED_HIGH) { // Bulk highspeed must be EXACTLY 512 TU_ASSERT(max_packet_size == 512); - }else - { + } else { // TODO Bulk fullspeed can only be 8, 16, 32, 64 TU_ASSERT(max_packet_size <= 64); } - break; + break; - case TUSB_XFER_INTERRUPT: - { + case TUSB_XFER_INTERRUPT: { uint16_t const spec_size = (speed == TUSB_SPEED_HIGH ? 1024 : 64); TU_ASSERT(max_packet_size <= spec_size); + break; } - break; - default: return false; + default: + return false; } return true; } -void tu_edpt_bind_driver(uint8_t ep2drv[][2], tusb_desc_interface_t const* desc_itf, uint16_t desc_len, uint8_t driver_id) -{ +void tu_edpt_bind_driver(uint8_t ep2drv[][2], tusb_desc_interface_t const* desc_itf, uint16_t desc_len, + uint8_t driver_id) { uint8_t const* p_desc = (uint8_t const*) desc_itf; uint8_t const* desc_end = p_desc + desc_len; - while( p_desc < desc_end ) - { - if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) ) - { + while (p_desc < desc_end) { + if (TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)) { uint8_t const ep_addr = ((tusb_desc_endpoint_t const*) p_desc)->bEndpointAddress; - TU_LOG(2, " Bind EP %02x to driver id %u\r\n", ep_addr, driver_id); ep2drv[tu_edpt_number(ep_addr)][tu_edpt_dir(ep_addr)] = driver_id; } - p_desc = tu_desc_next(p_desc); } } -uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_t itf_count, uint16_t max_len) -{ +uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_t itf_count, uint16_t max_len) { uint8_t const* p_desc = (uint8_t const*) desc_itf; uint16_t len = 0; - while (itf_count--) - { + while (itf_count--) { // Next on interface desc len += tu_desc_len(desc_itf); p_desc = tu_desc_next(p_desc); - while (len < max_len) - { + while (len < max_len) { // return on IAD regardless of itf count - if ( tu_desc_type(p_desc) == TUSB_DESC_INTERFACE_ASSOCIATION ) return len; - - if ( (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) && - ((tusb_desc_interface_t const*) p_desc)->bAlternateSetting == 0 ) - { + if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE_ASSOCIATION) { + return len; + } + if ((tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) && + ((tusb_desc_interface_t const*) p_desc)->bAlternateSetting == 0) { break; } @@ -243,9 +215,8 @@ uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf, //--------------------------------------------------------------------+ bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool overwritable, - void* ff_buf, uint16_t ff_bufsize, uint8_t* ep_buf, uint16_t ep_bufsize) -{ - osal_mutex_t new_mutex = osal_mutex_create(&s->ff_mutex); + void* ff_buf, uint16_t ff_bufsize, uint8_t* ep_buf, uint16_t ep_bufsize) { + osal_mutex_t new_mutex = osal_mutex_create(&s->ff_mutexdef); (void) new_mutex; (void) is_tx; @@ -259,92 +230,82 @@ bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool ove return true; } +bool tu_edpt_stream_deinit(tu_edpt_stream_t* s) { + (void) s; + #if OSAL_MUTEX_REQUIRED + if (s->ff.mutex_wr) osal_mutex_delete(s->ff.mutex_wr); + if (s->ff.mutex_rd) osal_mutex_delete(s->ff.mutex_rd); + #endif + return true; +} + TU_ATTR_ALWAYS_INLINE static inline -bool stream_claim(tu_edpt_stream_t* s) -{ - if (s->is_host) - { +bool stream_claim(tu_edpt_stream_t* s) { + if (s->is_host) { #if CFG_TUH_ENABLED return usbh_edpt_claim(s->daddr, s->ep_addr); #endif - }else - { + } else { #if CFG_TUD_ENABLED return usbd_edpt_claim(s->rhport, s->ep_addr); #endif } - return false; } TU_ATTR_ALWAYS_INLINE static inline -bool stream_xfer(tu_edpt_stream_t* s, uint16_t count) -{ - if (s->is_host) - { +bool stream_xfer(tu_edpt_stream_t* s, uint16_t count) { + if (s->is_host) { #if CFG_TUH_ENABLED return usbh_edpt_xfer(s->daddr, s->ep_addr, count ? s->ep_buf : NULL, count); #endif - }else - { + } else { #if CFG_TUD_ENABLED return usbd_edpt_xfer(s->rhport, s->ep_addr, count ? s->ep_buf : NULL, count); #endif } - return false; } TU_ATTR_ALWAYS_INLINE static inline -bool stream_release(tu_edpt_stream_t* s) -{ - if (s->is_host) - { +bool stream_release(tu_edpt_stream_t* s) { + if (s->is_host) { #if CFG_TUH_ENABLED return usbh_edpt_release(s->daddr, s->ep_addr); #endif - }else - { + } else { #if CFG_TUD_ENABLED return usbd_edpt_release(s->rhport, s->ep_addr); #endif } - return false; } //--------------------------------------------------------------------+ // Stream Write //--------------------------------------------------------------------+ - -bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t* s, uint32_t last_xferred_bytes) -{ +bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t* s, uint32_t last_xferred_bytes) { // ZLP condition: no pending data, last transferred bytes is multiple of packet size - TU_VERIFY( !tu_fifo_count(&s->ff) && last_xferred_bytes && (0 == (last_xferred_bytes & (s->ep_packetsize-1))) ); - - TU_VERIFY( stream_claim(s) ); - TU_ASSERT( stream_xfer(s, 0) ); - + TU_VERIFY(!tu_fifo_count(&s->ff) && last_xferred_bytes && (0 == (last_xferred_bytes & (s->ep_packetsize - 1)))); + TU_VERIFY(stream_claim(s)); + TU_ASSERT(stream_xfer(s, 0)); return true; } -uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t* s) -{ +uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t* s) { // skip if no data - TU_VERIFY( tu_fifo_count(&s->ff), 0 ); + TU_VERIFY(tu_fifo_count(&s->ff), 0); // Claim the endpoint - TU_VERIFY( stream_claim(s), 0 ); + TU_VERIFY(stream_claim(s), 0); // Pull data from FIFO -> EP buf uint16_t const count = tu_fifo_read_n(&s->ff, s->ep_buf, s->ep_bufsize); - if ( count ) - { - TU_ASSERT( stream_xfer(s, count), 0 ); + if (count) { + TU_ASSERT(stream_xfer(s, count), 0); return count; - }else - { + } else { // Release endpoint since we don't make any transfer // Note: data is dropped if terminal is not connected stream_release(s); @@ -352,16 +313,13 @@ uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t* s) } } -uint32_t tu_edpt_stream_write(tu_edpt_stream_t* s, void const *buffer, uint32_t bufsize) -{ +uint32_t tu_edpt_stream_write(tu_edpt_stream_t* s, void const* buffer, uint32_t bufsize) { TU_VERIFY(bufsize); // TODO support ZLP - uint16_t ret = tu_fifo_write_n(&s->ff, buffer, (uint16_t) bufsize); // flush if fifo has more than packet size or // in rare case: fifo depth is configured too small (which never reach packet size) - if ( (tu_fifo_count(&s->ff) >= s->ep_packetsize) || (tu_fifo_depth(&s->ff) < s->ep_packetsize) ) - { + if ((tu_fifo_count(&s->ff) >= s->ep_packetsize) || (tu_fifo_depth(&s->ff) < s->ep_packetsize)) { tu_edpt_stream_write_xfer(s); } @@ -371,9 +329,7 @@ uint32_t tu_edpt_stream_write(tu_edpt_stream_t* s, void const *buffer, uint32_t //--------------------------------------------------------------------+ // Stream Read //--------------------------------------------------------------------+ - -uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t* s) -{ +uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t* s) { uint16_t available = tu_fifo_remaining(&s->ff); // Prepare for incoming data but only allow what we can store in the ring buffer. @@ -388,25 +344,21 @@ uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t* s) // get available again since fifo can be changed before endpoint is claimed available = tu_fifo_remaining(&s->ff); - if ( available >= s->ep_packetsize ) - { + if (available >= s->ep_packetsize) { // multiple of packet size limit by ep bufsize - uint16_t count = (uint16_t) (available & ~(s->ep_packetsize -1)); + uint16_t count = (uint16_t) (available & ~(s->ep_packetsize - 1)); count = tu_min16(count, s->ep_bufsize); - TU_ASSERT( stream_xfer(s, count), 0 ); - + TU_ASSERT(stream_xfer(s, count), 0); return count; - }else - { + } else { // Release endpoint since we don't make any transfer stream_release(s); return 0; } } -uint32_t tu_edpt_stream_read(tu_edpt_stream_t* s, void* buffer, uint32_t bufsize) -{ +uint32_t tu_edpt_stream_read(tu_edpt_stream_t* s, void* buffer, uint32_t bufsize) { uint32_t num_read = tu_fifo_read_n(&s->ff, buffer, (uint16_t) bufsize); tu_edpt_stream_read_xfer(s); return num_read; @@ -419,43 +371,36 @@ uint32_t tu_edpt_stream_read(tu_edpt_stream_t* s, void* buffer, uint32_t bufsize #if CFG_TUSB_DEBUG #include -#if CFG_TUSB_DEBUG >= 2 - -char const* const tu_str_speed[] = { "Full", "Low", "High" }; -char const* const tu_str_std_request[] = -{ - "Get Status" , - "Clear Feature" , - "Reserved" , - "Set Feature" , - "Reserved" , - "Set Address" , - "Get Descriptor" , - "Set Descriptor" , - "Get Configuration" , - "Set Configuration" , - "Get Interface" , - "Set Interface" , - "Synch Frame" +#if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL || CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL +char const* const tu_str_speed[] = {"Full", "Low", "High"}; +char const* const tu_str_std_request[] = { + "Get Status", + "Clear Feature", + "Reserved", + "Set Feature", + "Reserved", + "Set Address", + "Get Descriptor", + "Set Descriptor", + "Get Configuration", + "Set Configuration", + "Get Interface", + "Set Interface", + "Synch Frame" }; char const* const tu_str_xfer_result[] = { "OK", "FAILED", "STALLED", "TIMEOUT" }; - #endif -static void dump_str_line(uint8_t const* buf, uint16_t count) -{ +static void dump_str_line(uint8_t const* buf, uint16_t count) { tu_printf(" |"); - // each line is 16 bytes - for(uint16_t i=0; i= 900 && CFG_TUSB_MCU < 1000) // check if Espressif MCU // Dialog #define OPT_MCU_DA1469X 1000 ///< Dialog Semiconductor DA1469x @@ -121,6 +135,7 @@ #define OPT_MCU_KINETIS_KL 1200 ///< NXP KL series #define OPT_MCU_KINETIS_K32L 1201 ///< NXP K32L series #define OPT_MCU_KINETIS_K32 1201 ///< Alias to K32L +#define OPT_MCU_KINETIS_K 1202 ///< NXP K series #define OPT_MCU_MKL25ZXX 1200 ///< Alias to KL (obsolete) #define OPT_MCU_K32L2BXX 1201 ///< Alias to K32 (obsolete) @@ -134,7 +149,6 @@ #define OPT_MCU_RX72N 1402 ///< Renesas RX72N #define OPT_MCU_RAXXX 1403 ///< Renesas RAxxx families - // Mind Motion #define OPT_MCU_MM32F327X 1500 ///< Mind Motion MM32F327 @@ -166,15 +180,17 @@ // WCH #define OPT_MCU_CH32V307 2200 ///< WCH CH32V307 +#define OPT_MCU_CH32F20X 2210 ///< WCH CH32F20x // NXP LPC MCX #define OPT_MCU_MCXN9 2300 ///< NXP MCX N9 Series +#define OPT_MCU_MCXA15 2301 ///< NXP MCX A15 Series -// Helper to check if configured MCU is one of listed +// Check if configured MCU is one of listed // Apply _TU_CHECK_MCU with || as separator to list of input -#define _TU_CHECK_MCU(_m) (CFG_TUSB_MCU == _m) -#define TU_CHECK_MCU(...) (TU_ARGS_APPLY(_TU_CHECK_MCU, ||, __VA_ARGS__)) +#define _TU_CHECK_MCU(_m) (CFG_TUSB_MCU == _m) +#define TU_CHECK_MCU(...) (TU_ARGS_APPLY(_TU_CHECK_MCU, ||, __VA_ARGS__)) //--------------------------------------------------------------------+ // Supported OS @@ -295,6 +311,16 @@ #define CFG_TUSB_DEBUG 0 #endif +// 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 + +// 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 + // 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 @@ -338,6 +364,15 @@ #define CFG_TUD_INTERFACE_MAX 16 #endif +//------------- Device Class Driver -------------// +#ifndef CFG_TUD_BTH + #define CFG_TUD_BTH 0 +#endif + +#if CFG_TUD_BTH && !defined(CFG_TUD_BTH_ISO_ALT_COUNT) +#error CFG_TUD_BTH_ISO_ALT_COUNT must be defined to tell Bluetooth driver the number of ISO endpoints to use +#endif + #ifndef CFG_TUD_CDC #define CFG_TUD_CDC 0 #endif @@ -378,10 +413,6 @@ #define CFG_TUD_DFU 0 #endif -#ifndef CFG_TUD_BTH - #define CFG_TUD_BTH 0 -#endif - #ifndef CFG_TUD_ECM_RNDIS #ifdef CFG_TUD_NET #warning "CFG_TUD_NET is renamed to CFG_TUD_ECM_RNDIS" @@ -421,11 +452,11 @@ //------------- CLASS -------------// #ifndef CFG_TUH_HUB -#define CFG_TUH_HUB 0 + #define CFG_TUH_HUB 0 #endif #ifndef CFG_TUH_CDC -#define CFG_TUH_CDC 0 + #define CFG_TUH_CDC 0 #endif #ifndef CFG_TUH_CDC_FTDI @@ -433,40 +464,75 @@ #define CFG_TUH_CDC_FTDI 0 #endif +#ifndef CFG_TUH_CDC_FTDI_VID_PID_LIST + // List of product IDs that can use the FTDI CDC driver. 0x0403 is FTDI's VID + #define CFG_TUH_CDC_FTDI_VID_PID_LIST \ + {0x0403, 0x6001}, {0x0403, 0x6006}, {0x0403, 0x6010}, {0x0403, 0x6011}, \ + {0x0403, 0x6014}, {0x0403, 0x6015}, {0x0403, 0x8372}, {0x0403, 0xFBFA}, \ + {0x0403, 0xCD18} +#endif + #ifndef CFG_TUH_CDC_CP210X // CP210X is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_CDC_CP210X 0 #endif +#ifndef CFG_TUH_CDC_CP210X_VID_PID_LIST + // List of product IDs that can use the CP210X CDC driver. 0x10C4 is Silicon Labs' VID + #define CFG_TUH_CDC_CP210X_VID_PID_LIST \ + {0x10C4, 0xEA60}, {0x10C4, 0xEA70} +#endif + +#ifndef CFG_TUH_CDC_CH34X + // CH34X is not part of CDC class, only to re-use CDC driver API + #define CFG_TUH_CDC_CH34X 0 +#endif + +#ifndef CFG_TUH_CDC_CH34X_VID_PID_LIST + // List of product IDs that can use the CH34X CDC driver + #define CFG_TUH_CDC_CH34X_VID_PID_LIST \ + { 0x1a86, 0x5523 }, /* ch341 chip */ \ + { 0x1a86, 0x7522 }, /* ch340k chip */ \ + { 0x1a86, 0x7523 }, /* ch340 chip */ \ + { 0x1a86, 0xe523 }, /* ch330 chip */ \ + { 0x4348, 0x5523 }, /* ch340 custom chip */ \ + { 0x2184, 0x0057 }, /* overtaken from Linux Kernel driver /drivers/usb/serial/ch341.c */ \ + { 0x9986, 0x7523 } /* overtaken from Linux Kernel driver /drivers/usb/serial/ch341.c */ +#endif + #ifndef CFG_TUH_HID -#define CFG_TUH_HID 0 + #define CFG_TUH_HID 0 #endif #ifndef CFG_TUH_MIDI -#define CFG_TUH_MIDI 0 + #define CFG_TUH_MIDI 0 #endif #ifndef CFG_TUH_MSC -#define CFG_TUH_MSC 0 + #define CFG_TUH_MSC 0 #endif #ifndef CFG_TUH_VENDOR -#define CFG_TUH_VENDOR 0 + #define CFG_TUH_VENDOR 0 #endif #ifndef CFG_TUH_API_EDPT_XFER -#define CFG_TUH_API_EDPT_XFER 0 + #define CFG_TUH_API_EDPT_XFER 0 #endif // Enable PIO-USB software host controller #ifndef CFG_TUH_RPI_PIO_USB -#define CFG_TUH_RPI_PIO_USB 0 + #define CFG_TUH_RPI_PIO_USB 0 #endif #ifndef CFG_TUD_RPI_PIO_USB -#define CFG_TUD_RPI_PIO_USB 0 + #define CFG_TUD_RPI_PIO_USB 0 #endif +// MAX3421 Host controller option +#ifndef CFG_TUH_MAX3421 + #define CFG_TUH_MAX3421 0 +#endif //--------------------------------------------------------------------+ // TypeC Options (Default) diff --git a/test/fuzz/net_fuzz.cc b/test/fuzz/net_fuzz.cc index 63cd1ac98..468437b0c 100644 --- a/test/fuzz/net_fuzz.cc +++ b/test/fuzz/net_fuzz.cc @@ -69,14 +69,6 @@ void tud_network_init_cb(void) { // TODO removed later since it is not part of tinyusb stack uint8_t tud_network_mac_address[6] = {0}; -//------------- NCM -------------// - -// callback to client providing optional indication of internal state of network -// driver -void tud_network_link_state_cb(bool state) { - (void)state; - // NoOp. -} -} +} // extern "C" #endif diff --git a/test/hil/hfp.json b/test/hil/hfp.json new file mode 100644 index 000000000..e79a3cfc9 --- /dev/null +++ b/test/hil/hfp.json @@ -0,0 +1,25 @@ +{ + "boards": [ + { + "name": "stm32l412nucleo", + "uid": "41003B000E504E5457323020", + "flasher": "jlink", + "flasher_sn": "774470029", + "flasher_args": "-device STM32L412KB" + }, + { + "name": "stm32f746disco", + "uid": "210041000C51343237303334", + "flasher": "jlink", + "flasher_sn": "770935966", + "flasher_args": "-device STM32F746NG" + }, + { + "name": "lpcxpresso43s67", + "uid": "08F000044528BAAA8D858F58C50700F5", + "flasher": "jlink", + "flasher_sn": "728973776", + "flasher_args": "-device LPC43S67_M4" + } + ] +} diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py new file mode 100644 index 000000000..dffb81765 --- /dev/null +++ b/test/hil/hil_test.py @@ -0,0 +1,384 @@ +# +# The MIT License (MIT) +# +# Copyright (c) 2023 HiFiPhile +# +# 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. + +# udev rules : +# ACTION=="add", SUBSYSTEM=="tty", SUBSYSTEMS=="usb", MODE="0666", PROGRAM="/bin/sh -c 'echo $$ID_SERIAL_SHORT | rev | cut -c -8 | rev'", SYMLINK+="ttyUSB_%c.%s{bInterfaceNumber}" +# ACTION=="add", SUBSYSTEM=="block", SUBSYSTEMS=="usb", ENV{ID_FS_USAGE}=="filesystem", MODE="0666", PROGRAM="/bin/sh -c 'echo $$ID_SERIAL_SHORT | rev | cut -c -8 | rev'", RUN{program}+="/usr/bin/systemd-mount --no-block --automount=yes --collect $devnode /media/blkUSB_%c.%s{bInterfaceNumber}" + +import os +import sys +import time +import click +import serial +import subprocess +import json +import glob +import platform + +# for RPI double reset +if platform.machine() == 'aarch64': + try: + import gpiozero + except ImportError: + pass + + +ENUM_TIMEOUT = 10 + + +# get usb serial by id +def get_serial_dev(id, vendor_str, product_str, ifnum): + if vendor_str and product_str: + # known vendor and product + vendor_str = vendor_str.replace(' ', '_') + product_str = product_str.replace(' ', '_') + return f'/dev/serial/by-id/usb-{vendor_str}_{product_str}_{id}-if{ifnum:02d}' + else: + # just use id: mostly for cp210x/ftdi flasher + pattern = f'/dev/serial/by-id/usb-*_{id}-if{ifnum:02d}*' + port_list = glob.glob(pattern) + return port_list[0] + + +# Currently not used, left as reference +def get_disk_dev(id, vendor_str, lun): + # get usb disk by id + return f'/dev/disk/by-id/usb-{vendor_str}_Mass_Storage_{id}-0:{lun}' + + +def get_hid_dev(id, vendor_str, product_str, event): + return f'/dev/input/by-id/usb-{vendor_str}_{product_str}_{id}-{event}' + + +def open_serial_dev(port): + timeout = ENUM_TIMEOUT + ser = None + while timeout: + if os.path.exists(port): + try: + # slight delay since kernel may occupy the port briefly + time.sleep(0.5) + timeout = timeout - 0.5 + ser = serial.Serial(port, timeout=1) + break + except serial.SerialException: + pass + time.sleep(0.5) + timeout = timeout - 0.5 + assert timeout, 'Device not available or Cannot open port' + return ser + + +def read_disk_file(id, fname): + # on different self-hosted, the mount point is different + file_list = [ + f'/media/blkUSB_{id[-8:]}.02/{fname}', + f'/media/{os.getenv("USER")}/TinyUSB MSC/{fname}' + ] + timeout = ENUM_TIMEOUT + while timeout: + for file in file_list: + if os.path.isfile(file): + with open(file, 'rb') as f: + data = f.read() + return data + + time.sleep(1) + timeout = timeout - 1 + + assert timeout, 'Device not available' + return None + + +# ------------------------------------------------------------- +# Flashing firmware +# ------------------------------------------------------------- +def run_cmd(cmd): + # print(cmd) + r = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + title = 'command error' + if r.returncode != 0: + # print build output if failed + if os.getenv('CI'): + print(f"::group::{title}") + print(r.stdout.decode("utf-8")) + print(f"::endgroup::") + else: + print(title) + print(r.stdout.decode("utf-8")) + return r + + +def flash_jlink(board, firmware): + script = ['halt', 'r', f'loadfile {firmware}.elf', 'r', 'go', 'exit'] + with open('flash.jlink', 'w') as f: + f.writelines(f'{s}\n' for s in script) + ret = run_cmd(f'JLinkExe -USB {board["flasher_sn"]} {board["flasher_args"]} -if swd -JTAGConf -1,-1 -speed auto -NoGui 1 -ExitOnError 1 -CommandFile flash.jlink') + os.remove('flash.jlink') + return ret + + +def flash_openocd(board, firmware): + ret = run_cmd(f'openocd -c "adapter serial {board["flasher_sn"]}" {board["flasher_args"]} -c "program {firmware}.elf reset exit"') + return ret + + +def flash_esptool(board, firmware): + port = get_serial_dev(board["flasher_sn"], None, None, 0) + dir = os.path.dirname(f'{firmware}.bin') + with open(f'{dir}/config.env') as f: + IDF_TARGET = json.load(f)['IDF_TARGET'] + with open(f'{dir}/flash_args') as f: + flash_args = f.read().strip().replace('\n', ' ') + command = (f'esptool.py --chip {IDF_TARGET} -p {port} {board["flasher_args"]} ' + f'--before=default_reset --after=hard_reset write_flash {flash_args}') + ret = subprocess.run(command, shell=True, cwd=dir, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + return ret + + +def doublereset_with_rpi_gpio(board): + # Off = 0 = Reset + led = gpiozero.LED(board["flasher_reset_pin"]) + + led.off() + time.sleep(0.1) + led.on() + time.sleep(0.1) + led.off() + time.sleep(0.1) + led.on() + + +def flash_bossac(board, firmware): + # double reset to enter bootloader + if platform.machine() == 'aarch64': + doublereset_with_rpi_gpio(board) + + port = get_serial_dev(board["uid"], board["flashser_vendor"], board["flasher_product"], 0) + timeout = ENUM_TIMEOUT + while timeout: + if os.path.exists(port): + break + else: + time.sleep(0.5) + timeout = timeout - 0.5 + assert timeout, 'bossac bootloader is not available' + # sleep a bit more for bootloader to be ready + time.sleep(0.5) + ret = run_cmd(f'bossac --port {port} {board["flasher_args"]} -U -i -R -e -w {firmware}.bin') + return ret + +# ------------------------------------------------------------- +# Tests +# ------------------------------------------------------------- +def test_board_test(id): + # Dummy test + pass + + +def test_cdc_dual_ports(id): + port1 = get_serial_dev(id, 'TinyUSB', "TinyUSB_Device", 0) + port2 = get_serial_dev(id, 'TinyUSB', "TinyUSB_Device", 2) + + ser1 = open_serial_dev(port1) + ser2 = open_serial_dev(port2) + + # Echo test + str1 = b"test_no1" + ser1.write(str1) + ser1.flush() + assert ser1.read(100) == str1.lower(), 'Port1 wrong data' + assert ser2.read(100) == str1.upper(), 'Port2 wrong data' + + str2 = b"test_no2" + ser2.write(str2) + ser2.flush() + assert ser1.read(100) == str2.lower(), 'Port1 wrong data' + assert ser2.read(100) == str2.upper(), 'Port2 wrong data' + + +def test_cdc_msc(id): + # Echo test + port = get_serial_dev(id, 'TinyUSB', "TinyUSB_Device", 0) + ser = open_serial_dev(port) + + str = b"test_str" + ser.write(str) + ser.flush() + assert ser.read(100) == str, 'CDC wrong data' + + # Block test + data = read_disk_file(id, 'README.TXT') + readme = \ + b"This is tinyusb's MassStorage Class demo.\r\n\r\n\ +If you find any bugs or get any questions, feel free to file an\r\n\ +issue at github.com/hathach/tinyusb" + + assert data == readme, 'MSC wrong data' + + +def test_cdc_msc_freertos(id): + test_cdc_msc(id) + + +def test_dfu(id): + # Wait device enum + timeout = ENUM_TIMEOUT + while timeout: + ret = subprocess.run(f'dfu-util -l', + shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + stdout = ret.stdout.decode() + if f'serial="{id}"' in stdout and 'Found DFU: [cafe:4000]' in stdout: + break + time.sleep(1) + timeout = timeout - 1 + + assert timeout, 'Device not available' + + # Test upload + try: + os.remove('dfu0') + os.remove('dfu1') + except OSError: + pass + + ret = subprocess.run(f'dfu-util -S {id} -a 0 -U dfu0', + shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + assert ret.returncode == 0, 'Upload failed' + + ret = subprocess.run(f'dfu-util -S {id} -a 1 -U dfu1', + shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + assert ret.returncode == 0, 'Upload failed' + + with open('dfu0') as f: + assert 'Hello world from TinyUSB DFU! - Partition 0' in f.read(), 'Wrong uploaded data' + + with open('dfu1') as f: + assert 'Hello world from TinyUSB DFU! - Partition 1' in f.read(), 'Wrong uploaded data' + + os.remove('dfu0') + os.remove('dfu1') + + +def test_dfu_runtime(id): + # Wait device enum + timeout = ENUM_TIMEOUT + while timeout: + ret = subprocess.run(f'dfu-util -l', + shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + stdout = ret.stdout.decode() + if f'serial="{id}"' in stdout and 'Found Runtime: [cafe:4000]' in stdout: + break + time.sleep(1) + timeout = timeout - 1 + + assert timeout, 'Device not available' + + +def test_hid_boot_interface(id): + kbd = get_hid_dev(id, 'TinyUSB', 'TinyUSB_Device', 'event-kbd') + mouse1 = get_hid_dev(id, 'TinyUSB', 'TinyUSB_Device', 'if01-event-mouse') + mouse2 = get_hid_dev(id, 'TinyUSB', 'TinyUSB_Device', 'if01-mouse') + # Wait device enum + timeout = ENUM_TIMEOUT + while timeout: + if os.path.exists(kbd) and os.path.exists(mouse1) and os.path.exists(mouse2): + break + time.sleep(1) + timeout = timeout - 1 + + assert timeout, 'Device not available' + + +def test_hid_composite_freertos(id): + # TODO implement later + pass + + +# ------------------------------------------------------------- +# Main +# ------------------------------------------------------------- +@click.command() +@click.argument('config_file') +@click.option('-b', '--board', multiple=True, default=None, help='Boards to test, all if not specified') +def main(config_file, board): + """ + Hardware test on specified boards + """ + config_file = os.path.join(os.path.dirname(__file__), config_file) + with open(config_file) as f: + config = json.load(f) + + # all possible tests + all_tests = [ + 'cdc_dual_ports', 'cdc_msc', 'dfu', 'dfu_runtime', 'hid_boot_interface', + ] + + if len(board) == 0: + config_boards = config['boards'] + else: + config_boards = [e for e in config['boards'] if e['name'] in board] + + for item in config_boards: + name = item['name'] + print(f'Testing board:{name}') + flasher = item['flasher'].lower() + + # default to all tests + if 'tests' in item: + test_list = item['tests'] + else: + test_list = all_tests + + # board_test is added last to disable board's usb + test_list.append('board_test') + + # remove skip_tests + if 'tests_skip' in item: + for skip in item['tests_skip']: + if skip in test_list: + test_list.remove(skip) + + for test in test_list: + fw_name = f'cmake-build/cmake-build-{name}/device/{test}/{test}' + print(f' {test} ...', end='') + + # flash firmware. It may fail randomly, retry a few times + for i in range(3): + ret = globals()[f'flash_{flasher}'](item, fw_name) + if ret.returncode == 0: + break + else: + print(f'Flashing failed, retry {i+1}') + time.sleep(1) + + assert ret.returncode == 0, 'Flash failed\n' + ret.stdout.decode() + + # run test + globals()[f'test_{test}'](item['uid']) + + print('OK') + + +if __name__ == '__main__': + main() diff --git a/test/hil/pi4.json b/test/hil/pi4.json new file mode 100644 index 000000000..04329bb64 --- /dev/null +++ b/test/hil/pi4.json @@ -0,0 +1,27 @@ +{ + "boards": [ + { + "name": "raspberry_pi_pico", + "uid": "E6614C311B764A37", + "flasher": "openocd", + "flasher_sn": "E6614103E72C1D2F", + "flasher_args": "-f interface/cmsis-dap.cfg -f target/rp2040.cfg -c \"adapter speed 5000\"" + }, + { + "name": "feather_nrf52840_express", + "uid": "1F0479CD0F764471", + "flasher": "jlink", + "flasher_sn": "000682804350", + "flasher_args": "-device nrf52840_xxaa" + }, + { + "name": "itsybitsy_m4", + "uid": "D784B28C5338533335202020FF044726", + "flasher": "bossac", + "flashser_vendor": "Adafruit Industries", + "flasher_product": "ItsyBitsy M4 Express", + "flasher_reset_pin": "2", + "flasher_args": "--offset 0x4000" + } + ] +} diff --git a/test/hil/pi4_esp32.json b/test/hil/pi4_esp32.json new file mode 100644 index 000000000..c95dd2d4e --- /dev/null +++ b/test/hil/pi4_esp32.json @@ -0,0 +1,14 @@ +{ + "boards": [ + { + "name": "espressif_s3_devkitm", + "uid": "84F703C084E4", + "tests": [ + "cdc_msc_freertos", "hid_composite_freertos" + ], + "flasher": "esptool", + "flasher_sn": "3ea619acd1cdeb11a0a0b806e93fd3f1", + "flasher_args": "-b 1500000" + } + ] +} diff --git a/test/unit-test/project.yml b/test/unit-test/project.yml index 562dbca09..7fbbabfe6 100644 --- a/test/unit-test/project.yml +++ b/test/unit-test/project.yml @@ -44,12 +44,13 @@ # in order to add common defines: # 1) remove the trailing [] from the :common: section # 2) add entries to the :common: section (e.g. :test: has TEST defined) - :common: &common_defines - - _UNITY_TEST_ + :common: &common_defines [] :test: - - *common_defines + - _UNITY_TEST_ + #- *common_defines :test_preprocess: - - *common_defines + - _UNITY_TEST_ + #- *common_defines :cmock: :mock_prefix: mock_ @@ -80,20 +81,20 @@ :tools: :test_compiler: - :executable: clang - :name: 'clang compiler' + :executable: gcc + :name: 'gcc compiler' :arguments: - -I"$": COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE #expands to -I search paths - -I"$": COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR #expands to -I search paths - -D$: COLLECTION_DEFINES_TEST_AND_VENDOR #expands to all -D defined symbols - - -fsanitize=address + #- -fsanitize=address - -c ${1} #source code input file (Ruby method call param list sub) - -o ${2} #object file output (Ruby method call param list sub) :test_linker: - :executable: clang - :name: 'clang linker' + :executable: gcc + :name: 'gcc linker' :arguments: - - -fsanitize=address + #- -fsanitize=address - ${1} #list of object files to link (Ruby method call param list sub) - -o ${2} #executable file output (Ruby method call param list sub) @@ -106,9 +107,9 @@ :flag: "${1}" # or "-L ${1}" for example :common: &common_libraries [] :test: - - *common_libraries + #- *common_libraries :release: - - *common_libraries + #- *common_libraries :plugins: :load_paths: diff --git a/tools/build.py b/tools/build.py new file mode 100644 index 000000000..884cd56f4 --- /dev/null +++ b/tools/build.py @@ -0,0 +1,177 @@ +import os +import sys +import time +import subprocess +import click +from pathlib import Path +from multiprocessing import Pool + +import build_utils + +SUCCEEDED = "\033[32msucceeded\033[0m" +FAILED = "\033[31mfailed\033[0m" + +build_separator = '-' * 106 + + +def run_cmd(cmd): + #print(cmd) + r = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + title = 'command error' + if r.returncode != 0: + # print build output if failed + if os.getenv('CI'): + print(f"::group::{title}") + print(r.stdout.decode("utf-8")) + print(f"::endgroup::") + else: + print(title) + print(r.stdout.decode("utf-8")) + return r + +def find_family(board): + bsp_dir = Path("hw/bsp") + for family_dir in bsp_dir.iterdir(): + if family_dir.is_dir(): + board_dir = family_dir / 'boards' / board + if board_dir.exists(): + return family_dir.name + return None + + +def get_examples(family): + all_examples = [] + for d in os.scandir("examples"): + if d.is_dir() and 'cmake' not in d.name and 'build_system' not in d.name: + for entry in os.scandir(d.path): + if entry.is_dir() and 'cmake' not in entry.name: + if family != 'espressif' or 'freertos' in entry.name: + all_examples.append(d.name + '/' + entry.name) + + if family == 'espressif': + all_examples.append('device/board_test') + all_examples.append('device/video_capture') + all_examples.sort() + return all_examples + + +def build_board_cmake(board, toolchain): + start_time = time.monotonic() + ret = [0, 0, 0] + + build_dir = f"cmake-build/cmake-build-{board}" + family = find_family(board) + if family == 'espressif': + # for espressif, we have to build example individually + all_examples = get_examples(family) + for example in all_examples: + r = run_cmd(f'cmake examples/{example} -B {build_dir}/{example} -G "Ninja" -DBOARD={board} -DMAX3421_HOST=1') + if r.returncode == 0: + r = run_cmd(f'cmake --build {build_dir}/{example}') + if r.returncode == 0: + ret[0] += 1 + else: + ret[1] += 1 + else: + r = run_cmd(f'cmake examples -B {build_dir} -G "Ninja" -DBOARD={board} -DCMAKE_BUILD_TYPE=MinSizeRel -DTOOLCHAIN={toolchain}') + if r.returncode == 0: + r = run_cmd(f"cmake --build {build_dir}") + if r.returncode == 0: + ret[0] += 1 + else: + ret[1] += 1 + + duration = time.monotonic() - start_time + + if ret[1] == 0: + status = SUCCEEDED + else: + status = FAILED + + flash_size = "-" + sram_size = "-" + example = 'all' + title = build_utils.build_format.format(example, board, status, "{:.2f}s".format(duration), flash_size, sram_size) + print(title) + return ret + + +def build_family(family, toolchain, build_system): + all_boards = [] + for entry in os.scandir(f"hw/bsp/{family}/boards"): + if entry.is_dir() and entry.name != 'pico_sdk': + all_boards.append(entry.name) + all_boards.sort() + + # success, failed, skipped + ret = [0, 0, 0] + if build_system == 'cmake': + for board in all_boards: + if build_board_cmake(board, toolchain): + ret[0] += 1 + else: + ret[1] += 1 + elif build_system == 'make': + all_examples = get_examples(family) + for example in all_examples: + with Pool(processes=os.cpu_count()) as pool: + pool_args = list((map(lambda b, e=example, o=f"TOOLCHAIN={toolchain}": [e, b, o], all_boards))) + r = pool.starmap(build_utils.build_example, pool_args) + # sum all element of same index (column sum) + rsum = list(map(sum, list(zip(*r)))) + ret[0] += rsum[0] + ret[1] += rsum[1] + ret[2] += rsum[2] + return ret + + +@click.command() +@click.argument('families', nargs=-1, required=False) +@click.option('-b', '--board', multiple=True, default=None, help='Boards to build') +@click.option('-t', '--toolchain', default='gcc', help='Toolchain to use, default is gcc') +@click.option('-s', '--build-system', default='cmake', help='Build system to use, default is cmake') +def main(families, board, toolchain, build_system): + if len(families) == 0 and len(board) == 0: + print("Please specify families or board to build") + return 1 + + print(build_separator) + print(build_utils.build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) + total_time = time.monotonic() + total_result = [0, 0, 0] + + # build families: cmake, make + if families is not None: + all_families = [] + if 'all' in families: + for entry in os.scandir("hw/bsp"): + if entry.is_dir() and entry.name != 'espressif' and os.path.isfile(entry.path + "/family.cmake"): + all_families.append(entry.name) + else: + all_families = list(families) + all_families.sort() + + # succeeded, failed + for f in all_families: + fret = build_family(f, toolchain, build_system) + total_result[0] += fret[0] + total_result[1] += fret[1] + total_result[2] += fret[2] + + # build board (only cmake) + if board is not None: + for b in board: + r = build_board_cmake(b, toolchain) + total_result[0] += r[0] + total_result[1] += r[1] + total_result[2] += r[2] + + total_time = time.monotonic() - total_time + print(build_separator) + print(f"Build Summary: {total_result[0]} {SUCCEEDED}, {total_result[1]} {FAILED} and took {total_time:.2f}s") + print(build_separator) + return total_result[1] + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/tools/build_board.py b/tools/build_board.py deleted file mode 100644 index 13376d126..000000000 --- a/tools/build_board.py +++ /dev/null @@ -1,69 +0,0 @@ -import os -import sys -import time -import subprocess -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 - - -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 - - -if __name__ == '__main__': - # If examples are not specified in arguments, build all - all_examples = [] - for dir1 in os.scandir("examples"): - if dir1.is_dir(): - for entry in os.scandir(dir1.path): - if entry.is_dir(): - all_examples.append(dir1.name + '/' + entry.name) - filter_with_input(all_examples) - all_examples.sort() - - # If boards are not specified in arguments, build all - all_boards = [] - for entry in os.scandir("hw/bsp"): - if entry.is_dir() and os.path.exists(entry.path + "/board.mk"): - all_boards.append(entry.name) - filter_with_input(all_boards) - all_boards.sort() - - # Get dependencies - for b in all_boards: - subprocess.run("make -C examples/device/board_test BOARD={} get-deps".format(b), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - - 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 example in all_examples: - print(build_separator) - with Pool(processes=os.cpu_count()) as pool: - pool_args = list((map(lambda b, e=example, o='': [e, b, o], all_boards))) - result = pool.starmap(build_utils.build_example, pool_args) - # sum all element of same index (column sum) - result = list(map(sum, list(zip(*result)))) - - # add to total result - total_result = list(map(lambda x, y: x + y, total_result, result)) - - 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]) diff --git a/tools/build_cmake.py b/tools/build_cmake.py deleted file mode 100644 index e539b9f94..000000000 --- a/tools/build_cmake.py +++ /dev/null @@ -1,105 +0,0 @@ -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 - -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, cmake_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() - - build_dir = f"cmake-build/cmake-build-{board}" - - # Generate build - r = subprocess.run(f"cmake examples -B {build_dir} -G \"Ninja\" -DFAMILY={family} -DBOARD" - f"={board} {cmake_option}", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - - # Build - if r.returncode == 0: - r = subprocess.run(f"cmake --build {build_dir}", 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' - title = build_utils.build_format.format(example, board, status, "{:.2f}s".format(duration), flash_size, sram_size) - - if os.getenv('CI'): - # always print build output if in CI - print(f"::group::{title}") - print(r.stdout.decode("utf-8")) - print(f"::endgroup::") - else: - # print build output if failed - print(title) - if r.returncode != 0: - print(r.stdout.decode("utf-8")) - - return ret - - -if __name__ == '__main__': - cmake_options = '' - for a in sys.argv[1:]: - if a.startswith('-'): - cmake_options += ' ' + a - - # If family are not specified in arguments, build all supported - all_families = [] - for entry in os.scandir("hw/bsp"): - if entry.is_dir() and entry.name != 'espressif' and os.path.isfile(entry.path + "/family.cmake"): - 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, cmake_options) - 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]) diff --git a/tools/build_esp32.py b/tools/build_esp32.py index 00783bf58..951467c23 100644 --- a/tools/build_esp32.py +++ b/tools/build_esp32.py @@ -17,8 +17,8 @@ exit_status = 0 total_time = time.monotonic() -build_format = '| {:23} | {:30} | {:18} | {:7} | {:6} | {:6} |' -build_separator = '-' * 100 +build_format = '| {:30} | {:30} | {:18} | {:7} | {:6} | {:6} |' +build_separator = '-' * 107 def filter_with_input(mylist): if len(sys.argv) > 1: @@ -26,13 +26,11 @@ def filter_with_input(mylist): if len(input_args) > 0: mylist[:] = input_args + # Build all examples if not specified -all_examples = [] -for entry in os.scandir("examples/device"): - # Only includes example with CMakeLists.txt for esp32s, and skip board_test to speed up ci - if entry.is_dir() and os.path.exists(entry.path + "/sdkconfig.defaults") and entry.name != 'board_test': - all_examples.append(entry.name) +all_examples = [entry.replace('examples/', '') for entry in glob.glob("examples/*/*_freertos")] filter_with_input(all_examples) +all_examples.append('device/board_test') all_examples.sort() # Build all boards if not specified @@ -46,32 +44,41 @@ all_boards.sort() def build_board(example, board): global success_count, fail_count, skip_count, exit_status start_time = time.monotonic() + + # Check if board is skipped + build_dir = f"cmake-build/cmake-build-{board}/{example}" + + # Generate and build + r = subprocess.run(f"cmake examples/{example} -B {build_dir} -G \"Ninja\" -DBOARD={board} -DMAX3421_HOST=1", + shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + if r.returncode == 0: + r = subprocess.run(f"cmake --build {build_dir}", shell=True, stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + build_duration = time.monotonic() - start_time flash_size = "-" sram_size = "-" - # Check if board is skipped - if build_utils.skip_example(example, board): - success = SKIPPED - skip_count += 1 - print(build_format.format(example, board, success, '-', flash_size, sram_size)) + if r.returncode == 0: + success = SUCCEEDED + success_count += 1 + #(flash_size, sram_size) = build_size(example, board) else: - subprocess.run("make -C examples/device/{} BOARD={} clean".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - build_result = subprocess.run("make -j -C examples/device/{} BOARD={} all".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + exit_status = r.returncode + success = FAILED + fail_count += 1 - if build_result.returncode == 0: - success = SUCCEEDED - success_count += 1 - (flash_size, sram_size) = build_size(example, board) - else: - exit_status = build_result.returncode - success = FAILED - fail_count += 1 + title = build_format.format(example, board, success, "{:.2f}s".format(build_duration), flash_size, sram_size) + if os.getenv('CI'): + # always print build output if in CI + print(f"::group::{title}") + print(r.stdout.decode("utf-8")) + print(f"::endgroup::") + else: + # print build output if failed + print(title) + if r.returncode != 0: + print(r.stdout.decode("utf-8")) - build_duration = time.monotonic() - start_time - print(build_format.format(example, board, success, "{:.2f}s".format(build_duration), flash_size, sram_size)) - - if build_result.returncode != 0: - print(build_result.stdout.decode("utf-8")) def build_size(example, board): #elf_file = 'examples/device/{}/_build/{}/{}-firmware.elf'.format(example, board, board) @@ -82,6 +89,7 @@ def build_size(example, board): sram_size = int(size_list[1]) + int(size_list[2]) return (flash_size, sram_size) + print(build_separator) print(build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) print(build_separator) diff --git a/tools/build_family.py b/tools/build_family.py deleted file mode 100644 index fb90e0edb..000000000 --- a/tools/build_family.py +++ /dev/null @@ -1,79 +0,0 @@ -import os -import sys -import time -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 = 'TOOLCHAIN=iar' - -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(example, 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) - filter_with_input(all_boards) - all_boards.sort() - - with Pool(processes=os.cpu_count()) as pool: - pool_args = list((map(lambda b, e=example, o=make_option: [e, b, o], all_boards))) - result = pool.starmap(build_utils.build_example, pool_args) - # sum all element of same index (column sum) - return list(map(sum, list(zip(*result)))) - -if __name__ == '__main__': - # IAR CC - if make_iar_option not in sys.argv: - make_iar_option = '' - - # If examples are not specified in arguments, build all - all_examples = [] - for d in os.scandir("examples"): - if d.is_dir() and 'cmake' not in d.name: - for entry in os.scandir(d.path): - if entry.is_dir() and 'cmake' not in entry.name: - all_examples.append(d.name + '/' + entry.name) - filter_with_input(all_examples) - all_examples.sort() - - # 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 example in all_examples: - print(build_separator) - for family in all_families: - fret = build_family(example, 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]) diff --git a/tools/build_utils.py b/tools/build_utils.py index 5d735bc17..b66b64b97 100644 --- a/tools/build_utils.py +++ b/tools/build_utils.py @@ -64,18 +64,19 @@ def skip_example(example, board): skip_file = ex_dir / "skip.txt" only_file = ex_dir / "only.txt" - if skip_file.exists() and only_file.exists(): - raise RuntimeError("Only have a skip or only file. Not both.") - elif skip_file.exists(): + if skip_file.exists(): skips = skip_file.read_text().split() - return ("mcu:" + mcu in skips or - "board:" + board in skips or - "family:" + family in skips) - elif only_file.exists(): + if ("mcu:" + mcu in skips or + "board:" + board in skips or + "family:" + family in skips): + return True + + if only_file.exists(): onlys = only_file.read_text().split() - return not ("mcu:" + mcu in onlys or - "board:" + board in onlys or - "family:" + family in onlys) + if not ("mcu:" + mcu in onlys or + "board:" + board in onlys or + "family:" + family in onlys): + return True return False diff --git a/tools/cmake/toolchain/arm_gcc.cmake b/tools/cmake/toolchain/arm_gcc.cmake deleted file mode 100644 index cefa9d2ce..000000000 --- a/tools/cmake/toolchain/arm_gcc.cmake +++ /dev/null @@ -1,46 +0,0 @@ -set(CMAKE_SYSTEM_NAME Generic) - -set(CMAKE_C_COMPILER "arm-none-eabi-gcc") -set(CMAKE_CXX_COMPILER "arm-none-eabi-g++") -set(CMAKE_ASM_COMPILER "arm-none-eabi-gcc") - -set(CMAKE_SIZE "arm-none-eabi-size" CACHE FILEPATH "") -set(CMAKE_OBJCOPY "arm-none-eabi-objcopy" CACHE FILEPATH "") -set(CMAKE_OBJDUMP "arm-none-eabi-objdump" CACHE FILEPATH "") - -set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE) - -# Look for includes and libraries only in the target system prefix. -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) - -# pass TOOLCHAIN_CPU to -set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES CMAKE_SYSTEM_PROCESSOR) - -include(${CMAKE_CURRENT_LIST_DIR}/../cpu/${CMAKE_SYSTEM_PROCESSOR}.cmake) - -# enable all possible warnings for building examples -list(APPEND TOOLCHAIN_COMMON_FLAGS - -fdata-sections - -ffunction-sections - -fsingle-precision-constant - -fno-strict-aliasing - ) - -set(TOOLCHAIN_EXE_LINKER_FLAGS - -Wl,--print-memory-usage - -Wl,--gc-sections - -Wl,--cref - ) - -include(${CMAKE_CURRENT_LIST_DIR}/set_flags.cmake) - -# 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) -if (IS_IN_TRY_COMPILE) - set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -nostdlib") - set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -nostdlib") -endif () diff --git a/tools/cmake/toolchain/arm_iar.cmake b/tools/cmake/toolchain/arm_iar.cmake deleted file mode 100644 index a487e5b9f..000000000 --- a/tools/cmake/toolchain/arm_iar.cmake +++ /dev/null @@ -1,31 +0,0 @@ -set(CMAKE_SYSTEM_NAME Generic) - -set(CMAKE_C_COMPILER "iccarm") -set(CMAKE_CXX_COMPILER "iccarm") -set(CMAKE_ASM_COMPILER "iasmarm") - -set(CMAKE_SIZE "size" CACHE FILEPATH "") -set(CMAKE_OBJCOPY "ielftool" CACHE FILEPATH "") -set(CMAKE_OBJDUMP "iefdumparm" CACHE FILEPATH "") - -set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE) - -# Look for includes and libraries only in the target system prefix. -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) - -# pass TOOLCHAIN_CPU to -set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES CMAKE_SYSTEM_PROCESSOR) - -include(${CMAKE_CURRENT_LIST_DIR}/../cpu/${CMAKE_SYSTEM_PROCESSOR}.cmake) - -# enable all possible warnings for building examples -list(APPEND TOOLCHAIN_COMMON_FLAGS - ) - -list(APPEND TOOLCHAIN_EXE_LINKER_FLAGS - ) - -include(${CMAKE_CURRENT_LIST_DIR}/set_flags.cmake) diff --git a/tools/cmake/toolchain/set_flags.cmake b/tools/cmake/toolchain/set_flags.cmake deleted file mode 100644 index 44930ef4d..000000000 --- a/tools/cmake/toolchain/set_flags.cmake +++ /dev/null @@ -1,17 +0,0 @@ -include(CMakePrintHelpers) - -# join the toolchain flags into a single string -list(JOIN TOOLCHAIN_COMMON_FLAGS " " TOOLCHAIN_COMMON_FLAGS) - -foreach (LANG IN ITEMS C CXX ASM) - set(CMAKE_${LANG}_FLAGS_INIT ${TOOLCHAIN_COMMON_FLAGS}) - - #cmake_print_variables(CMAKE_${LANG}_FLAGS_INIT) - - # optimization flags for LOG, LOGGER ? - #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) diff --git a/tools/codespell/ignore-words.txt b/tools/codespell/ignore-words.txt index 2513691cb..957cbd86b 100644 --- a/tools/codespell/ignore-words.txt +++ b/tools/codespell/ignore-words.txt @@ -11,3 +11,4 @@ attch endianess pris busses +ser diff --git a/tools/gen_doc.py b/tools/gen_doc.py index 9078299cc..c63294588 100644 --- a/tools/gen_doc.py +++ b/tools/gen_doc.py @@ -13,9 +13,9 @@ TOP = Path(__file__).parent.parent.resolve() def gen_deps_doc(): deps_rst = Path(TOP) / "docs/reference/dependencies.rst" - df = pd.DataFrame.from_dict(deps_all, orient='index', columns=['Commit', 'Project']) - df = df[['Project', 'Commit']].sort_index() - df = df.rename_axis("Path") + df = pd.DataFrame.from_dict(deps_all, orient='index', columns=['Repo', 'Commit', 'Required by']) + df = df[['Repo', 'Commit', 'Required by']].sort_index() + df = df.rename_axis("Local Path") outstr = f"""\ ************ diff --git a/tools/get_deps.py b/tools/get_deps.py index 82f756f64..bca38fc80 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -1,3 +1,4 @@ +import click import sys import subprocess from pathlib import Path @@ -7,7 +8,7 @@ from multiprocessing import Pool # path, url, commit, family (Alphabet sorted by path) deps_mandatory = { 'lib/FreeRTOS-Kernel': ['https://github.com/FreeRTOS/FreeRTOS-Kernel.git', - '5f19e34f878af97810a7662a75eac59bd74d628b', + 'cc0e0707c0c748713485b870bb980852b210877f', 'all'], 'lib/lwip': ['https://github.com/lwip-tcpip/lwip.git', '159e31b689577dbf69cf0683bbaffbd71fa5ee10', @@ -37,24 +38,24 @@ deps_optional = { 'xmc4000'], 'hw/mcu/microchip': ['https://github.com/hathach/microchip_driver.git', '9e8b37e307d8404033bb881623a113931e1edf27', - 'sam3x samd11 samd21 samd51 same5x same7x saml2x samg'], + 'sam3x samd11 samd21 samd51 samd5x_e5x same5x same7x saml2x samg'], 'hw/mcu/mindmotion/mm32sdk': ['https://github.com/hathach/mm32sdk.git', - '0b79559eb411149d36e073c1635c620e576308d4', + 'b93e856211060ae825216c6a1d6aa347ec758843', 'mm32'], 'hw/mcu/nordic/nrfx': ['https://github.com/NordicSemiconductor/nrfx.git', - '2527e3c8449cfd38aee41598e8af8492f410ed15', + '7c47cc0a56ce44658e6da2458e86cd8783ccc4a2', 'nrf'], 'hw/mcu/nuvoton': ['https://github.com/majbthrd/nuc_driver.git', '2204191ec76283371419fbcec207da02e1bc22fa', 'nuc'], 'hw/mcu/nxp/lpcopen': ['https://github.com/hathach/nxp_lpcopen.git', - '43c45c85405a5dd114fff0ea95cca62837740c13', + '04bfe7a5f6ee74a89a28ad618d3367dcfcfb7d83', 'lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43'], 'hw/mcu/nxp/mcux-sdk': ['https://github.com/hathach/mcux-sdk.git', - '950819b7de9b32f92c3edf396bc5ffb8d66e7009', - 'kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx imxrt'], + '144f1eb7ea8c06512e12f12b27383601c0272410', + 'kinetis_k 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', - 'd00a10a8c425d0d40f81b87169102944b01f3bb3', + '0f747aaa0c16f750bdfa2ba37ec25d6c8e1bc117', 'rp2040'], 'hw/mcu/renesas/fsp': ['https://github.com/renesas/fsp.git', 'd52e5a6a59b7c638da860c2bb309b6e78e752ff8', @@ -84,7 +85,7 @@ deps_optional = { '2615e866fa48fe1ff1af9e31c348813f2b19e7ec', 'stm32f4'], 'hw/mcu/st/cmsis_device_f7': ['https://github.com/STMicroelectronics/cmsis_device_f7.git', - 'fc676ef1ad177eb874eaa06444d3d75395fc51f4', + '25b0463439303b7a38f0d27b161f7d2f3c096e79', 'stm32f7'], 'hw/mcu/st/cmsis_device_g0': ['https://github.com/STMicroelectronics/cmsis_device_g0.git', '3a23e1224417f3f2d00300ecd620495e363f2094', @@ -95,8 +96,11 @@ deps_optional = { 'hw/mcu/st/cmsis_device_h7': ['https://github.com/STMicroelectronics/cmsis_device_h7.git', '60dc2c913203dc8629dc233d4384dcc41c91e77f', 'stm32h7'], + 'hw/mcu/st/cmsis_device_h5': ['https://github.com/STMicroelectronics/cmsis_device_h5.git', + 'cd2d1d579743de57b88ccaf61a968b9c05848ffc', + 'stm32h5'], 'hw/mcu/st/cmsis_device_l0': ['https://github.com/STMicroelectronics/cmsis_device_l0.git', - '06748ca1f93827befdb8b794402320d94d02004f', + '69cd5999fd40ae6e546d4905b21635c6ca1bcb92', 'stm32l0'], 'hw/mcu/st/cmsis_device_l1': ['https://github.com/STMicroelectronics/cmsis_device_l1.git', '7f16ec0a1c4c063f84160b4cc6bf88ad554a823e', @@ -108,7 +112,7 @@ deps_optional = { 'd922865fc0326a102c26211c44b8e42f52c1e53d', 'stm32l5'], 'hw/mcu/st/cmsis_device_u5': ['https://github.com/STMicroelectronics/cmsis_device_u5.git', - 'bc00f3c9d8a4e25220f84c26d414902cc6bdf566', + '5ad9797c54ec3e55eff770fc9b3cd4a1aefc1309', 'stm32u5'], 'hw/mcu/st/cmsis_device_wb': ['https://github.com/STMicroelectronics/cmsis_device_wb.git', '9c5d1920dd9fabbe2548e10561d63db829bb744f', @@ -140,6 +144,9 @@ deps_optional = { 'hw/mcu/st/stm32h7xx_hal_driver': ['https://github.com/STMicroelectronics/stm32h7xx_hal_driver.git', 'd8461b980b59b1625207d8c4f2ce0a9c2a7a3b04', 'stm32h7'], + 'hw/mcu/st/stm32h5xx_hal_driver': ['https://github.com/STMicroelectronics/stm32h5xx_hal_driver.git', + '2cf77de584196d619cec1b4586c3b9e2820a254e', + 'stm32h5'], 'hw/mcu/st/stm32l0xx_hal_driver': ['https://github.com/STMicroelectronics/stm32l0xx_hal_driver.git', 'fbdacaf6f8c82a4e1eb9bd74ba650b491e97e17b', 'stm32l0'], @@ -153,22 +160,28 @@ deps_optional = { '675c32a75df37f39d50d61f51cb0dcf53f07e1cb', 'stm32l5'], 'hw/mcu/st/stm32u5xx_hal_driver': ['https://github.com/STMicroelectronics/stm32u5xx_hal_driver.git', - '2e1d4cdb386e33391cb261dfff4fefa92e4aa35a', + '4d93097a67928e9377e655ddd14622adc31b9770', 'stm32u5'], 'hw/mcu/st/stm32wbxx_hal_driver': ['https://github.com/STMicroelectronics/stm32wbxx_hal_driver.git', '2c5f06638be516c1b772f768456ba637f077bac8', 'stm32wb'], 'hw/mcu/ti': ['https://github.com/hathach/ti_driver.git', '143ed6cc20a7615d042b03b21e070197d473e6e5', - 'msp430 msp432e4 tm4c123'], + 'msp430 msp432e4 tm4c'], 'hw/mcu/wch/ch32v307': ['https://github.com/openwch/ch32v307.git', '17761f5cf9dbbf2dcf665b7c04934188add20082', 'ch32v307'], + 'hw/mcu/wch/ch32f20x': ['https://github.com/openwch/ch32f20x.git', + '77c4095087e5ed2c548ec9058e655d0b8757663b', + 'ch32f20x'], 'lib/CMSIS_5': ['https://github.com/ARM-software/CMSIS_5.git', '20285262657d1b482d132d20d755c8c330d55c1f', 'imxrt kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx mm32 msp432e4 nrf ra saml2x' - 'stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 ' - 'stm32h7 stm32l0 stm32l1 stm32l4 stm32l5 stm32u5 stm32wb'], + 'lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43' + 'stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5' + 'stm32h7 stm32l0 stm32l1 stm32l4 stm32l5 stm32u5 stm32wb' + 'sam3x samd11 samd21 samd51 samd5x_e5x same5x same7x saml2x samg' + 'tm4c'], 'lib/sct_neopixel': ['https://github.com/gsteiert/sct_neopixel.git', 'e73e04ca63495672d955f9268e003cffe168fcd8', 'lpc55'], @@ -181,6 +194,10 @@ deps_all = {**deps_mandatory, **deps_optional} TOP = Path(__file__).parent.parent.resolve() +def run_cmd(cmd): + return subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + + def get_a_dep(d): if d not in deps_all.keys(): print('{} is not found in dependency list') @@ -189,50 +206,68 @@ def get_a_dep(d): commit = deps_all[d][1] families = deps_all[d][2] - print('cloning {} with {}'.format(d, url)) + print(f'cloning {d} with {url}') p = Path(TOP / d) - git_cmd = "git -C {}".format(p) + git_cmd = f"git -C {p}" # Init git deps if not existed if not p.exists(): p.mkdir(parents=True) - subprocess.run("{} init".format(git_cmd), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - subprocess.run("{} remote add origin {}".format(git_cmd, url), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + run_cmd(f"{git_cmd} init") + run_cmd(f"{git_cmd} remote add origin {url}") # Check if commit is already fetched - result = subprocess.run("{} rev-parse HEAD".format(git_cmd, commit), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + result = run_cmd(f"{git_cmd} rev-parse HEAD") head = result.stdout.decode("utf-8").splitlines()[0] - + run_cmd(f"{git_cmd} reset --hard") if commit != head: - subprocess.run("{} reset --hard".format(git_cmd, commit), shell=True) - subprocess.run("{} fetch --depth 1 origin {}".format(git_cmd, commit), shell=True) - subprocess.run("{} checkout FETCH_HEAD".format(git_cmd), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + run_cmd(f"{git_cmd} fetch --depth 1 origin {commit}") + run_cmd(f"{git_cmd} checkout FETCH_HEAD") return 0 -# Arguments can be -# - family name -# - specific deps path -# - all -if __name__ == "__main__": +def find_family(board): + bsp_dir = Path(TOP / "hw/bsp") + for family_dir in bsp_dir.iterdir(): + if family_dir.is_dir(): + board_dir = family_dir / 'boards' / board + if board_dir.exists(): + return family_dir.name + return None + + +@click.command() +@click.argument('family', nargs=-1, required=False) +@click.option('-b', '--board', multiple=True, default=None, help='Boards to fetch') +def main(family, board): + if len(family) == 0 and len(board) == 0: + print("Please specify family or board to fetch") + return + status = 0 deps = list(deps_mandatory.keys()) - # get all if 'all' is argument - if len(sys.argv) == 2 and sys.argv[1] == 'all': + + if 'all' in family: deps += deps_optional.keys() else: - for arg in sys.argv[1:]: - if arg in deps_all.keys(): - # if arg is a dep, add it - deps.append(arg) - else: - # arg is a family name, add all deps of that family - for d in deps_optional: - if arg in deps_optional[d][2]: - deps.append(d) + family = list(family) + if board is not None: + for b in board: + f = find_family(b) + if f is not None: + family.append(f) + + for f in family: + for d in deps_optional: + if f in deps_optional[d][2]: + deps.append(d) with Pool() as pool: status = sum(pool.map(get_a_dep, deps)) - sys.exit(status) + return status + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tools/iar_gen.py b/tools/iar_gen.py index 73c8b29fc..ebcfa1423 100644 --- a/tools/iar_gen.py +++ b/tools/iar_gen.py @@ -1,51 +1,87 @@ #!/usr/bin/python3 import os +import sys import xml.dom.minidom as XML +import glob -# Read base configuration -base = "" -with open("iar_template.ipcf") as f: - base = f.read() +def Main(): + # Read base configuration + base = "" + with open("iar_template.ipcf") as f: + base = f.read() -# Enumerate all device/host examples -dir_1 = os.listdir("../examples") -for dir_2 in dir_1: - if os.path.isdir("../examples/{}".format(dir_2)): - print(dir_2) - examples = os.listdir("../examples/{}".format(dir_2)) - for example in examples: - if os.path.isdir("../examples/{}/{}".format(dir_2, example)): - print("../examples/{}/{}".format(dir_2, example)) - conf = XML.parseString(base) - files = conf.getElementsByTagName("files")[0] - inc = conf.getElementsByTagName("includePath")[0] - # Add bsp inc - path = conf.createElement('path') - path_txt = conf.createTextNode("$TUSB_DIR$/hw") - path.appendChild(path_txt) - inc.appendChild(path) - # Add board.c/.h - grp = conf.createElement('group') - grp.setAttribute("name", "bsp") - path = conf.createElement('path') - path_txt = conf.createTextNode("$TUSB_DIR$/hw/bsp/board.c") - path.appendChild(path_txt) - grp.appendChild(path) - files.appendChild(grp) - # Add example's .c/.h - grp = conf.createElement('group') - grp.setAttribute("name", "example") - for file in os.listdir("../examples/{}/{}/src".format(dir_2, example)): - if file.endswith(".c") or file.endswith(".h"): - path = conf.createElement('path') - path.setAttribute("copyTo", "$PROJ_DIR$/{}".format(file)) - path_txt = conf.createTextNode("$TUSB_DIR$/examples/{0}/{1}/src/{2}".format(dir_2, example, file)) - path.appendChild(path_txt) - grp.appendChild(path) - files.appendChild(grp) - cfg_str = conf.toprettyxml() - cfg_str = '\n'.join([s for s in cfg_str.splitlines() if s.strip()]) - #print(cfg_str) - with open("../examples/{0}/{1}/iar_{1}.ipcf".format(dir_2, example), 'w') as f: - f.write(cfg_str) + # Enumerate all device/host examples + dir_1 = os.listdir("../examples") + for dir_2 in dir_1: + if os.path.isdir("../examples/{}".format(dir_2)): + print(dir_2) + examples = os.listdir("../examples/{}".format(dir_2)) + for example in examples: + if os.path.isdir("../examples/{}/{}".format(dir_2, example)): + print("../examples/{}/{}".format(dir_2, example)) + conf = XML.parseString(base) + files = conf.getElementsByTagName("files")[0] + inc = conf.getElementsByTagName("includePath")[0] + # Add bsp inc + path = conf.createElement('path') + path_txt = conf.createTextNode("$TUSB_DIR$/hw") + path.appendChild(path_txt) + inc.appendChild(path) + # Add board.c/.h + grp = conf.createElement('group') + grp.setAttribute("name", "bsp") + path = conf.createElement('path') + path_txt = conf.createTextNode("$TUSB_DIR$/hw/bsp/board.c") + path.appendChild(path_txt) + grp.appendChild(path) + files.appendChild(grp) + # Add example's .c/.h + grp = conf.createElement('group') + grp.setAttribute("name", "example") + for file in os.listdir("../examples/{}/{}/src".format(dir_2, example)): + if file.endswith(".c") or file.endswith(".h"): + path = conf.createElement('path') + path.setAttribute("copyTo", "$PROJ_DIR$/{}".format(file)) + path_txt = conf.createTextNode("$TUSB_DIR$/examples/{0}/{1}/src/{2}".format(dir_2, example, file)) + path.appendChild(path_txt) + grp.appendChild(path) + files.appendChild(grp) + cfg_str = conf.toprettyxml() + cfg_str = '\n'.join([s for s in cfg_str.splitlines() if s.strip()]) + #print(cfg_str) + with open("../examples/{0}/{1}/iar_{1}.ipcf".format(dir_2, example), 'w') as f: + f.write(cfg_str) + +def ListPath(path, blacklist=[]): + # Get all .c files + files = glob.glob(f'../{path}/**/*.c', recursive=True) + files.extend(glob.glob(f'../{path}/**/*.h', recursive=True)) + # Filter + files = [x for x in files if all(y not in x for y in blacklist)] + # Get common dir list + dirs = [] + for file in files: + dir = os.path.dirname(file) + if dir not in dirs: + dirs.append(dir) + # Print .c grouped by dir + for dir in dirs: + print('') + for file in files: + if os.path.dirname(file) == dir: + print(' $TUSB_DIR$/' + file.replace('../','').replace('\\','/')+'') + print('') + +def List(): + ListPath('src', [ 'template.c', 'dcd_synopsys.c', 'dcd_esp32sx.c' ]) + ListPath('lib/SEGGER_RTT') + +if __name__ == "__main__": + if os.path.dirname(os.getcwd()) != 'tools': + os.chdir('tools') + if (len(sys.argv) > 1): + if (sys.argv[1] == 'l'): + List() + else: + Main() diff --git a/tools/iar_template.ipcf b/tools/iar_template.ipcf index 6ea1d576d..e72ec0ce2 100644 --- a/tools/iar_template.ipcf +++ b/tools/iar_template.ipcf @@ -4,166 +4,272 @@ $TUSB_DIR$/src $TUSB_DIR$/lib/SEGGER_RTT/RTT + $TUSB_DIR$/lib/SEGGER_RTT/Config $PROJ_DIR$ - - $TUSB_DIR$/src/device/usbd.c - $TUSB_DIR$/src/device/usbd_control.c - - - $TUSB_DIR$/src/common/tusb_fifo.c - - - $TUSB_DIR$/src/class/audio/audio_device.c - - - $TUSB_DIR$/src/class/bth/bth_device.c - - - $TUSB_DIR$/src/class/cdc/cdc_device.c - $TUSB_DIR$/src/class/cdc/cdc_host.c - $TUSB_DIR$/src/class/cdc/cdc_rndis_host.c - - - $TUSB_DIR$/src/class/dfu/dfu_device.c - $TUSB_DIR$/src/class/dfu/dfu_rt_device.c - - - $TUSB_DIR$/src/class/hid/hid_device.c - $TUSB_DIR$/src/class/hid/hid_host.c - - - $TUSB_DIR$/src/class/midi/midi_device.c - - - $TUSB_DIR$/src/class/msc/msc_device.c - $TUSB_DIR$/src/class/msc/msc_host.c - - - $TUSB_DIR$/src/class/net/ecm_rndis_device.c - $TUSB_DIR$/src/class/net/ncm_device.c - - - $TUSB_DIR$/src/class/usbtmc/usbtmc_device.c - - - $TUSB_DIR$/src/class/vendor/vendor_device.c - $TUSB_DIR$/src/class/vendor/vendor_host.c - $TUSB_DIR$/src/tusb.c + $TUSB_DIR$/src/tusb.h + $TUSB_DIR$/src/tusb_option.h - - $TUSB_DIR$/src/host/hub.c - $TUSB_DIR$/src/host/usbh.c - - - $TUSB_DIR$/src/portable/bridgetek/ft9xx/dcd_ft9xx.c - - - $TUSB_DIR$/src/portable/chipidea/ci_hs/dcd_ci_hs.c - $TUSB_DIR$/src/portable/chipidea/ci_hs/hcd_ci_hs.c - - - $TUSB_DIR$/src/portable/synopsys/dwc2/dcd_dwc2.c - - - $TUSB_DIR$/src/portable/dialog/da146xx/dcd_da146xx.c - - - $TUSB_DIR$/src/portable/ehci/ehci.c - - - $TUSB_DIR$/src/portable/espressif/esp32sx/dcd_esp32sx.c - - - $TUSB_DIR$/src/portable/mentor/musb/dcd_musb.c - $TUSB_DIR$/src/portable/mentor/musb/hcd_musb.c - - - $TUSB_DIR$/src/portable/microchip/samd/dcd_samd.c - - - $TUSB_DIR$/src/portable/microchip/samg/dcd_samg.c - - - $TUSB_DIR$/src/portable/microchip/samx7x/dcd_samx7x.c - - - $TUSB_DIR$/src/portable/microchip/pic/dcd_pic.c - - - $TUSB_DIR$/src/portable/microchip/pic32mz/dcd_pic32mz.c - - - $TUSB_DIR$/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c - - - $TUSB_DIR$/src/portable/nordic/nrf5x/dcd_nrf5x.c - - - $TUSB_DIR$/src/portable/nuvoton/nuc120/dcd_nuc120.c - - - $TUSB_DIR$/src/portable/nuvoton/nuc121/dcd_nuc121.c - - - $TUSB_DIR$/src/portable/nuvoton/nuc505/dcd_nuc505.c - - - $TUSB_DIR$/src/portable/nxp/khci/dcd_khci.c - $TUSB_DIR$/src/portable/nxp/khci/hcd_khci.c - - - $TUSB_DIR$/src/portable/nxp/lpc17_40/dcd_lpc17_40.c - $TUSB_DIR$/src/portable/nxp/lpc17_40/hcd_lpc17_40.c - - - $TUSB_DIR$/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c - - - $TUSB_DIR$/src/portable/nxp/transdimension/dcd_transdimension.c - $TUSB_DIR$/src/portable/nxp/transdimension/hcd_transdimension.c - - - $TUSB_DIR$/src/portable/ohci/ohci.c - - - $TUSB_DIR$/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c - $TUSB_DIR$/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c - - - $TUSB_DIR$/src/portable/raspberrypi/rp2040/dcd_rp2040.c - $TUSB_DIR$/src/portable/raspberrypi/rp2040/hcd_rp2040.c - - - $TUSB_DIR$/src/portable/renesas/rusb2/dcd_rusb2.c - $TUSB_DIR$/src/portable/renesas/rusb2/hcd_rusb2.c - - - $TUSB_DIR$/src/portable/sony/cxd56/dcd_cxd56.c - - - $TUSB_DIR$/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c - - - $TUSB_DIR$/src/portable/sunxi/dcd_sunxi_musb.c - - - $TUSB_DIR$/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c - - - $TUSB_DIR$/src/portable/valentyusb/eptri/dcd_eptri.c - - - $TUSB_DIR$/src/portable/wch/ch32v307/dcd_usbhs.c - - - $TUSB_DIR$/lib/SEGGER_RTT/RTT/SEGGER_RTT.c + + $TUSB_DIR$/src/class/audio/audio_device.c + $TUSB_DIR$/src/class/audio/audio.h + $TUSB_DIR$/src/class/audio/audio_device.h + + + $TUSB_DIR$/src/class/bth/bth_device.c + $TUSB_DIR$/src/class/bth/bth_device.h + + + $TUSB_DIR$/src/class/cdc/cdc_device.c + $TUSB_DIR$/src/class/cdc/cdc_host.c + $TUSB_DIR$/src/class/cdc/cdc_rndis_host.c + $TUSB_DIR$/src/class/cdc/cdc.h + $TUSB_DIR$/src/class/cdc/cdc_device.h + $TUSB_DIR$/src/class/cdc/cdc_host.h + $TUSB_DIR$/src/class/cdc/cdc_rndis.h + $TUSB_DIR$/src/class/cdc/cdc_rndis_host.h + + + $TUSB_DIR$/src/class/dfu/dfu_device.c + $TUSB_DIR$/src/class/dfu/dfu_rt_device.c + $TUSB_DIR$/src/class/dfu/dfu.h + $TUSB_DIR$/src/class/dfu/dfu_device.h + $TUSB_DIR$/src/class/dfu/dfu_rt_device.h + + + $TUSB_DIR$/src/class/hid/hid_device.c + $TUSB_DIR$/src/class/hid/hid_host.c + $TUSB_DIR$/src/class/hid/hid.h + $TUSB_DIR$/src/class/hid/hid_device.h + $TUSB_DIR$/src/class/hid/hid_host.h + + + $TUSB_DIR$/src/class/midi/midi_device.c + $TUSB_DIR$/src/class/midi/midi.h + $TUSB_DIR$/src/class/midi/midi_device.h + + + $TUSB_DIR$/src/class/msc/msc_device.c + $TUSB_DIR$/src/class/msc/msc_host.c + $TUSB_DIR$/src/class/msc/msc.h + $TUSB_DIR$/src/class/msc/msc_device.h + $TUSB_DIR$/src/class/msc/msc_host.h + + + $TUSB_DIR$/src/class/net/ecm_rndis_device.c + $TUSB_DIR$/src/class/net/ncm_device.c + $TUSB_DIR$/src/class/net/ncm.h + $TUSB_DIR$/src/class/net/net_device.h + + + $TUSB_DIR$/src/class/usbtmc/usbtmc_device.c + $TUSB_DIR$/src/class/usbtmc/usbtmc.h + $TUSB_DIR$/src/class/usbtmc/usbtmc_device.h + + + $TUSB_DIR$/src/class/vendor/vendor_device.c + $TUSB_DIR$/src/class/vendor/vendor_host.c + $TUSB_DIR$/src/class/vendor/vendor_device.h + $TUSB_DIR$/src/class/vendor/vendor_host.h + + + $TUSB_DIR$/src/class/video/video_device.c + $TUSB_DIR$/src/class/video/video.h + $TUSB_DIR$/src/class/video/video_device.h + + + $TUSB_DIR$/src/common/tusb_fifo.c + $TUSB_DIR$/src/common/tusb_common.h + $TUSB_DIR$/src/common/tusb_compiler.h + $TUSB_DIR$/src/common/tusb_debug.h + $TUSB_DIR$/src/common/tusb_fifo.h + $TUSB_DIR$/src/common/tusb_mcu.h + $TUSB_DIR$/src/common/tusb_private.h + $TUSB_DIR$/src/common/tusb_types.h + $TUSB_DIR$/src/common/tusb_verify.h + + + $TUSB_DIR$/src/device/usbd.c + $TUSB_DIR$/src/device/usbd_control.c + $TUSB_DIR$/src/device/dcd.h + $TUSB_DIR$/src/device/usbd.h + $TUSB_DIR$/src/device/usbd_pvt.h + + + $TUSB_DIR$/src/host/hub.c + $TUSB_DIR$/src/host/usbh.c + $TUSB_DIR$/src/host/hcd.h + $TUSB_DIR$/src/host/hub.h + $TUSB_DIR$/src/host/usbh.h + $TUSB_DIR$/src/host/usbh_pvt.h + + + $TUSB_DIR$/src/portable/analog/max3421/hcd_max3421.c + + + $TUSB_DIR$/src/portable/bridgetek/ft9xx/dcd_ft9xx.c + + + $TUSB_DIR$/src/portable/chipidea/ci_fs/dcd_ci_fs.c + $TUSB_DIR$/src/portable/chipidea/ci_fs/ci_fs_kinetis.h + $TUSB_DIR$/src/portable/chipidea/ci_fs/ci_fs_mcx.h + $TUSB_DIR$/src/portable/chipidea/ci_fs/ci_fs_type.h + + + $TUSB_DIR$/src/portable/chipidea/ci_hs/dcd_ci_hs.c + $TUSB_DIR$/src/portable/chipidea/ci_hs/hcd_ci_hs.c + $TUSB_DIR$/src/portable/chipidea/ci_hs/ci_hs_imxrt.h + $TUSB_DIR$/src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h + $TUSB_DIR$/src/portable/chipidea/ci_hs/ci_hs_mcx.h + $TUSB_DIR$/src/portable/chipidea/ci_hs/ci_hs_type.h + + + $TUSB_DIR$/src/portable/dialog/da146xx/dcd_da146xx.c + + + $TUSB_DIR$/src/portable/ehci/ehci.c + $TUSB_DIR$/src/portable/ehci/ehci.h + $TUSB_DIR$/src/portable/ehci/ehci_api.h + + + $TUSB_DIR$/src/portable/mentor/musb/dcd_musb.c + $TUSB_DIR$/src/portable/mentor/musb/hcd_musb.c + $TUSB_DIR$/src/portable/mentor/musb/musb_msp432e.h + $TUSB_DIR$/src/portable/mentor/musb/musb_tm4c.h + $TUSB_DIR$/src/portable/mentor/musb/musb_type.h + + + $TUSB_DIR$/src/portable/microchip/pic/dcd_pic.c + + + $TUSB_DIR$/src/portable/microchip/pic32mz/dcd_pic32mz.c + $TUSB_DIR$/src/portable/microchip/pic32mz/usbhs_registers.h + + + $TUSB_DIR$/src/portable/microchip/samd/dcd_samd.c + + + $TUSB_DIR$/src/portable/microchip/samg/dcd_samg.c + + + $TUSB_DIR$/src/portable/microchip/samx7x/dcd_samx7x.c + $TUSB_DIR$/src/portable/microchip/samx7x/common_usb_regs.h + + + $TUSB_DIR$/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c + + + $TUSB_DIR$/src/portable/nordic/nrf5x/dcd_nrf5x.c + + + $TUSB_DIR$/src/portable/nuvoton/nuc120/dcd_nuc120.c + + + $TUSB_DIR$/src/portable/nuvoton/nuc121/dcd_nuc121.c + + + $TUSB_DIR$/src/portable/nuvoton/nuc505/dcd_nuc505.c + + + $TUSB_DIR$/src/portable/nxp/khci/dcd_khci.c + $TUSB_DIR$/src/portable/nxp/khci/hcd_khci.c + + + $TUSB_DIR$/src/portable/nxp/lpc17_40/dcd_lpc17_40.c + $TUSB_DIR$/src/portable/nxp/lpc17_40/hcd_lpc17_40.c + $TUSB_DIR$/src/portable/nxp/lpc17_40/dcd_lpc17_40.h + + + $TUSB_DIR$/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c + + + $TUSB_DIR$/src/portable/ohci/ohci.c + $TUSB_DIR$/src/portable/ohci/ohci.h + + + $TUSB_DIR$/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c + $TUSB_DIR$/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c + + + $TUSB_DIR$/src/portable/raspberrypi/rp2040/dcd_rp2040.c + $TUSB_DIR$/src/portable/raspberrypi/rp2040/hcd_rp2040.c + $TUSB_DIR$/src/portable/raspberrypi/rp2040/rp2040_usb.c + $TUSB_DIR$/src/portable/raspberrypi/rp2040/rp2040_usb.h + + + $TUSB_DIR$/src/portable/renesas/rusb2/dcd_rusb2.c + $TUSB_DIR$/src/portable/renesas/rusb2/hcd_rusb2.c + $TUSB_DIR$/src/portable/renesas/rusb2/rusb2_common.c + $TUSB_DIR$/src/portable/renesas/rusb2/rusb2_ra.h + $TUSB_DIR$/src/portable/renesas/rusb2/rusb2_rx.h + $TUSB_DIR$/src/portable/renesas/rusb2/rusb2_type.h + + + $TUSB_DIR$/src/portable/sony/cxd56/dcd_cxd56.c + + + $TUSB_DIR$/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c + $TUSB_DIR$/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h + + + $TUSB_DIR$/src/portable/st/typec/typec_stm32.c + + + $TUSB_DIR$/src/portable/sunxi/dcd_sunxi_musb.c + $TUSB_DIR$/src/portable/sunxi/musb_def.h + + + $TUSB_DIR$/src/portable/synopsys/dwc2/dcd_dwc2.c + $TUSB_DIR$/src/portable/synopsys/dwc2/dwc2_bcm.h + $TUSB_DIR$/src/portable/synopsys/dwc2/dwc2_efm32.h + $TUSB_DIR$/src/portable/synopsys/dwc2/dwc2_esp32.h + $TUSB_DIR$/src/portable/synopsys/dwc2/dwc2_gd32.h + $TUSB_DIR$/src/portable/synopsys/dwc2/dwc2_stm32.h + $TUSB_DIR$/src/portable/synopsys/dwc2/dwc2_type.h + $TUSB_DIR$/src/portable/synopsys/dwc2/dwc2_xmc.h + + + $TUSB_DIR$/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c + + + $TUSB_DIR$/src/portable/valentyusb/eptri/dcd_eptri.c + $TUSB_DIR$/src/portable/valentyusb/eptri/dcd_eptri.h + + + $TUSB_DIR$/src/portable/wch/dcd_ch32_usbhs.c + $TUSB_DIR$/src/portable/wch/ch32_usbhs_reg.h + + + $TUSB_DIR$/src/typec/usbc.c + $TUSB_DIR$/src/typec/pd_types.h + $TUSB_DIR$/src/typec/tcd.h + $TUSB_DIR$/src/typec/usbc.h + + + $TUSB_DIR$/src/class/cdc/serial/ch34x.h + $TUSB_DIR$/src/class/cdc/serial/cp210x.h + $TUSB_DIR$/src/class/cdc/serial/ftdi_sio.h + + + $TUSB_DIR$/src/osal/osal.h + $TUSB_DIR$/src/osal/osal_freertos.h + $TUSB_DIR$/src/osal/osal_mynewt.h + $TUSB_DIR$/src/osal/osal_none.h + $TUSB_DIR$/src/osal/osal_pico.h + $TUSB_DIR$/src/osal/osal_rtthread.h + $TUSB_DIR$/src/osal/osal_rtx4.h + + + $TUSB_DIR$/lib/SEGGER_RTT/RTT/SEGGER_RTT.c $TUSB_DIR$/lib/SEGGER_RTT/RTT/SEGGER_RTT_printf.c - $TUSB_DIR$/lib/SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_IAR.c - + $TUSB_DIR$/lib/SEGGER_RTT/RTT/SEGGER_RTT.h + + + $TUSB_DIR$/lib/SEGGER_RTT/Config/SEGGER_RTT_Conf.h + diff --git a/tools/make_release.py b/tools/make_release.py index 7481e8864..256ca8f21 100644 --- a/tools/make_release.py +++ b/tools/make_release.py @@ -1,6 +1,6 @@ import re -version = '0.15.0' +version = '0.16.0' print('version {}'.format(version)) ver_id = version.split('.') @@ -9,13 +9,11 @@ ver_id = version.split('.') # src/tusb_option.h ################### f_option_h = 'src/tusb_option.h' - with open(f_option_h) as f: fdata = f.read() - -fdata = re.sub(r'(#define TUSB_VERSION_MAJOR *) \d+', r"\1 {}".format(ver_id[0]), fdata) -fdata = re.sub(r'(#define TUSB_VERSION_MINOR *) \d+', r"\1 {}".format(ver_id[1]), fdata) -fdata = re.sub(r'(#define TUSB_VERSION_REVISION *) \d+', r"\1 {}".format(ver_id[2]), fdata) + fdata = re.sub(r'(#define TUSB_VERSION_MAJOR *) \d+', r"\1 {}".format(ver_id[0]), fdata) + fdata = re.sub(r'(#define TUSB_VERSION_MINOR *) \d+', r"\1 {}".format(ver_id[1]), fdata) + fdata = re.sub(r'(#define TUSB_VERSION_REVISION *) \d+', r"\1 {}".format(ver_id[2]), fdata) # Write the file out again with open(f_option_h, 'w') as f: @@ -33,6 +31,17 @@ if fdata.find(version) < 0: with open(f_repository_yml, 'w') as f: f.write(fdata) +################### +# library.json +################### +f_library_json = 'library.json' +with open(f_library_json) as f: + fdata = f.read() + fdata = re.sub(r'( {4}"version":) "\d+\.\d+\.\d+"', rf'\1 "{version}"', fdata) + +with open(f_library_json, 'w') as f: + f.write(fdata) + ################### # docs/info/changelog.rst ###################