mirror of
https://github.com/hathach/tinyusb.git
synced 2025-01-31 05:52:55 +08:00
Merge branch 'refs/heads/master' into fork/BrentK-ADI/max32_port
This commit is contained in:
commit
761399b5e0
@ -1,92 +1,39 @@
|
|||||||
version: 2.1
|
version: 2.1
|
||||||
|
|
||||||
commands:
|
setup: true
|
||||||
setup-toolchain:
|
orbs:
|
||||||
parameters:
|
continuation: circleci/continuation@1
|
||||||
toolchain:
|
|
||||||
type: string
|
|
||||||
toolchain_url:
|
|
||||||
type: string
|
|
||||||
steps:
|
|
||||||
# - run:
|
|
||||||
# name: Make toolchain cache key
|
|
||||||
# command: echo "<< parameters.toolchain >>-<< parameters.toolchain_url>>" > toolchain_key
|
|
||||||
# - restore_cache:
|
|
||||||
# name: Restore Toolchain Cache
|
|
||||||
# key: deps-{{ checksum "toolchain_key" }}
|
|
||||||
# paths:
|
|
||||||
# - ~/cache/<< parameters.toolchain >>
|
|
||||||
- run:
|
|
||||||
name: Install Toolchain
|
|
||||||
command: |
|
|
||||||
# Only download if folder does not exist (not cached)
|
|
||||||
if [ ! -d ~/cache/<< parameters.toolchain >> ]; then
|
|
||||||
mkdir -p ~/cache/<< parameters.toolchain >>
|
|
||||||
wget << parameters.toolchain_url>> -O toolchain.tar.gz
|
|
||||||
tar -C ~/cache/<< parameters.toolchain >> -xaf toolchain.tar.gz
|
|
||||||
fi
|
|
||||||
# - save_cache:
|
|
||||||
# name: Save Toolchain Cache
|
|
||||||
# key: deps-{{ checksum "toolchain_key" }}
|
|
||||||
# paths:
|
|
||||||
# - ~/cache/<< parameters.toolchain >>
|
|
||||||
- run:
|
|
||||||
name: Setup build environment
|
|
||||||
command: |
|
|
||||||
echo "export PATH=$PATH:`echo ~/cache/<< parameters.toolchain >>/*/bin`" >> $BASH_ENV
|
|
||||||
# Install Ninja
|
|
||||||
NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.12.1/ninja-linux.zip
|
|
||||||
wget $NINJA_URL -O ninja-linux.zip
|
|
||||||
unzip ninja-linux.zip -d ~/bin
|
|
||||||
|
|
||||||
get-deps:
|
|
||||||
parameters:
|
|
||||||
family:
|
|
||||||
type: string
|
|
||||||
steps:
|
|
||||||
- run:
|
|
||||||
name: Get Dependencies
|
|
||||||
command: |
|
|
||||||
python tools/get_deps.py << parameters.family >>
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
arm-clang:
|
set-matrix:
|
||||||
parameters:
|
executor: continuation/default
|
||||||
family:
|
|
||||||
type: string
|
|
||||||
build-system:
|
|
||||||
type: string
|
|
||||||
|
|
||||||
docker:
|
docker:
|
||||||
- image: cimg/base:current
|
- image: cimg/base:current
|
||||||
resource_class: medium
|
resource_class: small
|
||||||
environment:
|
|
||||||
TOOLCHAIN_URL: 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
|
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
- setup-toolchain:
|
|
||||||
toolchain: clang
|
|
||||||
toolchain_url: $TOOLCHAIN_URL
|
|
||||||
- get-deps:
|
|
||||||
family: << parameters.family >>
|
|
||||||
- run:
|
- run:
|
||||||
name: Build
|
name: Set matrix
|
||||||
command: |
|
command: |
|
||||||
# Only build one board per family for non PRs i.e commit to master
|
MATRIX_JSON=$(python .github/workflows/ci_set_matrix.py)
|
||||||
ONE_PER_FAMILY=""
|
echo "MATRIX_JSON=$MATRIX_JSON"
|
||||||
if [ -z "$CIRCLE_PULL_REQUEST" ]; then
|
|
||||||
ONE_PER_FAMILY="--one-per-family"
|
TOOLCHAIN_LIST=("arm-clang" "arm-gcc")
|
||||||
fi
|
for toolchain in "${TOOLCHAIN_LIST[@]}"; do
|
||||||
python tools/build.py $ONE_PER_FAMILY -s << parameters.build-system >> --toolchain clang << parameters.family >>
|
FAMILY=$(echo $MATRIX_JSON | jq -r ".\"$toolchain\".family")
|
||||||
|
echo "${toolchain}_FAMILY=$FAMILY"
|
||||||
|
echo " - build:" >> .circleci/config2.yml
|
||||||
|
echo " matrix:" >> .circleci/config2.yml
|
||||||
|
echo " parameters:" >> .circleci/config2.yml
|
||||||
|
echo " toolchain: ['$toolchain']" >> .circleci/config2.yml
|
||||||
|
echo " build-system: ['cmake']" >> .circleci/config2.yml
|
||||||
|
echo " family: $FAMILY" >> .circleci/config2.yml
|
||||||
|
done
|
||||||
|
|
||||||
|
- continuation/continue:
|
||||||
|
configuration_path: .circleci/config2.yml
|
||||||
|
|
||||||
workflows:
|
workflows:
|
||||||
build:
|
set-matrix:
|
||||||
jobs:
|
jobs:
|
||||||
- arm-clang:
|
- set-matrix
|
||||||
matrix:
|
|
||||||
parameters:
|
|
||||||
build-system:
|
|
||||||
- cmake
|
|
||||||
#family: ['stm32f1']
|
|
||||||
#family: ['stm32f1', 'stm32f2']
|
|
||||||
family: ['imxrt', 'kinetis_k kinetis_kl kinetis_k32l2', 'lpc11 lpc13 lpc15', 'lpc17 lpc18 lpc40 lpc43', 'lpc51 lpc54 lpc55', 'nrf', 'samd11 samd21 saml2x', 'samd5x_e5x samg', 'stm32f0 stm32f1 stm32f2 stm32f3', 'stm32f4', 'stm32f7', 'stm32g0 stm32g4 stm32h5', 'stm32h7', 'stm32l4 stm32u5 stm32wb']
|
|
||||||
|
98
.circleci/config2.yml
Normal file
98
.circleci/config2.yml
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
version: 2.1
|
||||||
|
|
||||||
|
commands:
|
||||||
|
setup-toolchain:
|
||||||
|
parameters:
|
||||||
|
toolchain:
|
||||||
|
type: string
|
||||||
|
steps:
|
||||||
|
- run:
|
||||||
|
name: Install Toolchain
|
||||||
|
command: |
|
||||||
|
TOOLCHAIN_JSON='{
|
||||||
|
"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": "https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v12.3.1-1.1/xpack-arm-none-eabi-gcc-12.3.1-1.1-linux-x64.tar.gz"
|
||||||
|
}'
|
||||||
|
toolchain_url=$(echo $TOOLCHAIN_JSON | jq -r '.["<< parameters.toolchain >>"]')
|
||||||
|
echo "toolchain_url=$toolchain_url"
|
||||||
|
|
||||||
|
# download and extract toolchain
|
||||||
|
mkdir -p ~/cache/<< parameters.toolchain >>
|
||||||
|
wget $toolchain_url -O toolchain.tar.gz
|
||||||
|
tar -C ~/cache/<< parameters.toolchain >> -xaf toolchain.tar.gz
|
||||||
|
|
||||||
|
# Add toolchain to PATH
|
||||||
|
echo "export PATH=$PATH:`echo ~/cache/<< parameters.toolchain >>/*/bin`" >> $BASH_ENV
|
||||||
|
|
||||||
|
get-deps:
|
||||||
|
parameters:
|
||||||
|
family:
|
||||||
|
type: string
|
||||||
|
steps:
|
||||||
|
- run:
|
||||||
|
name: Get Dependencies
|
||||||
|
command: |
|
||||||
|
python tools/get_deps.py << parameters.family >>
|
||||||
|
|
||||||
|
# Install Pico SDK
|
||||||
|
if [ << parameters.family >> == "rp2040" ]; then
|
||||||
|
git clone --depth 1 https://github.com/raspberrypi/pico-sdk.git ~/pico-sdk
|
||||||
|
echo "export PICO_SDK_PATH=~/pico-sdk" >> $BASH_ENV
|
||||||
|
fi
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
parameters:
|
||||||
|
build-system:
|
||||||
|
type: string
|
||||||
|
toolchain:
|
||||||
|
type: string
|
||||||
|
family:
|
||||||
|
type: string
|
||||||
|
|
||||||
|
docker:
|
||||||
|
- image: cimg/base:current
|
||||||
|
resource_class: medium+
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- when:
|
||||||
|
condition: << parameters.build-system >> == 'cmake'
|
||||||
|
steps:
|
||||||
|
- run:
|
||||||
|
name: Install Ninja
|
||||||
|
command: |
|
||||||
|
# Install Ninja
|
||||||
|
NINJA_URL=https://github.com/ninja-build/ninja/releases/download/v1.12.1/ninja-linux.zip
|
||||||
|
wget $NINJA_URL -O ninja-linux.zip
|
||||||
|
unzip ninja-linux.zip -d ~/bin
|
||||||
|
- setup-toolchain:
|
||||||
|
toolchain: << parameters.toolchain >>
|
||||||
|
- get-deps:
|
||||||
|
family: << parameters.family >>
|
||||||
|
- run:
|
||||||
|
name: Build
|
||||||
|
command: |
|
||||||
|
# Only build one board per family for non PRs i.e commit to master
|
||||||
|
ONE_PER_FAMILY=""
|
||||||
|
if [ -z "$CIRCLE_PULL_REQUEST" ]; then
|
||||||
|
ONE_PER_FAMILY="--one-per-family"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Toolchain option default is gcc
|
||||||
|
if [ "<< parameters.toolchain >>" == "arm-clang" ]; then
|
||||||
|
TOOLCHAIN_OPTION="--toolchain clang"
|
||||||
|
elif [ "<< parameters.toolchain >>" == "arm-gcc" ]; then
|
||||||
|
TOOLCHAIN_OPTION="--toolchain gcc"
|
||||||
|
fi
|
||||||
|
|
||||||
|
python tools/build.py $ONE_PER_FAMILY -s << parameters.build-system >> $TOOLCHAIN_OPTION << parameters.family >>
|
||||||
|
|
||||||
|
workflows:
|
||||||
|
build:
|
||||||
|
jobs:
|
||||||
|
# - build:
|
||||||
|
# matrix:
|
||||||
|
# parameters:
|
||||||
|
# toolchain: ['arm-clang']
|
||||||
|
# build-system: ['cmake']
|
||||||
|
# family: ['imxrt']
|
29
.github/actions/setup_toolchain/action.yml
vendored
29
.github/actions/setup_toolchain/action.yml
vendored
@ -4,8 +4,8 @@ inputs:
|
|||||||
toolchain:
|
toolchain:
|
||||||
description: 'Toolchain name'
|
description: 'Toolchain name'
|
||||||
required: true
|
required: true
|
||||||
toolchain_url:
|
toolchain_version:
|
||||||
description: 'Toolchain URL or version'
|
description: 'Toolchain version'
|
||||||
required: false
|
required: false
|
||||||
|
|
||||||
outputs:
|
outputs:
|
||||||
@ -27,7 +27,28 @@ runs:
|
|||||||
uses: ./.github/actions/setup_toolchain/espressif
|
uses: ./.github/actions/setup_toolchain/espressif
|
||||||
with:
|
with:
|
||||||
toolchain: ${{ inputs.toolchain }}
|
toolchain: ${{ inputs.toolchain }}
|
||||||
toolchain_url: ${{ inputs.toolchain_url }}
|
toolchain_version: ${{ inputs.toolchain_version }}
|
||||||
|
|
||||||
|
- name: Get Toolchain URL
|
||||||
|
if: >-
|
||||||
|
inputs.toolchain != 'arm-gcc' &&
|
||||||
|
inputs.toolchain != 'arm-iar' &&
|
||||||
|
inputs.toolchain != 'esp-idf'
|
||||||
|
id: set-toolchain-url
|
||||||
|
run: |
|
||||||
|
TOOLCHAIN_JSON='{
|
||||||
|
"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-iar": "",
|
||||||
|
"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-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz",
|
||||||
|
"rx-gcc": "http://gcc-renesas.com/downloads/get.php?f=rx/8.3.0.202004-gnurx/gcc-8.3.0.202004-GNURX-ELF.run"
|
||||||
|
}'
|
||||||
|
TOOLCHAIN_URL=$(echo $TOOLCHAIN_JSON | jq -r '.["${{ inputs.toolchain }}"]')
|
||||||
|
echo "toolchain_url=$TOOLCHAIN_URL"
|
||||||
|
echo "toolchain_url=$TOOLCHAIN_URL" >> $GITHUB_OUTPUT
|
||||||
|
shell: bash
|
||||||
|
|
||||||
- name: Download Toolchain
|
- name: Download Toolchain
|
||||||
if: >-
|
if: >-
|
||||||
@ -37,7 +58,7 @@ runs:
|
|||||||
uses: ./.github/actions/setup_toolchain/download
|
uses: ./.github/actions/setup_toolchain/download
|
||||||
with:
|
with:
|
||||||
toolchain: ${{ inputs.toolchain }}
|
toolchain: ${{ inputs.toolchain }}
|
||||||
toolchain_url: ${{ inputs.toolchain_url }}
|
toolchain_url: ${{ steps.set-toolchain-url.outputs.toolchain_url }}
|
||||||
|
|
||||||
- name: Set toolchain option
|
- name: Set toolchain option
|
||||||
id: set-toolchain-option
|
id: set-toolchain-option
|
||||||
|
@ -4,7 +4,7 @@ inputs:
|
|||||||
toolchain:
|
toolchain:
|
||||||
description: 'Toolchain name'
|
description: 'Toolchain name'
|
||||||
required: true
|
required: true
|
||||||
toolchain_url:
|
toolchain_version:
|
||||||
description: 'Toolchain URL or version'
|
description: 'Toolchain URL or version'
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
@ -22,14 +22,14 @@ runs:
|
|||||||
id: cache-toolchain-espressif
|
id: cache-toolchain-espressif
|
||||||
with:
|
with:
|
||||||
path: ${{ env.DOCKER_ESP_IDF }}
|
path: ${{ env.DOCKER_ESP_IDF }}
|
||||||
key: ${{ inputs.toolchain }}-${{ inputs.toolchain_url }}
|
key: ${{ inputs.toolchain }}-${{ inputs.toolchain_version }}
|
||||||
|
|
||||||
- name: Pull and Save Docker Image
|
- name: Pull and Save Docker Image
|
||||||
if: steps.cache-toolchain-espressif.outputs.cache-hit != 'true'
|
if: steps.cache-toolchain-espressif.outputs.cache-hit != 'true'
|
||||||
run: |
|
run: |
|
||||||
docker pull espressif/idf:${{ inputs.toolchain_url }}
|
docker pull espressif/idf:${{ inputs.toolchain_version }}
|
||||||
mkdir -p $(dirname $DOCKER_ESP_IDF)
|
mkdir -p $(dirname $DOCKER_ESP_IDF)
|
||||||
docker save -o $DOCKER_ESP_IDF espressif/idf:${{ inputs.toolchain_url }}
|
docker save -o $DOCKER_ESP_IDF espressif/idf:${{ inputs.toolchain_version }}
|
||||||
du -sh $DOCKER_ESP_IDF
|
du -sh $DOCKER_ESP_IDF
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
|
27
.github/workflows/build.yml
vendored
27
.github/workflows/build.yml
vendored
@ -58,18 +58,30 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
toolchain:
|
toolchain:
|
||||||
# - 'arm-clang' is built by circle-ci
|
# - 'arm-clang' is built by circle-ci in PR
|
||||||
- 'aarch64-gcc'
|
- 'aarch64-gcc'
|
||||||
- 'arm-gcc'
|
|
||||||
- 'msp430-gcc'
|
- 'msp430-gcc'
|
||||||
- 'riscv-gcc'
|
- 'riscv-gcc'
|
||||||
with:
|
with:
|
||||||
build-system: 'cmake'
|
build-system: 'cmake'
|
||||||
toolchain: ${{ matrix.toolchain }}
|
toolchain: ${{ matrix.toolchain }}
|
||||||
toolchain_url: ${{ fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].toolchain_url }}
|
|
||||||
build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }}
|
build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }}
|
||||||
one-per-family: ${{ github.event_name != 'pull_request' }}
|
one-per-family: ${{ github.event_name != 'pull_request' }}
|
||||||
|
|
||||||
|
# ---------------------------------------
|
||||||
|
# Build CMake arm-gcc
|
||||||
|
# only build with push, for PR: all board is built by circle-ci
|
||||||
|
# ---------------------------------------
|
||||||
|
cmake-arm-gcc:
|
||||||
|
if: github.event_name == 'push'
|
||||||
|
needs: set-matrix
|
||||||
|
uses: ./.github/workflows/build_util.yml
|
||||||
|
with:
|
||||||
|
build-system: 'cmake'
|
||||||
|
toolchain: 'arm-gcc'
|
||||||
|
build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)['arm-gcc'].family) }}
|
||||||
|
one-per-family: true
|
||||||
|
|
||||||
# ---------------------------------------
|
# ---------------------------------------
|
||||||
# Build Make
|
# Build Make
|
||||||
# ---------------------------------------
|
# ---------------------------------------
|
||||||
@ -81,7 +93,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
toolchain:
|
toolchain:
|
||||||
# 'arm-clang' is built by circle-ci
|
# 'arm-clang' would be built by circle-ci
|
||||||
- 'aarch64-gcc'
|
- 'aarch64-gcc'
|
||||||
- 'arm-gcc'
|
- 'arm-gcc'
|
||||||
- 'msp430-gcc'
|
- 'msp430-gcc'
|
||||||
@ -90,7 +102,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
build-system: 'make'
|
build-system: 'make'
|
||||||
toolchain: ${{ matrix.toolchain }}
|
toolchain: ${{ matrix.toolchain }}
|
||||||
toolchain_url: ${{ fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].toolchain_url }}
|
|
||||||
build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }}
|
build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain].family) }}
|
||||||
one-per-family: ${{ github.event_name != 'pull_request' }}
|
one-per-family: ${{ github.event_name != 'pull_request' }}
|
||||||
|
|
||||||
@ -120,14 +131,12 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
board:
|
board:
|
||||||
# ESP32-S2
|
|
||||||
- 'espressif_kaluga_1'
|
- 'espressif_kaluga_1'
|
||||||
# ESP32-S3 skip since devkitm is also compiled in hil-test workflow
|
- 'espressif_s3_devkitm'
|
||||||
#- 'espressif_s3_devkitm'
|
|
||||||
with:
|
with:
|
||||||
build-system: 'cmake'
|
build-system: 'cmake'
|
||||||
toolchain: 'esp-idf'
|
toolchain: 'esp-idf'
|
||||||
toolchain_url: 'v5.1.1'
|
toolchain_version: 'v5.1.1'
|
||||||
build-args: '["-b${{ matrix.board }}"]'
|
build-args: '["-b${{ matrix.board }}"]'
|
||||||
|
|
||||||
# ---------------------------------------
|
# ---------------------------------------
|
||||||
|
17
.github/workflows/build_util.yml
vendored
17
.github/workflows/build_util.yml
vendored
@ -9,7 +9,7 @@ on:
|
|||||||
toolchain:
|
toolchain:
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
toolchain_url:
|
toolchain_version:
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
build-args:
|
build-args:
|
||||||
@ -40,7 +40,7 @@ jobs:
|
|||||||
uses: ./.github/actions/setup_toolchain
|
uses: ./.github/actions/setup_toolchain
|
||||||
with:
|
with:
|
||||||
toolchain: ${{ inputs.toolchain }}
|
toolchain: ${{ inputs.toolchain }}
|
||||||
toolchain_url: ${{ inputs.toolchain_url }}
|
toolchain_version: ${{ inputs.toolchain_version }}
|
||||||
|
|
||||||
- name: Get Dependencies
|
- name: Get Dependencies
|
||||||
uses: ./.github/actions/get_deps
|
uses: ./.github/actions/get_deps
|
||||||
@ -58,11 +58,10 @@ jobs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
if: inputs.toolchain != 'esp-idf'
|
|
||||||
run: |
|
run: |
|
||||||
python tools/build.py -s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ steps.set-one-per-family.outputs.build_option }} ${{ matrix.arg }}
|
if [ "${{ inputs.toolchain }}" == "esp-idf" ]; then
|
||||||
|
docker run --rm -v $PWD:/project -w /project espressif/idf:${{ inputs.toolchain_version }} python3 tools/build.py ${{ matrix.arg }}
|
||||||
- name: Build using ESP-IDF docker
|
else
|
||||||
if: inputs.toolchain == 'esp-idf'
|
python tools/build.py -s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ steps.set-one-per-family.outputs.build_option }} ${{ matrix.arg }}
|
||||||
run: |
|
fi
|
||||||
docker run --rm -v $PWD:/project -w /project espressif/idf:${{ inputs.toolchain_url }} python3 tools/build.py ${{ matrix.arg }}
|
shell: bash
|
||||||
|
27
.github/workflows/ci_set_matrix.py
vendored
27
.github/workflows/ci_set_matrix.py
vendored
@ -1,21 +1,22 @@
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
# toolchain, url
|
# toolchain, url
|
||||||
toolchain_list = {
|
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",
|
"aarch64-gcc",
|
||||||
"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-clang",
|
||||||
"arm-iar": "",
|
"arm-iar",
|
||||||
"arm-gcc": "",
|
"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",
|
"msp430-gcc",
|
||||||
"riscv-gcc": "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz",
|
"riscv-gcc",
|
||||||
"rx-gcc": "http://gcc-renesas.com/downloads/get.php?f=rx/8.3.0.202004-gnurx/gcc-8.3.0.202004-GNURX-ELF.run",
|
"rx-gcc"
|
||||||
}
|
]
|
||||||
|
|
||||||
# family: [supported toolchain]
|
# family: [supported toolchain]
|
||||||
family_list = {
|
family_list = {
|
||||||
"broadcom_32bit": ["arm-gcc"],
|
"broadcom_32bit": ["arm-gcc"],
|
||||||
"broadcom_64bit": ["aarch64-gcc"],
|
"broadcom_64bit": ["aarch64-gcc"],
|
||||||
"ch32v20x ch32v307 fomu gd32vf103": ["riscv-gcc"],
|
"ch32v10x ch32v20x ch32v307 fomu gd32vf103": ["riscv-gcc"],
|
||||||
|
"da1469x": ["arm-gcc"],
|
||||||
"imxrt": ["arm-gcc", "arm-clang"],
|
"imxrt": ["arm-gcc", "arm-clang"],
|
||||||
"kinetis_k kinetis_kl kinetis_k32l2": ["arm-gcc", "arm-clang"],
|
"kinetis_k kinetis_kl kinetis_k32l2": ["arm-gcc", "arm-clang"],
|
||||||
"lpc11 lpc13 lpc15": ["arm-gcc", "arm-clang"],
|
"lpc11 lpc13 lpc15": ["arm-gcc", "arm-clang"],
|
||||||
@ -36,14 +37,14 @@ family_list = {
|
|||||||
"stm32f7": ["arm-gcc", "arm-clang", "arm-iar"],
|
"stm32f7": ["arm-gcc", "arm-clang", "arm-iar"],
|
||||||
"stm32g0 stm32g4 stm32h5": ["arm-gcc", "arm-clang", "arm-iar"],
|
"stm32g0 stm32g4 stm32h5": ["arm-gcc", "arm-clang", "arm-iar"],
|
||||||
"stm32h7": ["arm-gcc", "arm-clang", "arm-iar"],
|
"stm32h7": ["arm-gcc", "arm-clang", "arm-iar"],
|
||||||
"stm32l4 stm32u5 stm32wb": ["arm-gcc", "arm-clang", "arm-iar"],
|
"stm32l0 stm32l4 stm32u5 stm32wb": ["arm-gcc", "arm-clang", "arm-iar"],
|
||||||
"xmc4000": ["arm-gcc"],
|
"xmc4000": ["arm-gcc"],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def set_matrix_json():
|
def set_matrix_json():
|
||||||
matrix = {}
|
matrix = {}
|
||||||
for toolchain in toolchain_list.keys():
|
for toolchain in toolchain_list:
|
||||||
filtered_families = [family for family, supported_toolchain in family_list.items() if
|
filtered_families = [family for family, supported_toolchain in family_list.items() if
|
||||||
toolchain in supported_toolchain]
|
toolchain in supported_toolchain]
|
||||||
|
|
||||||
@ -54,7 +55,7 @@ def set_matrix_json():
|
|||||||
hfp_boards = [f"-b{board['name']}" for board in hfp_data['boards']]
|
hfp_boards = [f"-b{board['name']}" for board in hfp_data['boards']]
|
||||||
filtered_families = filtered_families + hfp_boards
|
filtered_families = filtered_families + hfp_boards
|
||||||
|
|
||||||
matrix[toolchain] = {"family": filtered_families, "toolchain_url": toolchain_list[toolchain]}
|
matrix[toolchain] = {"family": filtered_families}
|
||||||
|
|
||||||
print(json.dumps(matrix))
|
print(json.dumps(matrix))
|
||||||
|
|
||||||
|
2
.github/workflows/cifuzz.yml
vendored
2
.github/workflows/cifuzz.yml
vendored
@ -26,7 +26,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
oss-fuzz-project-name: 'tinyusb'
|
oss-fuzz-project-name: 'tinyusb'
|
||||||
language: c++
|
language: c++
|
||||||
fuzz-seconds: 600
|
fuzz-seconds: 400
|
||||||
|
|
||||||
- name: Upload Crash
|
- name: Upload Crash
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
|
93
.github/workflows/hil_test.yml
vendored
93
.github/workflows/hil_test.yml
vendored
@ -17,6 +17,9 @@ concurrency:
|
|||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
env:
|
||||||
|
HIL_JSON: test/hil/rpi.json
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
# ---------------------------------------
|
# ---------------------------------------
|
||||||
# Build Non Espressif
|
# Build Non Espressif
|
||||||
@ -36,16 +39,21 @@ jobs:
|
|||||||
sudo apt install -y jq
|
sudo apt install -y jq
|
||||||
|
|
||||||
# Non-Espresif boards
|
# Non-Espresif boards
|
||||||
BOARDS_LIST=$(jq -r '.boards[] | select(.flasher != "esptool") | "-b " + .name' test/hil/pi4.json | tr '\n' ' ')
|
BOARDS_LIST=$(jq -r '.boards[] | select(.flasher != "esptool") | "-b " + .name' ${{ env.HIL_JSON }} | tr '\n' ' ')
|
||||||
echo "BOARDS_LIST=$BOARDS_LIST"
|
echo "BOARDS_LIST=$BOARDS_LIST"
|
||||||
echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_ENV
|
echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_ENV
|
||||||
echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_OUTPUT
|
echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Setup Toolchain
|
- name: Setup arm-gcc toolchain
|
||||||
uses: ./.github/actions/setup_toolchain
|
uses: ./.github/actions/setup_toolchain
|
||||||
with:
|
with:
|
||||||
toolchain: 'arm-gcc'
|
toolchain: 'arm-gcc'
|
||||||
|
|
||||||
|
- name: Setup risv-gcc toolchain
|
||||||
|
uses: ./.github/actions/setup_toolchain
|
||||||
|
with:
|
||||||
|
toolchain: 'riscv-gcc'
|
||||||
|
|
||||||
- name: Get Dependencies
|
- name: Get Dependencies
|
||||||
uses: ./.github/actions/get_deps
|
uses: ./.github/actions/get_deps
|
||||||
with:
|
with:
|
||||||
@ -57,71 +65,22 @@ jobs:
|
|||||||
- name: Upload Artifacts for Hardware Testing
|
- name: Upload Artifacts for Hardware Testing
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: hil_pi4
|
name: hil_rpi
|
||||||
path: |
|
path: |
|
||||||
cmake-build/cmake-build-*/*/*/*.elf
|
cmake-build/cmake-build-*/*/*/*.elf
|
||||||
cmake-build/cmake-build-*/*/*/*.bin
|
cmake-build/cmake-build-*/*/*/*.bin
|
||||||
|
|
||||||
# ---------------------------------------
|
|
||||||
# Build Espressif
|
|
||||||
# ---------------------------------------
|
|
||||||
build-esp:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
outputs:
|
|
||||||
BOARDS_LIST: ${{ steps.parse_hil_json.outputs.BOARDS_LIST }}
|
|
||||||
steps:
|
|
||||||
- name: Checkout TinyUSB
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Parse HIL json
|
|
||||||
id: parse_hil_json
|
|
||||||
run: |
|
|
||||||
sudo apt install -y jq
|
|
||||||
# Espressif boards
|
|
||||||
BOARDS_LIST=$(jq -r '.boards[] | select(.flasher == "esptool") | "-b " + .name' test/hil/pi4.json | tr '\n' ' ')
|
|
||||||
echo "BOARDS_LIST=$BOARDS_LIST"
|
|
||||||
echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_ENV
|
|
||||||
echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Setup ESP-IDF
|
|
||||||
if: env.BOARDS_LIST != ''
|
|
||||||
uses: ./.github/actions/setup_toolchain
|
|
||||||
with:
|
|
||||||
toolchain: 'esp-idf'
|
|
||||||
toolchain_url: 'v5.1.1'
|
|
||||||
|
|
||||||
- name: Get Dependencies
|
|
||||||
uses: ./.github/actions/get_deps
|
|
||||||
with:
|
|
||||||
arg: ${{ env.BOARDS_LIST }}
|
|
||||||
|
|
||||||
- name: Build Espressif
|
|
||||||
if: env.BOARDS_LIST != ''
|
|
||||||
run: docker run --rm -v $PWD:/project -w /project espressif/idf:v5.1.1 python3 tools/build.py $BOARDS_LIST
|
|
||||||
|
|
||||||
- name: Upload Artifacts for Hardware Testing
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: hil_pi4_esp
|
|
||||||
path: |
|
|
||||||
cmake-build/cmake-build-*/*/*/*.bin
|
|
||||||
cmake-build/cmake-build-*/*/*/bootloader/bootloader.bin
|
|
||||||
cmake-build/cmake-build-*/*/*/partition_table/partition-table.bin
|
|
||||||
cmake-build/cmake-build-*/*/*/config.env
|
|
||||||
cmake-build/cmake-build-*/*/*/flash_args
|
|
||||||
|
|
||||||
# ---------------------------------------
|
# ---------------------------------------
|
||||||
# Hardware in the loop (HIL)
|
# Hardware in the loop (HIL)
|
||||||
# Current self-hosted instance is running on an RPI4. For attached hardware checkout test/hil/pi4.json
|
# self-hosted running on an RPI. For attached hardware checkout test/hil/rpi.json
|
||||||
# ---------------------------------------
|
# ---------------------------------------
|
||||||
hil-pi4:
|
hil-rpi:
|
||||||
if: github.repository_owner == 'hathach'
|
if: github.repository_owner == 'hathach'
|
||||||
needs:
|
needs:
|
||||||
- build
|
- build
|
||||||
- build-esp
|
runs-on: [self-hosted, ARM64, rpi, hardware-in-the-loop]
|
||||||
runs-on: [self-hosted, rp2040, nrf52840, esp32s3, hardware-in-the-loop]
|
|
||||||
env:
|
env:
|
||||||
BOARDS_LIST: "${{ needs.build.outputs.BOARDS_LIST }} ${{ needs.build-esp.outputs.BOARDS_LIST }}"
|
BOARDS_LIST: "${{ needs.build-esp.outputs.BOARDS_LIST }} ${{ needs.build.outputs.BOARDS_LIST }}"
|
||||||
steps:
|
steps:
|
||||||
- name: Clean workspace
|
- name: Clean workspace
|
||||||
run: |
|
run: |
|
||||||
@ -129,12 +88,12 @@ jobs:
|
|||||||
rm -rf "${{ github.workspace }}"
|
rm -rf "${{ github.workspace }}"
|
||||||
mkdir -p "${{ github.workspace }}"
|
mkdir -p "${{ github.workspace }}"
|
||||||
|
|
||||||
# USB bus on rpi4 is not stable, reset it before testing
|
# USB bus on rpi is not stable, reset it before testing
|
||||||
- name: Reset USB bus
|
# - name: Reset USB bus
|
||||||
run: |
|
# run: |
|
||||||
# lsusb -t
|
# echo "1-2" | sudo tee /sys/bus/usb/drivers/usb/unbind
|
||||||
# reset VIA Labs 2.0 hub
|
# sleep 5
|
||||||
sudo usbreset 001/002
|
# echo "1-2" | sudo tee /sys/bus/usb/drivers/usb/bind
|
||||||
|
|
||||||
- name: Checkout TinyUSB
|
- name: Checkout TinyUSB
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@ -144,14 +103,8 @@ jobs:
|
|||||||
- name: Download Artifacts
|
- name: Download Artifacts
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: hil_pi4
|
|
||||||
path: cmake-build
|
|
||||||
|
|
||||||
- name: Download Artifacts
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: hil_pi4_esp
|
|
||||||
path: cmake-build
|
path: cmake-build
|
||||||
|
merge-multiple: true
|
||||||
|
|
||||||
- name: Test on actual hardware
|
- name: Test on actual hardware
|
||||||
run: |
|
run: |
|
||||||
@ -159,4 +112,4 @@ jobs:
|
|||||||
echo "::group::{cmake-build contents}"
|
echo "::group::{cmake-build contents}"
|
||||||
tree cmake-build
|
tree cmake-build
|
||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
python3 test/hil/hil_test.py $BOARDS_LIST pi4.json
|
python3 test/hil/hil_test.py $BOARDS_LIST ${{ env.HIL_JSON }}
|
||||||
|
60
.gitignore
vendored
60
.gitignore
vendored
@ -31,62 +31,4 @@ cov-int
|
|||||||
__pycache__
|
__pycache__
|
||||||
cmake-build-*
|
cmake-build-*
|
||||||
sdkconfig
|
sdkconfig
|
||||||
|
.PVS-Studio
|
||||||
# submodules
|
|
||||||
hw/mcu/allwinner
|
|
||||||
hw/mcu/bridgetek/ft9xx/ft90x-sdk
|
|
||||||
hw/mcu/broadcom
|
|
||||||
hw/mcu/gd/nuclei-sdk
|
|
||||||
hw/mcu/infineon/mtb-xmclib-cat3
|
|
||||||
hw/mcu/microchip
|
|
||||||
hw/mcu/mindmotion/mm32sdk
|
|
||||||
hw/mcu/nordic/nrfx
|
|
||||||
hw/mcu/nuvoton
|
|
||||||
hw/mcu/nxp/lpcopen
|
|
||||||
hw/mcu/nxp/mcux-sdk
|
|
||||||
hw/mcu/nxp/nxp_sdk
|
|
||||||
hw/mcu/raspberry_pi/Pico-PIO-USB
|
|
||||||
hw/mcu/renesas/rx
|
|
||||||
hw/mcu/silabs/cmsis-dfp-efm32gg12b
|
|
||||||
hw/mcu/sony/cxd56/spresense-exported-sdk
|
|
||||||
hw/mcu/st/cmsis_device_f0
|
|
||||||
hw/mcu/st/cmsis_device_f1
|
|
||||||
hw/mcu/st/cmsis_device_f2
|
|
||||||
hw/mcu/st/cmsis_device_f3
|
|
||||||
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
|
|
||||||
hw/mcu/st/cmsis_device_l4
|
|
||||||
hw/mcu/st/cmsis_device_l5
|
|
||||||
hw/mcu/st/cmsis_device_u5
|
|
||||||
hw/mcu/st/cmsis_device_wb
|
|
||||||
hw/mcu/st/stm32f0xx_hal_driver
|
|
||||||
hw/mcu/st/stm32f1xx_hal_driver
|
|
||||||
hw/mcu/st/stm32f2xx_hal_driver
|
|
||||||
hw/mcu/st/stm32f3xx_hal_driver
|
|
||||||
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
|
|
||||||
hw/mcu/st/stm32l4xx_hal_driver
|
|
||||||
hw/mcu/st/stm32l5xx_hal_driver
|
|
||||||
hw/mcu/st/stm32u5xx_hal_driver
|
|
||||||
hw/mcu/st/stm32wbxx_hal_driver
|
|
||||||
hw/mcu/ti
|
|
||||||
hw/mcu/wch/ch32v20x
|
|
||||||
hw/mcu/wch/ch32v307
|
|
||||||
hw/mcu/wch/ch32f20x
|
|
||||||
lib/CMSIS_5
|
|
||||||
lib/FreeRTOS-Kernel
|
|
||||||
lib/lwip
|
|
||||||
lib/sct_neopixel
|
|
||||||
tools/uf2
|
|
||||||
|
139
.idea/cmake.xml
generated
139
.idea/cmake.xml
generated
@ -3,138 +3,143 @@
|
|||||||
<component name="CMakeSharedSettings">
|
<component name="CMakeSharedSettings">
|
||||||
<configurations>
|
<configurations>
|
||||||
<configuration PROFILE_NAME="pico" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=raspberry_pi_pico -DLOG=1" />
|
<configuration PROFILE_NAME="pico" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=raspberry_pi_pico -DLOG=1" />
|
||||||
<configuration PROFILE_NAME="feather_rp2040" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=pico_sdk -DPICO_BOARD=adafruit_feather_rp2040 -DLOG=2" />
|
<configuration PROFILE_NAME="pico pio-host" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=raspberry_pi_pico -DLOG=1 -DCFLAGS_CLI="-DCFG_TUH_RPI_PIO_USB=1"" />
|
||||||
<configuration PROFILE_NAME="feather_rp2040_max3421" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=feather_rp2040_max3421 -DLOG=2" />
|
<configuration PROFILE_NAME="feather_rp2040" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=pico_sdk -DPICO_BOARD=adafruit_feather_rp2040 -DLOG=1" />
|
||||||
<configuration PROFILE_NAME="metro_rp2040" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=pico_sdk -DPICO_BOARD=adafruit_metro_rp2040 -DLOG=2 -DMAX3421_HOST=1" />
|
<configuration PROFILE_NAME="feather_rp2040_max3421" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=feather_rp2040_max3421 -DLOG=1" />
|
||||||
<configuration PROFILE_NAME="feather esp32s2" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=adafruit_feather_esp32s2 -DMAX3421_HOST=1 -DLOG=2">
|
<configuration PROFILE_NAME="metro_rp2040" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=pico_sdk -DPICO_BOARD=adafruit_metro_rp2040 -DLOG=1 -DMAX3421_HOST=1" />
|
||||||
|
<configuration PROFILE_NAME="feather esp32s2" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=adafruit_feather_esp32s2 -DMAX3421_HOST=1 -DLOG=1">
|
||||||
<ADDITIONAL_GENERATION_ENVIRONMENT>
|
<ADDITIONAL_GENERATION_ENVIRONMENT>
|
||||||
<envs>
|
<envs>
|
||||||
<env name="ESPBAUD" value="1500000" />
|
<env name="ESPBAUD" value="1500000" />
|
||||||
</envs>
|
</envs>
|
||||||
</ADDITIONAL_GENERATION_ENVIRONMENT>
|
</ADDITIONAL_GENERATION_ENVIRONMENT>
|
||||||
</configuration>
|
</configuration>
|
||||||
<configuration PROFILE_NAME="metro esp32s2" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=adafruit_metro_esp32s2 -DMAX3421_HOST=1 -DLOG=2">
|
<configuration PROFILE_NAME="metro esp32s2" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=adafruit_metro_esp32s2 -DMAX3421_HOST=1 -DLOG=1">
|
||||||
<ADDITIONAL_GENERATION_ENVIRONMENT>
|
<ADDITIONAL_GENERATION_ENVIRONMENT>
|
||||||
<envs>
|
<envs>
|
||||||
<env name="ESPBAUD" value="1500000" />
|
<env name="ESPBAUD" value="1500000" />
|
||||||
</envs>
|
</envs>
|
||||||
</ADDITIONAL_GENERATION_ENVIRONMENT>
|
</ADDITIONAL_GENERATION_ENVIRONMENT>
|
||||||
</configuration>
|
</configuration>
|
||||||
<configuration PROFILE_NAME="kaluga" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=espressif_kaluga_1 -DMAX3421_HOST=1 -DLOG=2">
|
<configuration PROFILE_NAME="kaluga" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=espressif_kaluga_1 -DMAX3421_HOST=1 -DLOG=1">
|
||||||
<ADDITIONAL_GENERATION_ENVIRONMENT>
|
<ADDITIONAL_GENERATION_ENVIRONMENT>
|
||||||
<envs>
|
<envs>
|
||||||
<env name="ESPBAUD" value="1500000" />
|
<env name="ESPBAUD" value="1500000" />
|
||||||
</envs>
|
</envs>
|
||||||
</ADDITIONAL_GENERATION_ENVIRONMENT>
|
</ADDITIONAL_GENERATION_ENVIRONMENT>
|
||||||
</configuration>
|
</configuration>
|
||||||
<configuration PROFILE_NAME="feather esp32s3" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=adafruit_feather_esp32s3 -DMAX3421_HOST=1 -DLOG=2">
|
<configuration PROFILE_NAME="feather esp32s3" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=adafruit_feather_esp32s3 -DMAX3421_HOST=1 -DLOG=1">
|
||||||
<ADDITIONAL_GENERATION_ENVIRONMENT>
|
<ADDITIONAL_GENERATION_ENVIRONMENT>
|
||||||
<envs>
|
<envs>
|
||||||
<env name="ESPBAUD" value="1500000" />
|
<env name="ESPBAUD" value="1500000" />
|
||||||
</envs>
|
</envs>
|
||||||
</ADDITIONAL_GENERATION_ENVIRONMENT>
|
</ADDITIONAL_GENERATION_ENVIRONMENT>
|
||||||
</configuration>
|
</configuration>
|
||||||
<configuration PROFILE_NAME="espressif_s3_devkitc" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=espressif_s3_devkitc -DMAX3421_HOST=1 -DLOG=2">
|
<configuration PROFILE_NAME="espressif_s3_devkitc" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=espressif_s3_devkitc -DMAX3421_HOST=1 -DLOG=1">
|
||||||
<ADDITIONAL_GENERATION_ENVIRONMENT>
|
<ADDITIONAL_GENERATION_ENVIRONMENT>
|
||||||
<envs>
|
<envs>
|
||||||
<env name="ESPBAUD" value="1500000" />
|
<env name="ESPBAUD" value="1500000" />
|
||||||
</envs>
|
</envs>
|
||||||
</ADDITIONAL_GENERATION_ENVIRONMENT>
|
</ADDITIONAL_GENERATION_ENVIRONMENT>
|
||||||
</configuration>
|
</configuration>
|
||||||
<configuration PROFILE_NAME="adafruit_metro_esp32s2" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=adafruit_metro_esp32s2 -DMAX3421_HOST=1 -DLOG=2">
|
<configuration PROFILE_NAME="adafruit_metro_esp32s2" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=adafruit_metro_esp32s2 -DMAX3421_HOST=1 -DLOG=1">
|
||||||
<ADDITIONAL_GENERATION_ENVIRONMENT>
|
<ADDITIONAL_GENERATION_ENVIRONMENT>
|
||||||
<envs>
|
<envs>
|
||||||
<env name="ESPBAUD" value="1500000" />
|
<env name="ESPBAUD" value="1500000" />
|
||||||
</envs>
|
</envs>
|
||||||
</ADDITIONAL_GENERATION_ENVIRONMENT>
|
</ADDITIONAL_GENERATION_ENVIRONMENT>
|
||||||
</configuration>
|
</configuration>
|
||||||
<configuration PROFILE_NAME="adafruit_feather_esp32_v2" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=adafruit_feather_esp32_v2 -DMAX3421_HOST=1 -DLOG=2">
|
<configuration PROFILE_NAME="adafruit_feather_esp32_v2" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=adafruit_feather_esp32_v2 -DMAX3421_HOST=1 -DLOG=1">
|
||||||
<ADDITIONAL_GENERATION_ENVIRONMENT>
|
<ADDITIONAL_GENERATION_ENVIRONMENT>
|
||||||
<envs>
|
<envs>
|
||||||
<env name="ESPBAUD" value="1500000" />
|
<env name="ESPBAUD" value="1500000" />
|
||||||
</envs>
|
</envs>
|
||||||
</ADDITIONAL_GENERATION_ENVIRONMENT>
|
</ADDITIONAL_GENERATION_ENVIRONMENT>
|
||||||
</configuration>
|
</configuration>
|
||||||
<configuration PROFILE_NAME="espressif_c3_devkitc" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=espressif_c3_devkitc -DMAX3421_HOST=1 -DLOG=2">
|
<configuration PROFILE_NAME="espressif_c3_devkitc" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=espressif_c3_devkitc -DMAX3421_HOST=1 -DLOG=1">
|
||||||
<ADDITIONAL_GENERATION_ENVIRONMENT>
|
<ADDITIONAL_GENERATION_ENVIRONMENT>
|
||||||
<envs>
|
<envs>
|
||||||
<env name="ESPBAUD" value="1500000" />
|
<env name="ESPBAUD" value="1500000" />
|
||||||
</envs>
|
</envs>
|
||||||
</ADDITIONAL_GENERATION_ENVIRONMENT>
|
</ADDITIONAL_GENERATION_ENVIRONMENT>
|
||||||
</configuration>
|
</configuration>
|
||||||
<configuration PROFILE_NAME="feather_m0_express" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=feather_m0_express -DLOG=3 -DLOGGER=RTT -DMAX3421_HOST=1" />
|
<configuration PROFILE_NAME="feather_m0_express" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=feather_m0_express -DLOG=1 -DLOGGER=RTT -DMAX3421_HOST=1" />
|
||||||
<configuration PROFILE_NAME="metro_m0_express" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=metro_m0_express -DLOG=3 -DLOGGER=RTT -DMAX3421_HOST=1" />
|
<configuration PROFILE_NAME="metro_m0_express" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=metro_m0_express -DLOG=1 -DLOGGER=RTT -DMAX3421_HOST=1" />
|
||||||
<configuration PROFILE_NAME="feather_m4_express" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=feather_m4_express -DLOG=3 -DLOGGER=RTT -DMAX3421_HOST=1" />
|
<configuration PROFILE_NAME="feather_m4_express" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=feather_m4_express -DLOG=1 -DLOGGER=RTT -DMAX3421_HOST=1" />
|
||||||
<configuration PROFILE_NAME="metro_m4_express" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=metro_m4_express -DLOG=3 -DLOGGER=RTT -DMAX3421_HOST=1" />
|
<configuration PROFILE_NAME="metro_m4_express" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=metro_m4_express" />
|
||||||
<configuration PROFILE_NAME="itsybitsy_m4" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=itsybitsy_m4 -DLOG=3 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="itsybitsy_m4" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=itsybitsy_m4" />
|
||||||
<configuration PROFILE_NAME="same54_xplained" ENABLED="false" GENERATION_OPTIONS="-DBOARD=same54_xplained -DLOG=2 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="same54_xplained" ENABLED="false" GENERATION_OPTIONS="-DBOARD=same54_xplained -DLOG=1 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="feather_nrf52840_express" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=feather_nrf52840_express -DLOG=3 -DLOGGER=RTT -DMAX3421_HOST=1" />
|
<configuration PROFILE_NAME="feather_nrf52840_express" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=feather_nrf52840_express -DLOG=1 -DLOGGER=RTT -DMAX3421_HOST=1" />
|
||||||
<configuration PROFILE_NAME="pca10056" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=pca10056 -DLOG=3 -DLOGGER=RTT -DTRACE_ETM=1" />
|
<configuration PROFILE_NAME="pca10056" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=pca10056 -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
|
||||||
<configuration PROFILE_NAME="pca10095" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=pca10095 -DLOG=3 -DLOGGER=RTT -DTRACE_ETM=1" />
|
<configuration PROFILE_NAME="pca10095" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=pca10095 -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
|
||||||
<configuration PROFILE_NAME="metro m7 1011 sd" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=metro_m7_1011_sd -DLOG=3 -DLOGGER=RTT -DTRACE_ETM=1" />
|
<configuration PROFILE_NAME="metro m7 1011 sd" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=metro_m7_1011_sd -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
|
||||||
<configuration PROFILE_NAME="metro m7 1011" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=metro_m7_1011 -DLOG=3 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="metro_m7_1011" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=metro_m7_1011 -DLOG=1 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="rt1010 evk" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=mimxrt1010_evk -DLOG=3 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="rt1010 evk" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=mimxrt1010_evk -DLOG=1 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="rt1060 evk" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=mimxrt1060_evk -DLOG=3 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="rt1060 evk" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=mimxrt1060_evk -DLOG=1 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="rt1170 evkb" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=mimxrt1170_evkb -DLOG=3 -DLOGGER=RTT -DTRACE_ETM=1" />
|
<configuration PROFILE_NAME="rt1170 evkb" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=mimxrt1170_evkb -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
|
||||||
<configuration PROFILE_NAME="lpcxpresso1769" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso1769 -DLOG=3 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="lpcxpresso1769" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso1769 -DLOG=1 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="mcb1800" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=mcb1800 -DLOG=3 -DLOGGER=RTT -DTRACE_ETM=1" />
|
<configuration PROFILE_NAME="mcb1800" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=mcb1800 -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
|
||||||
<configuration PROFILE_NAME="ea4088 quickstart" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ea4088_quickstart -DLOG=3 -DLOGGER=RTT -DTRACE_ETM=1" />
|
<configuration PROFILE_NAME="ea4088 quickstart" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ea4088_quickstart -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
|
||||||
<configuration PROFILE_NAME="ea4357" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ea4357 -DLOG=3 -DLOGGER=RTT -DTRACE_ETM=1" />
|
<configuration PROFILE_NAME="ea4357" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ea4357 -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
|
||||||
<configuration PROFILE_NAME="lpc5414" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso54114 -DLOG=1 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="lpc5414" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso54114 -DLOG=1 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="lpc54628" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso54628 -DLOG=3 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="lpc54628" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso54628 -DLOG=1 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="lpc55s69" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso55s69 -DLOG=3 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="lpc55s69" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso55s69 -DLOG=1 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="mcxn947brk" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=mcxn947brk -DLOG=3 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="mcxn947brk" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=mcxn947brk -DLOG=1 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="frdm_mcxa153" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=frdm_mcxa153 -DLOG=3 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="frdm_mcxa153" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=frdm_mcxa153 -DLOG=1 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="frdm_kl25z" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=frdm_kl25z -DLOG=3 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="frdm_kl25z" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=frdm_kl25z -DLOG=1 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="frdm_k32l2a4s" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=frdm_k32l2a4s" />
|
<configuration PROFILE_NAME="frdm_k32l2a4s" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=frdm_k32l2a4s" />
|
||||||
<configuration PROFILE_NAME="frdm_k64f" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=frdm_k64f -DLOG=2 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="frdm_k64f" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=frdm_k64f -DLOG=1 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="stm32f072disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f072disco" />
|
<configuration PROFILE_NAME="stm32f072disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f072disco -DLOG=0 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="stm32f103_mini_2" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f103_mini_2" />
|
<configuration PROFILE_NAME="stm32f103_mini_2" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f103_mini_2 -DLOG=1 -DLOGGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="stm32f207nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f207nucleo -DLOG=2 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="stm32f103ze_iar" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f103ze_iar -DLOG=1 -DLOGGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="stm32f303disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f303disco -DLOG=2 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="stm32f207nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f207nucleo -DLOG=1 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="stm32f411disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f411disco -DLOG=2 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="stm32f303disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f303disco -DLOG=0 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="stm32f769disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f769disco -DLOG=3 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="stm32f411disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f411disco -DLOG=1 -DLOGGER=RTT" />
|
||||||
|
<configuration PROFILE_NAME="stm32f769disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f769disco -DLOG=1 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="stm32g0b1nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32g0b1nucleo" />
|
<configuration PROFILE_NAME="stm32g0b1nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32g0b1nucleo" />
|
||||||
<configuration PROFILE_NAME="stm32g474nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32g474nucleo" />
|
<configuration PROFILE_NAME="stm32g474nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32g474nucleo" />
|
||||||
<configuration PROFILE_NAME="b_g474e_dpow1" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=b_g474e_dpow1 -DLOG=3 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="b_g474e_dpow1" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=b_g474e_dpow1 -DLOG=1 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="stm32h563nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32h563nucleo -DLOG=3 -DLOGGER=RTT -DTRACE_ETM=1" />
|
<configuration PROFILE_NAME="stm32h563nucleo" ENABLED="false" GENERATION_OPTIONS="-DBOARD=stm32h563nucleo -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
|
||||||
<configuration PROFILE_NAME="stm32h743eval" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32h743eval -DLOG=3 -DLOGGER=RTT -DTRACE_ETM=1" />
|
<configuration PROFILE_NAME="stm32h743eval" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32h743eval -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
|
||||||
<configuration PROFILE_NAME="stm32h743nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32h743nucleo -DLOG=3" />
|
<configuration PROFILE_NAME="stm32h743nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32h743nucleo -DLOG=1" />
|
||||||
<configuration PROFILE_NAME="stm32l0538disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32l0538disco" />
|
<configuration PROFILE_NAME="stm32l0538disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32l0538disco -DLOG=0 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="stm32l476disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32l476disco" />
|
<configuration PROFILE_NAME="stm32l476disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32l476disco" />
|
||||||
<configuration PROFILE_NAME="stm32u575nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32u575nucleo -DLOG=2 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="stm32u575nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32u575nucleo -DLOG=1 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="stm32u5a5nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32u5a5nucleo -DLOG=3 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="stm32u5a5nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32u5a5nucleo -DLOG=1 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="stm32wb55nucleo" ENABLED="false" GENERATION_OPTIONS="-DBOARD=stm32wb55nucleo" />
|
<configuration PROFILE_NAME="stm32wb55nucleo" ENABLED="false" GENERATION_OPTIONS="-DBOARD=stm32wb55nucleo" />
|
||||||
<configuration PROFILE_NAME="ra2a1" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ra2a1_ek -DLOG=3 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="ra2a1_ek" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ra2a1_ek -DLOG=1 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="ra4m1" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ra4m1_ek -DLOG=3 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="ra4m1_ek" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ra4m1_ek -DLOG=1 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="ra6m1" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ra6m1_ek -DLOG=3 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="ra6m1_ek" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ra6m1_ek -DLOG=1 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="ra6m5" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ra6m5_ek -DLOG=3 -DLOGGER=RTT -DTRACE_ETM=1" />
|
<configuration PROFILE_NAME="ra6m5_ek" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ra6m5_ek -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
|
||||||
<configuration PROFILE_NAME="ra6m5 PORT0" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ra6m5_ek -DLOG=3 -DLOGGER=RTT -DTRACE_ETM=1 -DPORT=0" />
|
<configuration PROFILE_NAME="ra6m5_ek PORT0" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ra6m5_ek -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1 -DPORT=0" />
|
||||||
<configuration PROFILE_NAME="uno_r4" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=uno_r4 -DLOG=4 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="uno_r4" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=uno_r4 -DLOG=4 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="portenta_c33" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=portenta_c33 -DLOG=3" />
|
<configuration PROFILE_NAME="portenta_c33" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=portenta_c33 -DLOG=1" />
|
||||||
<configuration PROFILE_NAME="msp430f5529" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=msp_exp430f5529lp" />
|
<configuration PROFILE_NAME="msp430f5529" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=msp_exp430f5529lp" />
|
||||||
<configuration PROFILE_NAME="raspberrypi_zero" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=raspberrypi_zero -DLOG=2" />
|
<configuration PROFILE_NAME="raspberrypi_zero" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=raspberrypi_zero -DLOG=1" />
|
||||||
<configuration PROFILE_NAME="raspberrypi_cm4" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=raspberrypi_cm4 -DLOG=2" />
|
<configuration PROFILE_NAME="raspberrypi_cm4" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=raspberrypi_cm4 -DLOG=1" />
|
||||||
<configuration PROFILE_NAME="raspberrypi_zero2" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=raspberrypi_zero2 -DLOG=2" />
|
<configuration PROFILE_NAME="raspberrypi_zero2" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=raspberrypi_zero2 -DLOG=1" />
|
||||||
<configuration PROFILE_NAME="lpcxpresso11u68" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso11u68 -DLOG=2 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="lpcxpresso11u37" ENABLED="false" GENERATION_OPTIONS="-DBOARD=lpcxpresso11u37" />
|
||||||
<configuration PROFILE_NAME="lpcxpresso1347" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso1347 -DLOG=2 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="lpcxpresso11u68" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso11u68 -DLOG=1 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="lpcxpresso1549" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso1549 -DLOG=2 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="lpcxpresso1347" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso1347 -DLOG=1 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="lpcxpresso51u68" ENABLED="false" CONFIG_NAME="Debug" TOOLCHAIN_NAME="armclang 17.0.1" GENERATION_OPTIONS="-DBOARD=lpcxpresso51u68 -DLOG=2 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="lpcxpresso1549" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso1549 -DLOG=1 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="msp_exp432e401y" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=msp_exp432e401y -DLOG=2" />
|
<configuration PROFILE_NAME="lpcxpresso51u68" ENABLED="false" CONFIG_NAME="Debug" TOOLCHAIN_NAME="armclang 17.0.1" GENERATION_OPTIONS="-DBOARD=lpcxpresso51u68 -DLOG=1 -DLOGGER=RTT" />
|
||||||
|
<configuration PROFILE_NAME="msp_exp432e401y" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=msp_exp432e401y -DLOG=1" />
|
||||||
<configuration PROFILE_NAME="atsaml21_xpro" ENABLED="false" GENERATION_OPTIONS="-DBOARD=atsaml21_xpro" />
|
<configuration PROFILE_NAME="atsaml21_xpro" ENABLED="false" GENERATION_OPTIONS="-DBOARD=atsaml21_xpro" />
|
||||||
<configuration PROFILE_NAME="samd11_xplained" ENABLED="false" CONFIG_NAME="MinSizeRel" GENERATION_OPTIONS="-DBOARD=samd11_xplained" />
|
<configuration PROFILE_NAME="samd11_xplained" ENABLED="false" CONFIG_NAME="MinSizeRel" GENERATION_OPTIONS="-DBOARD=samd11_xplained" />
|
||||||
<configuration PROFILE_NAME="ek_tm4c123gxl" ENABLED="false" CONFIG_NAME="MinSizeRel" GENERATION_OPTIONS="-DBOARD=ek_tm4c123gxl" />
|
<configuration PROFILE_NAME="ek_tm4c123gxl" ENABLED="false" CONFIG_NAME="MinSizeRel" GENERATION_OPTIONS="-DBOARD=ek_tm4c123gxl" />
|
||||||
<configuration PROFILE_NAME="xmc4500_relax" ENABLED="false" GENERATION_OPTIONS="-DBOARD=xmc4500_relax -DLOG=2 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="xmc4500_relax" ENABLED="false" GENERATION_OPTIONS="-DBOARD=xmc4500_relax -DLOG=1 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="f1c100s" ENABLED="false" GENERATION_OPTIONS="-DBOARD=f1c100s" />
|
<configuration PROFILE_NAME="f1c100s" ENABLED="false" GENERATION_OPTIONS="-DBOARD=f1c100s" />
|
||||||
<configuration PROFILE_NAME="mm32f327x_mb39" ENABLED="false" GENERATION_OPTIONS="-DBOARD=mm32f327x_mb39" />
|
<configuration PROFILE_NAME="mm32f327x_mb39" ENABLED="false" GENERATION_OPTIONS="-DBOARD=mm32f327x_mb39" />
|
||||||
<configuration PROFILE_NAME="samg55_xplained" ENABLED="false" GENERATION_OPTIONS="-DBOARD=samg55_xplained" />
|
<configuration PROFILE_NAME="samg55_xplained" ENABLED="false" GENERATION_OPTIONS="-DBOARD=samg55_xplained" />
|
||||||
<configuration PROFILE_NAME="fomu" ENABLED="false" GENERATION_OPTIONS="-DBOARD=fomu" />
|
<configuration PROFILE_NAME="fomu" ENABLED="false" GENERATION_OPTIONS="-DBOARD=fomu" />
|
||||||
<configuration PROFILE_NAME="sipeed_longan_nano" ENABLED="false" GENERATION_OPTIONS="-DBOARD=sipeed_longan_nano" />
|
<configuration PROFILE_NAME="sipeed_longan_nano" ENABLED="false" GENERATION_OPTIONS="-DBOARD=sipeed_longan_nano" />
|
||||||
<configuration PROFILE_NAME="nanoch32v203" ENABLED="false" GENERATION_OPTIONS="-DBOARD=nanoch32v203" />
|
<configuration PROFILE_NAME="nanoch32v203" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=nanoch32v203" />
|
||||||
<configuration PROFILE_NAME="ch32v203_r0_1v0" ENABLED="true" CONFIG_NAME="MinSizeRel" GENERATION_OPTIONS="-DBOARD=ch32v203_r0_1v0" />
|
<configuration PROFILE_NAME="ch32v203c_r0_1v0" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ch32v203c_r0_1v0 -DLOG=0" />
|
||||||
<configuration PROFILE_NAME="ch32v203_r0_1v0 USBFS" ENABLED="false" CONFIG_NAME="MinSizeRel" GENERATION_OPTIONS="-DBOARD=ch32v203_r0_1v0 -DPORT=1" />
|
<configuration PROFILE_NAME="ch32v203c_r0_1v0 USBFS" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ch32v203c_r0_1v0 -DPORT=1" />
|
||||||
<configuration PROFILE_NAME="ch32v307v_r1_1v0" ENABLED="false" GENERATION_OPTIONS="-DBOARD=ch32v307v_r1_1v0 -DLOG=2" />
|
<configuration PROFILE_NAME="ch32v203g_r0_1v0" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ch32v203g_r0_1v0" />
|
||||||
|
<configuration PROFILE_NAME="ch32v307v_r1_1v0" ENABLED="false" GENERATION_OPTIONS="-DBOARD=ch32v307v_r1_1v0 -DLOG=1" />
|
||||||
<configuration PROFILE_NAME="ch32v307v_r1_1v0 USBFS" ENABLED="false" GENERATION_OPTIONS="-DBOARD=ch32v307v_r1_1v0 -DSPEED=full" />
|
<configuration PROFILE_NAME="ch32v307v_r1_1v0 USBFS" ENABLED="false" GENERATION_OPTIONS="-DBOARD=ch32v307v_r1_1v0 -DSPEED=full" />
|
||||||
|
<configuration PROFILE_NAME="da14695_dk_usb" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=da14695_dk_usb" />
|
||||||
</configurations>
|
</configurations>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
@ -151,8 +151,9 @@ Following CPUs are supported, check out `Supported Devices`_ for comprehensive l
|
|||||||
+--------------+------------------------------------------------------------+
|
+--------------+------------------------------------------------------------+
|
||||||
| Sony | CXD56 |
|
| Sony | CXD56 |
|
||||||
+--------------+------------------------------------------------------------+
|
+--------------+------------------------------------------------------------+
|
||||||
| ST STM32 | F0, F1, F2, F3, F4, F7, H5, H7, G0, G4, L0, L1, L4, L4+, |
|
| ST STM32 | F0, F1, F2, F3, F4, F7, G0, G4, H5, H7, |
|
||||||
| | U5, WB |
|
| | |
|
||||||
|
| | L0, L1, L4, L4+, L5, U5, WB |
|
||||||
+--------------+------------------------------------------------------------+
|
+--------------+------------------------------------------------------------+
|
||||||
| TI | MSP430, MSP432E4, TM4C123 |
|
| TI | MSP430, MSP432E4, TM4C123 |
|
||||||
+--------------+------------------------------------------------------------+
|
+--------------+------------------------------------------------------------+
|
||||||
|
@ -104,21 +104,33 @@ Supported MCUs
|
|||||||
| +-----------------------+--------+------+-----------+-------------------+--------------+
|
| +-----------------------+--------+------+-----------+-------------------+--------------+
|
||||||
| | F7 | ✔ | | ✔ | dwc2 | |
|
| | F7 | ✔ | | ✔ | dwc2 | |
|
||||||
| +-----------------------+--------+------+-----------+-------------------+--------------+
|
| +-----------------------+--------+------+-----------+-------------------+--------------+
|
||||||
| | H7 | ✔ | | ✔ | dwc2 | |
|
| | G0 | ✔ | | ✖ | stm32_fsdev | |
|
||||||
| +-----------------------+--------+------+-----------+-------------------+--------------+
|
| +-----------------------+--------+------+-----------+-------------------+--------------+
|
||||||
| | G4 | ✔ | ✖ | ✖ | stm32_fsdev | |
|
| | G4 | ✔ | ✖ | ✖ | stm32_fsdev | |
|
||||||
| +-----------------------+--------+------+-----------+-------------------+--------------+
|
| +-----------------------+--------+------+-----------+-------------------+--------------+
|
||||||
| | L0, L1 | ✔ | ✖ | ✖ | stm32_fsdev | |
|
| | H5 | ✔ | | ✖ | stm32_fsdev | |
|
||||||
|
| +-----------------------+--------+------+-----------+-------------------+--------------+
|
||||||
|
| | H7 | ✔ | | ✔ | dwc2 | |
|
||||||
|
| +-----------------------+--------+------+-----------+-------------------+--------------+
|
||||||
|
| | L0 | ✔ | ✖ | ✖ | stm32_fsdev | |
|
||||||
|
| +-----------------------+--------+------+-----------+-------------------+--------------+
|
||||||
|
| | L1 | ✔ | ✖ | ✖ | stm32_fsdev | |
|
||||||
| +----+------------------+--------+------+-----------+-------------------+--------------+
|
| +----+------------------+--------+------+-----------+-------------------+--------------+
|
||||||
| | L4 | 4x2, 4x3 | ✔ | ✖ | ✖ | stm32_fsdev | |
|
| | L4 | 4x2, 4x3 | ✔ | ✖ | ✖ | stm32_fsdev | |
|
||||||
| | +------------------+--------+------+-----------+-------------------+--------------+
|
| | +------------------+--------+------+-----------+-------------------+--------------+
|
||||||
| | | 4x5, 4x6 | ✔ | | | dwc2 | |
|
| | | 4x5, 4x6 | ✔ | | ✖ | dwc2 | |
|
||||||
| +----+------------------+--------+------+-----------+-------------------+--------------+
|
| +----+------------------+--------+------+-----------+-------------------+--------------+
|
||||||
| | L4+ | ✔ | | | dwc2 | |
|
| | L4+ | ✔ | | ✖ | dwc2 | |
|
||||||
| +-----------------------+--------+------+-----------+-------------------+--------------+
|
| +-----------------------+--------+------+-----------+-------------------+--------------+
|
||||||
| | U5 | ✔ | | ✔ | dwc2 | |
|
| | L5 | ✔ | ✖ | ✖ | stm32_fsdev | |
|
||||||
| +-----------------------+--------+------+-----------+-------------------+--------------+
|
| +----+------------------+--------+------+-----------+-------------------+--------------+
|
||||||
| | WBx5 | ✔ | | | stm32_fsdev | |
|
| | U5 | 535, 545 | ✔ | | ✖ | stm32_fsdev | |
|
||||||
|
| | +------------------+--------+------+-----------+-------------------+--------------+
|
||||||
|
| | | 575, 585 | ✔ | | ✖ | dwc2 | |
|
||||||
|
| | +------------------+--------+------+-----------+-------------------+--------------+
|
||||||
|
| | | 59x,5Ax,5Fx,5Gx | ✔ | | ✔ | dwc2 | |
|
||||||
|
| +----+------------------+--------+------+-----------+-------------------+--------------+
|
||||||
|
| | WBx5 | ✔ | ✖ | ✖ | stm32_fsdev | |
|
||||||
+--------------+-----------------------+--------+------+-----------+-------------------+--------------+
|
+--------------+-----------------------+--------+------+-----------+-------------------+--------------+
|
||||||
| TI | MSP430 | ✔ | ✖ | ✖ | msp430x5xx | |
|
| TI | MSP430 | ✔ | ✖ | ✖ | msp430x5xx | |
|
||||||
| +-----------------------+--------+------+-----------+-------------------+--------------+
|
| +-----------------------+--------+------+-----------+-------------------+--------------+
|
||||||
@ -129,7 +141,9 @@ Supported MCUs
|
|||||||
| ValentyUSB | eptri | ✔ | ✖ | ✖ | eptri | |
|
| ValentyUSB | eptri | ✔ | ✖ | ✖ | eptri | |
|
||||||
+--------------+-----------------------+--------+------+-----------+-------------------+--------------+
|
+--------------+-----------------------+--------+------+-----------+-------------------+--------------+
|
||||||
| WCH | CH32F20x | ✔ | | ✔ | ch32f205 | |
|
| WCH | CH32F20x | ✔ | | ✔ | ch32f205 | |
|
||||||
|
| +-----------------------+--------+------+-----------+-------------------+--------------+
|
||||||
| | CH32V20x | ✔ | | ✖ | ch32v20x | |
|
| | CH32V20x | ✔ | | ✖ | ch32v20x | |
|
||||||
|
| +-----------------------+--------+------+-----------+-------------------+--------------+
|
||||||
| | CH32V307 | ✔ | | ✔ | ch32v307 | |
|
| | CH32V307 | ✔ | | ✔ | ch32v307 | |
|
||||||
+--------------+-----------------------+--------+------+-----------+-------------------+--------------+
|
+--------------+-----------------------+--------+------+-----------+-------------------+--------------+
|
||||||
|
|
||||||
@ -137,11 +151,12 @@ Supported MCUs
|
|||||||
Table Legend
|
Table Legend
|
||||||
------------
|
------------
|
||||||
|
|
||||||
= ===================
|
========= =========================
|
||||||
✔ Supported
|
✔ Supported
|
||||||
⚠ WIP/partial support
|
⚠ Partial support
|
||||||
✖ Not supported
|
✖ Not supported by hardware
|
||||||
= ===================
|
\[empty\] Unknown
|
||||||
|
========= =========================
|
||||||
|
|
||||||
Supported Boards
|
Supported Boards
|
||||||
================
|
================
|
||||||
|
25
examples/build_system/cmake/cpu/cortex-m33-nodsp.cmake
Normal file
25
examples/build_system/cmake/cpu/cortex-m33-nodsp.cmake
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
if (TOOLCHAIN STREQUAL "gcc")
|
||||||
|
set(TOOLCHAIN_COMMON_FLAGS
|
||||||
|
-mthumb
|
||||||
|
-mcpu=cortex-m33+nodsp
|
||||||
|
-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+nodsp
|
||||||
|
-mfpu=fpv5-sp-d16
|
||||||
|
)
|
||||||
|
set(FREERTOS_PORT GCC_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "")
|
||||||
|
|
||||||
|
elseif (TOOLCHAIN STREQUAL "iar")
|
||||||
|
set(TOOLCHAIN_COMMON_FLAGS
|
||||||
|
--cpu cortex-m33+nodsp
|
||||||
|
--fpu VFPv5-SP
|
||||||
|
)
|
||||||
|
set(FREERTOS_PORT IAR_ARM_CM33_NTZ_NONSECURE CACHE INTERNAL "")
|
||||||
|
|
||||||
|
endif ()
|
@ -109,6 +109,10 @@ 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))))))))))))))))))))))))))))
|
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)
|
CFLAGS += -DBOARD_$(BOARD_UPPER)
|
||||||
|
|
||||||
|
ifdef CFLAGS_CLI
|
||||||
|
CFLAGS += $(CFLAGS_CLI)
|
||||||
|
endif
|
||||||
|
|
||||||
# use max3421 as host controller
|
# use max3421 as host controller
|
||||||
ifeq (${MAX3421_HOST},1)
|
ifeq (${MAX3421_HOST},1)
|
||||||
SRC_C += src/portable/analog/max3421/hcd_max3421.c
|
SRC_C += src/portable/analog/max3421/hcd_max3421.c
|
||||||
|
@ -145,6 +145,12 @@ OPENOCD_WCH_OPTION ?=
|
|||||||
flash-openocd-wch: $(BUILD)/$(PROJECT).elf
|
flash-openocd-wch: $(BUILD)/$(PROJECT).elf
|
||||||
$(OPENOCD_WCH) $(OPENOCD_WCH_OPTION) -c init -c halt -c "flash write_image $<" -c reset -c exit
|
$(OPENOCD_WCH) $(OPENOCD_WCH_OPTION) -c init -c halt -c "flash write_image $<" -c reset -c exit
|
||||||
|
|
||||||
|
# --------------- wlink-rs -----------------
|
||||||
|
# flash with https://github.com/ch32-rs/wlink
|
||||||
|
WLINK_RS ?= wlink
|
||||||
|
flash-wlink-rs: $(BUILD)/$(PROJECT).elf
|
||||||
|
$(WLINK_RS) flash $<
|
||||||
|
|
||||||
# --------------- dfu-util -----------------
|
# --------------- dfu-util -----------------
|
||||||
DFU_UTIL_OPTION ?= -a 0
|
DFU_UTIL_OPTION ?= -a 0
|
||||||
flash-dfu-util: $(BUILD)/$(PROJECT).bin
|
flash-dfu-util: $(BUILD)/$(PROJECT).bin
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
mcu:CH32V103
|
||||||
mcu:CH32V20X
|
mcu:CH32V20X
|
||||||
mcu:CH32V307
|
mcu:CH32V307
|
||||||
mcu:CXD56
|
mcu:CXD56
|
||||||
|
@ -67,6 +67,7 @@
|
|||||||
#define configENABLE_FPU 1
|
#define configENABLE_FPU 1
|
||||||
#define configENABLE_TRUSTZONE 0
|
#define configENABLE_TRUSTZONE 0
|
||||||
#define configMINIMAL_SECURE_STACK_SIZE ( 1024 )
|
#define configMINIMAL_SECURE_STACK_SIZE ( 1024 )
|
||||||
|
#define configRUN_FREERTOS_SECURE_ONLY 1
|
||||||
|
|
||||||
#define configUSE_PREEMPTION 1
|
#define configUSE_PREEMPTION 1
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
mcu:CH32V103
|
||||||
mcu:CH32V20X
|
mcu:CH32V20X
|
||||||
mcu:CH32V307
|
mcu:CH32V307
|
||||||
mcu:CXD56
|
mcu:CXD56
|
||||||
|
@ -67,6 +67,7 @@
|
|||||||
#define configENABLE_FPU 1
|
#define configENABLE_FPU 1
|
||||||
#define configENABLE_TRUSTZONE 0
|
#define configENABLE_TRUSTZONE 0
|
||||||
#define configMINIMAL_SECURE_STACK_SIZE ( 1024 )
|
#define configMINIMAL_SECURE_STACK_SIZE ( 1024 )
|
||||||
|
#define configRUN_FREERTOS_SECURE_ONLY 1
|
||||||
|
|
||||||
#define configUSE_PREEMPTION 1
|
#define configUSE_PREEMPTION 1
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||||
|
@ -119,6 +119,26 @@ static void cdc_task(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Invoked when cdc when line state changed e.g connected/disconnected
|
||||||
|
// Use to reset to DFU when disconnect with 1200 bps
|
||||||
|
void tud_cdc_line_state_cb(uint8_t instance, bool dtr, bool rts) {
|
||||||
|
(void)rts;
|
||||||
|
|
||||||
|
// DTR = false is counted as disconnected
|
||||||
|
if (!dtr) {
|
||||||
|
// touch1200 only with first CDC instance (Serial)
|
||||||
|
if (instance == 0) {
|
||||||
|
cdc_line_coding_t coding;
|
||||||
|
tud_cdc_get_line_coding(&coding);
|
||||||
|
if (coding.bit_rate == 1200) {
|
||||||
|
if (board_reset_to_bootloader) {
|
||||||
|
board_reset_to_bootloader();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// BLINKING TASK
|
// BLINKING TASK
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
mcu:SAMD11
|
mcu:SAMD11
|
||||||
family:espressif
|
family:espressif
|
||||||
|
board:ch32v203g_r0_1v0
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
mcu:CH32V103
|
||||||
mcu:CH32V20X
|
mcu:CH32V20X
|
||||||
mcu:CH32V307
|
mcu:CH32V307
|
||||||
mcu:CXD56
|
mcu:CXD56
|
||||||
|
@ -67,6 +67,7 @@
|
|||||||
#define configENABLE_FPU 1
|
#define configENABLE_FPU 1
|
||||||
#define configENABLE_TRUSTZONE 0
|
#define configENABLE_TRUSTZONE 0
|
||||||
#define configMINIMAL_SECURE_STACK_SIZE ( 1024 )
|
#define configMINIMAL_SECURE_STACK_SIZE ( 1024 )
|
||||||
|
#define configRUN_FREERTOS_SECURE_ONLY 1
|
||||||
|
|
||||||
#define configUSE_PREEMPTION 1
|
#define configUSE_PREEMPTION 1
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||||
|
@ -28,6 +28,9 @@
|
|||||||
|
|
||||||
#if CFG_TUD_MSC
|
#if CFG_TUD_MSC
|
||||||
|
|
||||||
|
// whether host does safe-eject
|
||||||
|
static bool ejected = false;
|
||||||
|
|
||||||
// Some MCU doesn't have enough 8KB SRAM to store the whole disk
|
// Some MCU doesn't have enough 8KB SRAM to store the whole disk
|
||||||
// We will use Flash as read-only disk with board that has
|
// We will use Flash as read-only disk with board that has
|
||||||
// CFG_EXAMPLE_MSC_READONLY defined
|
// CFG_EXAMPLE_MSC_READONLY defined
|
||||||
@ -137,7 +140,14 @@ bool tud_msc_test_unit_ready_cb(uint8_t lun)
|
|||||||
{
|
{
|
||||||
(void) lun;
|
(void) lun;
|
||||||
|
|
||||||
return true; // RAM disk is always ready
|
// RAM disk is ready until ejected
|
||||||
|
if (ejected) {
|
||||||
|
// Additional Sense 3A-00 is NOT_FOUND
|
||||||
|
tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3a, 0x00);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size
|
// Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size
|
||||||
@ -166,6 +176,7 @@ bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, boo
|
|||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
// unload disk storage
|
// unload disk storage
|
||||||
|
ejected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,6 +198,17 @@ int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buff
|
|||||||
return (int32_t) bufsize;
|
return (int32_t) bufsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool tud_msc_is_writable_cb (uint8_t lun)
|
||||||
|
{
|
||||||
|
(void) lun;
|
||||||
|
|
||||||
|
#ifdef CFG_EXAMPLE_MSC_READONLY
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// Callback invoked when received WRITE10 command.
|
// Callback invoked when received WRITE10 command.
|
||||||
// Process data in buffer to disk's storage and return number of written bytes
|
// Process data in buffer to disk's storage and return number of written bytes
|
||||||
int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize)
|
int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize)
|
||||||
|
@ -141,7 +141,7 @@ static bool tud_audio_feature_unit_get_request(uint8_t rhport, audio_control_req
|
|||||||
TU_LOG1("Get channel %u mute %d\r\n", request->bChannelNumber, mute1.bCur);
|
TU_LOG1("Get channel %u mute %d\r\n", request->bChannelNumber, mute1.bCur);
|
||||||
return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &mute1, sizeof(mute1));
|
return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &mute1, sizeof(mute1));
|
||||||
}
|
}
|
||||||
else if (UAC2_ENTITY_SPK_FEATURE_UNIT && request->bControlSelector == AUDIO_FU_CTRL_VOLUME)
|
else if (request->bControlSelector == AUDIO_FU_CTRL_VOLUME)
|
||||||
{
|
{
|
||||||
if (request->bRequest == AUDIO_CS_REQ_RANGE)
|
if (request->bRequest == AUDIO_CS_REQ_RANGE)
|
||||||
{
|
{
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
mcu:SAMD11
|
mcu:SAMD11
|
||||||
family:espressif
|
family:espressif
|
||||||
|
board:ch32v203g_r0_1v0
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
mcu:CH32V103
|
||||||
mcu:CH32V20X
|
mcu:CH32V20X
|
||||||
mcu:CH32V307
|
mcu:CH32V307
|
||||||
mcu:CXD56
|
mcu:CXD56
|
||||||
|
@ -67,6 +67,7 @@
|
|||||||
#define configENABLE_FPU 1
|
#define configENABLE_FPU 1
|
||||||
#define configENABLE_TRUSTZONE 0
|
#define configENABLE_TRUSTZONE 0
|
||||||
#define configMINIMAL_SECURE_STACK_SIZE ( 1024 )
|
#define configMINIMAL_SECURE_STACK_SIZE ( 1024 )
|
||||||
|
#define configRUN_FREERTOS_SECURE_ONLY 1
|
||||||
|
|
||||||
#define configUSE_PREEMPTION 1
|
#define configUSE_PREEMPTION 1
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||||
|
@ -5,7 +5,14 @@ include(${CMAKE_CURRENT_LIST_DIR}/../../../hw/bsp/family_support.cmake)
|
|||||||
# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
|
# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
|
||||||
family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
|
family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
|
||||||
|
|
||||||
|
# Prefer the tinyusb lwip
|
||||||
set(LWIP ${TOP}/lib/lwip)
|
set(LWIP ${TOP}/lib/lwip)
|
||||||
|
|
||||||
|
# If we can't find one from tinyusb then check cmake var before giving up
|
||||||
|
if (NOT EXISTS ${LWIP}/src)
|
||||||
|
set(LWIP ${TINYUSB_LWIP_PATH})
|
||||||
|
endif()
|
||||||
|
|
||||||
if (NOT EXISTS ${LWIP}/src)
|
if (NOT EXISTS ${LWIP}/src)
|
||||||
family_example_missing_dependency(${PROJECT} "lib/lwip")
|
family_example_missing_dependency(${PROJECT} "lib/lwip")
|
||||||
return()
|
return()
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
mcu:CH32V103
|
||||||
mcu:CH32V20X
|
mcu:CH32V20X
|
||||||
mcu:LPC11UXX
|
mcu:LPC11UXX
|
||||||
mcu:LPC13XX
|
mcu:LPC13XX
|
||||||
|
@ -229,7 +229,7 @@ static bool tud_audio_feature_unit_get_request(uint8_t rhport, audio_control_req
|
|||||||
TU_LOG1("Get channel %u mute %d\r\n", request->bChannelNumber, mute1.bCur);
|
TU_LOG1("Get channel %u mute %d\r\n", request->bChannelNumber, mute1.bCur);
|
||||||
return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &mute1, sizeof(mute1));
|
return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &mute1, sizeof(mute1));
|
||||||
}
|
}
|
||||||
else if (UAC2_ENTITY_SPK_FEATURE_UNIT && request->bControlSelector == AUDIO_FU_CTRL_VOLUME)
|
else if (request->bControlSelector == AUDIO_FU_CTRL_VOLUME)
|
||||||
{
|
{
|
||||||
if (request->bRequest == AUDIO_CS_REQ_RANGE)
|
if (request->bRequest == AUDIO_CS_REQ_RANGE)
|
||||||
{
|
{
|
||||||
|
33
examples/device/uac2_speaker_fb/CMakeLists.txt
Normal file
33
examples/device/uac2_speaker_fb/CMakeLists.txt
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.17)
|
||||||
|
|
||||||
|
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
|
||||||
|
|
||||||
|
# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
|
||||||
|
family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
|
||||||
|
|
||||||
|
project(${PROJECT} 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/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)
|
11
examples/device/uac2_speaker_fb/Makefile
Normal file
11
examples/device/uac2_speaker_fb/Makefile
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
include ../../build_system/make/make.mk
|
||||||
|
|
||||||
|
INC += \
|
||||||
|
src \
|
||||||
|
$(TOP)/hw \
|
||||||
|
|
||||||
|
# Example source
|
||||||
|
EXAMPLE_SOURCE += $(wildcard src/*.c)
|
||||||
|
SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE))
|
||||||
|
|
||||||
|
include ../../build_system/make/rules.mk
|
8
examples/device/uac2_speaker_fb/skip.txt
Normal file
8
examples/device/uac2_speaker_fb/skip.txt
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
mcu:LPC11UXX
|
||||||
|
mcu:LPC13XX
|
||||||
|
mcu:NUC121
|
||||||
|
mcu:SAMD11
|
||||||
|
mcu:SAME5X
|
||||||
|
mcu:SAMG
|
||||||
|
board:stm32l052dap52
|
||||||
|
family:broadcom_64bit
|
69
examples/device/uac2_speaker_fb/src/audio_debug.py
Normal file
69
examples/device/uac2_speaker_fb/src/audio_debug.py
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
# Install python3 HID package https://pypi.org/project/hid/
|
||||||
|
# Install python3 matplotlib package https://pypi.org/project/matplotlib/
|
||||||
|
|
||||||
|
from ctypes import *
|
||||||
|
try:
|
||||||
|
import hid
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import matplotlib.animation as animation
|
||||||
|
except:
|
||||||
|
print("Missing import, please try 'pip install hid matplotlib' or consult your OS's python package manager.")
|
||||||
|
|
||||||
|
# Example must be compiled with CFG_AUDIO_DEBUG=1
|
||||||
|
VID = 0xcafe
|
||||||
|
PID = 0x4014
|
||||||
|
|
||||||
|
CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX = 2
|
||||||
|
|
||||||
|
class audio_debug_info_t (Structure):
|
||||||
|
_fields_ = [("sample_rate", c_uint32),
|
||||||
|
("alt_settings", c_uint8),
|
||||||
|
("mute", (CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1) * c_int8),
|
||||||
|
("volume", (CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1) * c_int16),
|
||||||
|
("fifo_size", c_uint16),
|
||||||
|
("fifo_count", c_uint16),
|
||||||
|
("fifo_count_avg", c_uint16)
|
||||||
|
]
|
||||||
|
|
||||||
|
dev = hid.Device(VID, PID)
|
||||||
|
|
||||||
|
if dev:
|
||||||
|
# Create figure for plotting
|
||||||
|
fig = plt.figure()
|
||||||
|
ax = fig.add_subplot(1, 1, 1)
|
||||||
|
fifo_avg = []
|
||||||
|
fifo_cnt = []
|
||||||
|
# This function is called periodically from FuncAnimation
|
||||||
|
def animate(i):
|
||||||
|
info = None
|
||||||
|
for i in range(30):
|
||||||
|
try:
|
||||||
|
str_in = dev.read(64, 50)
|
||||||
|
info = audio_debug_info_t.from_buffer_copy(str_in)
|
||||||
|
|
||||||
|
global fifo_avg
|
||||||
|
global fifo_cnt
|
||||||
|
fifo_avg.append(info.fifo_count_avg)
|
||||||
|
fifo_cnt.append(info.fifo_count)
|
||||||
|
except:
|
||||||
|
exit(1)
|
||||||
|
# Limit to 1000 items
|
||||||
|
fifo_avg = fifo_avg[-1000:]
|
||||||
|
fifo_cnt = fifo_cnt[-1000:]
|
||||||
|
|
||||||
|
if info is not None:
|
||||||
|
# Draw x and y lists
|
||||||
|
ax.clear()
|
||||||
|
ax.plot(fifo_cnt, label='FIFO count')
|
||||||
|
ax.plot(fifo_avg, label='FIFO average')
|
||||||
|
ax.legend()
|
||||||
|
ax.set_ylim(bottom=0, top=info.fifo_size)
|
||||||
|
|
||||||
|
# Format plot
|
||||||
|
plt.title('FIFO information')
|
||||||
|
plt.grid()
|
||||||
|
|
||||||
|
print(f'Sample rate:{info.sample_rate} | Alt settings:{info.alt_settings} | Volume:{info.volume[:]}')
|
||||||
|
|
||||||
|
ani = animation.FuncAnimation(fig, animate, interval=10)
|
||||||
|
plt.show()
|
52
examples/device/uac2_speaker_fb/src/common_types.h
Normal file
52
examples/device/uac2_speaker_fb/src/common_types.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _COMMON_TYPES_H_
|
||||||
|
#define _COMMON_TYPES_H_
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
ITF_NUM_AUDIO_CONTROL = 0,
|
||||||
|
ITF_NUM_AUDIO_STREAMING,
|
||||||
|
#if CFG_AUDIO_DEBUG
|
||||||
|
ITF_NUM_DEBUG,
|
||||||
|
#endif
|
||||||
|
ITF_NUM_TOTAL
|
||||||
|
};
|
||||||
|
|
||||||
|
#if CFG_AUDIO_DEBUG
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t sample_rate;
|
||||||
|
uint8_t alt_settings;
|
||||||
|
int8_t mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1];
|
||||||
|
int16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1];
|
||||||
|
uint16_t fifo_size;
|
||||||
|
uint16_t fifo_count;
|
||||||
|
uint16_t fifo_count_avg;
|
||||||
|
} audio_debug_info_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
505
examples/device/uac2_speaker_fb/src/main.c
Normal file
505
examples/device/uac2_speaker_fb/src/main.c
Normal file
@ -0,0 +1,505 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Jerzy Kasenberg
|
||||||
|
*
|
||||||
|
* 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 <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "bsp/board_api.h"
|
||||||
|
#include "tusb.h"
|
||||||
|
#include "usb_descriptors.h"
|
||||||
|
#include "common_types.h"
|
||||||
|
|
||||||
|
#ifdef CFG_QUIRK_OS_GUESSING
|
||||||
|
#include "quirk_os_guessing.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// MACRO CONSTANT TYPEDEF PROTOTYPES
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
uint32_t current_sample_rate = 44100;
|
||||||
|
|
||||||
|
#define N_SAMPLE_RATES TU_ARRAY_SIZE(sample_rates)
|
||||||
|
|
||||||
|
/* Blink pattern
|
||||||
|
* - 25 ms : streaming data
|
||||||
|
* - 250 ms : device not mounted
|
||||||
|
* - 1000 ms : device mounted
|
||||||
|
* - 2500 ms : device is suspended
|
||||||
|
*/
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
BLINK_STREAMING = 25,
|
||||||
|
BLINK_NOT_MOUNTED = 250,
|
||||||
|
BLINK_MOUNTED = 1000,
|
||||||
|
BLINK_SUSPENDED = 2500,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
VOLUME_CTRL_0_DB = 0,
|
||||||
|
VOLUME_CTRL_10_DB = 2560,
|
||||||
|
VOLUME_CTRL_20_DB = 5120,
|
||||||
|
VOLUME_CTRL_30_DB = 7680,
|
||||||
|
VOLUME_CTRL_40_DB = 10240,
|
||||||
|
VOLUME_CTRL_50_DB = 12800,
|
||||||
|
VOLUME_CTRL_60_DB = 15360,
|
||||||
|
VOLUME_CTRL_70_DB = 17920,
|
||||||
|
VOLUME_CTRL_80_DB = 20480,
|
||||||
|
VOLUME_CTRL_90_DB = 23040,
|
||||||
|
VOLUME_CTRL_100_DB = 25600,
|
||||||
|
VOLUME_CTRL_SILENCE = 0x8000,
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
|
||||||
|
|
||||||
|
// Audio controls
|
||||||
|
// Current states
|
||||||
|
int8_t mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1]; // +1 for master channel 0
|
||||||
|
int16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1]; // +1 for master channel 0
|
||||||
|
|
||||||
|
// Buffer for speaker data
|
||||||
|
uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ/2];
|
||||||
|
|
||||||
|
void led_blinking_task(void);
|
||||||
|
void audio_task(void);
|
||||||
|
|
||||||
|
#if CFG_AUDIO_DEBUG
|
||||||
|
void audio_debug_task(void);
|
||||||
|
uint8_t current_alt_settings;
|
||||||
|
uint16_t fifo_count;
|
||||||
|
uint32_t fifo_count_avg;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*------------- MAIN -------------*/
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
board_init();
|
||||||
|
|
||||||
|
// init device stack on configured roothub port
|
||||||
|
tud_init(BOARD_TUD_RHPORT);
|
||||||
|
|
||||||
|
if (board_init_after_tusb) {
|
||||||
|
board_init_after_tusb();
|
||||||
|
}
|
||||||
|
|
||||||
|
TU_LOG1("Speaker running\r\n");
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
tud_task(); // TinyUSB device task
|
||||||
|
led_blinking_task();
|
||||||
|
#if CFG_AUDIO_DEBUG
|
||||||
|
audio_debug_task();
|
||||||
|
#endif
|
||||||
|
audio_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Application Callback API Implementations
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// Helper for clock get requests
|
||||||
|
static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t const *request)
|
||||||
|
{
|
||||||
|
TU_ASSERT(request->bEntityID == UAC2_ENTITY_CLOCK);
|
||||||
|
|
||||||
|
if (request->bControlSelector == AUDIO_CS_CTRL_SAM_FREQ)
|
||||||
|
{
|
||||||
|
if (request->bRequest == AUDIO_CS_REQ_CUR)
|
||||||
|
{
|
||||||
|
TU_LOG1("Clock get current freq %lu\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));
|
||||||
|
}
|
||||||
|
else if (request->bRequest == AUDIO_CS_REQ_RANGE)
|
||||||
|
{
|
||||||
|
audio_control_range_4_n_t(N_SAMPLE_RATES) rangef =
|
||||||
|
{
|
||||||
|
.wNumSubRanges = tu_htole16(N_SAMPLE_RATES)
|
||||||
|
};
|
||||||
|
TU_LOG1("Clock get %d freq ranges\r\n", N_SAMPLE_RATES);
|
||||||
|
for(uint8_t i = 0; i < N_SAMPLE_RATES; i++)
|
||||||
|
{
|
||||||
|
rangef.subrange[i].bMin = (int32_t) sample_rates[i];
|
||||||
|
rangef.subrange[i].bMax = (int32_t) sample_rates[i];
|
||||||
|
rangef.subrange[i].bRes = 0;
|
||||||
|
TU_LOG1("Range %d (%d, %d, %d)\r\n", i, (int)rangef.subrange[i].bMin, (int)rangef.subrange[i].bMax, (int)rangef.subrange[i].bRes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &rangef, sizeof(rangef));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (request->bControlSelector == AUDIO_CS_CTRL_CLK_VALID &&
|
||||||
|
request->bRequest == AUDIO_CS_REQ_CUR)
|
||||||
|
{
|
||||||
|
audio_control_cur_1_t cur_valid = { .bCur = 1 };
|
||||||
|
TU_LOG1("Clock get is valid %u\r\n", cur_valid.bCur);
|
||||||
|
return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &cur_valid, sizeof(cur_valid));
|
||||||
|
}
|
||||||
|
TU_LOG1("Clock get request not supported, entity = %u, selector = %u, request = %u\r\n",
|
||||||
|
request->bEntityID, request->bControlSelector, request->bRequest);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper for clock set requests
|
||||||
|
static bool tud_audio_clock_set_request(uint8_t rhport, audio_control_request_t const *request, uint8_t const *buf)
|
||||||
|
{
|
||||||
|
(void)rhport;
|
||||||
|
|
||||||
|
TU_ASSERT(request->bEntityID == UAC2_ENTITY_CLOCK);
|
||||||
|
TU_VERIFY(request->bRequest == AUDIO_CS_REQ_CUR);
|
||||||
|
|
||||||
|
if (request->bControlSelector == AUDIO_CS_CTRL_SAM_FREQ)
|
||||||
|
{
|
||||||
|
TU_VERIFY(request->wLength == sizeof(audio_control_cur_4_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);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TU_LOG1("Clock set request not supported, entity = %u, selector = %u, request = %u\r\n",
|
||||||
|
request->bEntityID, request->bControlSelector, request->bRequest);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper for feature unit get requests
|
||||||
|
static bool tud_audio_feature_unit_get_request(uint8_t rhport, audio_control_request_t const *request)
|
||||||
|
{
|
||||||
|
TU_ASSERT(request->bEntityID == UAC2_ENTITY_FEATURE_UNIT);
|
||||||
|
|
||||||
|
if (request->bControlSelector == AUDIO_FU_CTRL_MUTE && request->bRequest == AUDIO_CS_REQ_CUR)
|
||||||
|
{
|
||||||
|
audio_control_cur_1_t mute1 = { .bCur = mute[request->bChannelNumber] };
|
||||||
|
TU_LOG1("Get channel %u mute %d\r\n", request->bChannelNumber, mute1.bCur);
|
||||||
|
return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &mute1, sizeof(mute1));
|
||||||
|
}
|
||||||
|
else if (request->bControlSelector == AUDIO_FU_CTRL_VOLUME)
|
||||||
|
{
|
||||||
|
if (request->bRequest == AUDIO_CS_REQ_RANGE)
|
||||||
|
{
|
||||||
|
audio_control_range_2_n_t(1) range_vol = {
|
||||||
|
.wNumSubRanges = tu_htole16(1),
|
||||||
|
.subrange[0] = { .bMin = tu_htole16(-VOLUME_CTRL_50_DB), tu_htole16(VOLUME_CTRL_0_DB), tu_htole16(256) }
|
||||||
|
};
|
||||||
|
TU_LOG1("Get channel %u volume range (%d, %d, %u) dB\r\n", request->bChannelNumber,
|
||||||
|
range_vol.subrange[0].bMin / 256, range_vol.subrange[0].bMax / 256, range_vol.subrange[0].bRes / 256);
|
||||||
|
return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &range_vol, sizeof(range_vol));
|
||||||
|
}
|
||||||
|
else if (request->bRequest == AUDIO_CS_REQ_CUR)
|
||||||
|
{
|
||||||
|
audio_control_cur_2_t cur_vol = { .bCur = tu_htole16(volume[request->bChannelNumber]) };
|
||||||
|
TU_LOG1("Get channel %u volume %d dB\r\n", request->bChannelNumber, cur_vol.bCur / 256);
|
||||||
|
return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &cur_vol, sizeof(cur_vol));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TU_LOG1("Feature unit get request not supported, entity = %u, selector = %u, request = %u\r\n",
|
||||||
|
request->bEntityID, request->bControlSelector, request->bRequest);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper for feature unit set requests
|
||||||
|
static bool tud_audio_feature_unit_set_request(uint8_t rhport, audio_control_request_t const *request, uint8_t const *buf)
|
||||||
|
{
|
||||||
|
(void)rhport;
|
||||||
|
|
||||||
|
TU_ASSERT(request->bEntityID == UAC2_ENTITY_FEATURE_UNIT);
|
||||||
|
TU_VERIFY(request->bRequest == AUDIO_CS_REQ_CUR);
|
||||||
|
|
||||||
|
if (request->bControlSelector == AUDIO_FU_CTRL_MUTE)
|
||||||
|
{
|
||||||
|
TU_VERIFY(request->wLength == sizeof(audio_control_cur_1_t));
|
||||||
|
|
||||||
|
mute[request->bChannelNumber] = ((audio_control_cur_1_t const *)buf)->bCur;
|
||||||
|
|
||||||
|
TU_LOG1("Set channel %d Mute: %d\r\n", request->bChannelNumber, mute[request->bChannelNumber]);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (request->bControlSelector == AUDIO_FU_CTRL_VOLUME)
|
||||||
|
{
|
||||||
|
TU_VERIFY(request->wLength == sizeof(audio_control_cur_2_t));
|
||||||
|
|
||||||
|
volume[request->bChannelNumber] = ((audio_control_cur_2_t const *)buf)->bCur;
|
||||||
|
|
||||||
|
TU_LOG1("Set channel %d volume: %d dB\r\n", request->bChannelNumber, volume[request->bChannelNumber] / 256);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TU_LOG1("Feature unit set request not supported, entity = %u, selector = %u, request = %u\r\n",
|
||||||
|
request->bEntityID, request->bControlSelector, request->bRequest);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
audio_control_request_t const *request = (audio_control_request_t const *)p_request;
|
||||||
|
|
||||||
|
if (request->bEntityID == UAC2_ENTITY_CLOCK)
|
||||||
|
return tud_audio_clock_get_request(rhport, request);
|
||||||
|
if (request->bEntityID == UAC2_ENTITY_FEATURE_UNIT)
|
||||||
|
return tud_audio_feature_unit_get_request(rhport, request);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TU_LOG1("Get request not handled, entity = %d, selector = %d, request = %d\r\n",
|
||||||
|
request->bEntityID, request->bControlSelector, request->bRequest);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 *buf)
|
||||||
|
{
|
||||||
|
audio_control_request_t const *request = (audio_control_request_t const *)p_request;
|
||||||
|
|
||||||
|
if (request->bEntityID == UAC2_ENTITY_FEATURE_UNIT)
|
||||||
|
return tud_audio_feature_unit_set_request(rhport, request, buf);
|
||||||
|
if (request->bEntityID == UAC2_ENTITY_CLOCK)
|
||||||
|
return tud_audio_clock_set_request(rhport, request, buf);
|
||||||
|
TU_LOG1("Set request not handled, entity = %d, selector = %d, request = %d\r\n",
|
||||||
|
request->bEntityID, request->bControlSelector, request->bRequest);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const * p_request)
|
||||||
|
{
|
||||||
|
(void)rhport;
|
||||||
|
|
||||||
|
uint8_t const itf = tu_u16_low(tu_le16toh(p_request->wIndex));
|
||||||
|
uint8_t const alt = tu_u16_low(tu_le16toh(p_request->wValue));
|
||||||
|
|
||||||
|
if (ITF_NUM_AUDIO_STREAMING == itf && alt == 0)
|
||||||
|
blink_interval_ms = BLINK_MOUNTED;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request)
|
||||||
|
{
|
||||||
|
(void)rhport;
|
||||||
|
uint8_t const itf = tu_u16_low(tu_le16toh(p_request->wIndex));
|
||||||
|
uint8_t const alt = tu_u16_low(tu_le16toh(p_request->wValue));
|
||||||
|
|
||||||
|
TU_LOG2("Set interface %d alt %d\r\n", itf, alt);
|
||||||
|
if (ITF_NUM_AUDIO_STREAMING == itf && alt != 0)
|
||||||
|
blink_interval_ms = BLINK_STREAMING;
|
||||||
|
|
||||||
|
#if CFG_AUDIO_DEBUG
|
||||||
|
current_alt_settings = alt;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedback_params_t* feedback_param)
|
||||||
|
{
|
||||||
|
(void)func_id;
|
||||||
|
(void)alt_itf;
|
||||||
|
// Set feedback method to fifo counting
|
||||||
|
feedback_param->method = AUDIO_FEEDBACK_METHOD_FIFO_COUNT;
|
||||||
|
feedback_param->sample_freq = current_sample_rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CFG_AUDIO_DEBUG
|
||||||
|
bool tud_audio_rx_done_post_read_cb(uint8_t rhport, uint16_t n_bytes_received, uint8_t func_id, uint8_t ep_out, uint8_t cur_alt_setting)
|
||||||
|
{
|
||||||
|
(void)rhport;
|
||||||
|
(void)n_bytes_received;
|
||||||
|
(void)func_id;
|
||||||
|
(void)ep_out;
|
||||||
|
(void)cur_alt_setting;
|
||||||
|
|
||||||
|
fifo_count = tud_audio_available();
|
||||||
|
// Same averaging method used in UAC2 class
|
||||||
|
fifo_count_avg = (uint32_t)(((uint64_t)fifo_count_avg * 63 + ((uint32_t)fifo_count << 16)) >> 6);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CFG_QUIRK_OS_GUESSING
|
||||||
|
bool tud_audio_feedback_format_correction_cb(uint8_t func_id)
|
||||||
|
{
|
||||||
|
(void)func_id;
|
||||||
|
if(tud_speed_get() == TUSB_SPEED_FULL && quirk_os_guessing_get() == QUIRK_OS_GUESSING_OSX) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// AUDIO Task
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
void audio_task(void)
|
||||||
|
{
|
||||||
|
// Replace audio_task() with your I2S transmit callback.
|
||||||
|
// Here we simulate a callback called 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;
|
||||||
|
|
||||||
|
uint16_t length = current_sample_rate/1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX;
|
||||||
|
|
||||||
|
if (current_sample_rate == 44100 && (curr_ms % 10 == 0))
|
||||||
|
{
|
||||||
|
// Take one more sample every 10 cycles, to have a average reading speed of 44.1
|
||||||
|
// This correction is not needed in real world cases
|
||||||
|
length += CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX;
|
||||||
|
} else
|
||||||
|
if (current_sample_rate == 88200 && (curr_ms % 5 == 0))
|
||||||
|
{
|
||||||
|
// Take one more sample every 5 cycles, to have a average reading speed of 88.2
|
||||||
|
// This correction is not needed in real world cases
|
||||||
|
length += CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX;
|
||||||
|
}
|
||||||
|
|
||||||
|
tud_audio_read(i2s_dummy_buffer, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// BLINKING TASK
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
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;
|
||||||
|
start_ms += blink_interval_ms;
|
||||||
|
|
||||||
|
board_led_write(led_state);
|
||||||
|
led_state = 1 - led_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CFG_AUDIO_DEBUG
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// HID interface for audio debug
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Every 1ms, we will sent 1 debug information report
|
||||||
|
void audio_debug_task(void)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
audio_debug_info_t debug_info;
|
||||||
|
debug_info.sample_rate = current_sample_rate;
|
||||||
|
debug_info.alt_settings = current_alt_settings;
|
||||||
|
debug_info.fifo_size = CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ;
|
||||||
|
debug_info.fifo_count = fifo_count;
|
||||||
|
debug_info.fifo_count_avg = fifo_count_avg >> 16;
|
||||||
|
for (int i = 0; i < CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1; i++)
|
||||||
|
{
|
||||||
|
debug_info.mute[i] = mute[i];
|
||||||
|
debug_info.volume[i] = volume[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tud_hid_ready())
|
||||||
|
tud_hid_report(0, &debug_info, sizeof(debug_info));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when received GET_REPORT control request
|
||||||
|
// Unused here
|
||||||
|
uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen)
|
||||||
|
{
|
||||||
|
// TODO not Implemented
|
||||||
|
(void) itf;
|
||||||
|
(void) report_id;
|
||||||
|
(void) report_type;
|
||||||
|
(void) buffer;
|
||||||
|
(void) reqlen;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when received SET_REPORT control request or
|
||||||
|
// Unused here
|
||||||
|
void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize)
|
||||||
|
{
|
||||||
|
// This example doesn't use multiple report and report ID
|
||||||
|
(void) itf;
|
||||||
|
(void) report_id;
|
||||||
|
(void) report_type;
|
||||||
|
(void) buffer;
|
||||||
|
(void) bufsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
90
examples/device/uac2_speaker_fb/src/quirk_os_guessing.c
Normal file
90
examples/device/uac2_speaker_fb/src/quirk_os_guessing.c
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2024 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "quirk_os_guessing.h"
|
||||||
|
|
||||||
|
static tusb_desc_type_t desc_req_buf[2];
|
||||||
|
static int desc_req_idx = 0;
|
||||||
|
|
||||||
|
// Place at the start of tud_descriptor_device_cb()
|
||||||
|
void quirk_os_guessing_desc_device_cb() {
|
||||||
|
desc_req_idx = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Place at the start of tud_descriptor_configuration_cb()
|
||||||
|
void quirk_os_guessing_desc_configuration_cb() {
|
||||||
|
// Skip redundant request
|
||||||
|
if (desc_req_idx == 0 || (desc_req_idx == 1 && desc_req_buf[0] != TUSB_DESC_CONFIGURATION)) {
|
||||||
|
desc_req_buf[desc_req_idx++] = TUSB_DESC_CONFIGURATION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Place at the start of tud_descriptor_bos_cb()
|
||||||
|
void quirk_os_guessing_desc_bos_cb() {
|
||||||
|
// Skip redundant request
|
||||||
|
if (desc_req_idx == 0 || (desc_req_idx == 1 && desc_req_buf[0] != TUSB_DESC_BOS)) {
|
||||||
|
desc_req_buf[desc_req_idx++] = TUSB_DESC_BOS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Place at the start of tud_descriptor_string_cb()
|
||||||
|
void quirk_os_guessing_desc_string_cb() {
|
||||||
|
// Skip redundant request
|
||||||
|
if (desc_req_idx == 0 || (desc_req_idx == 1 && desc_req_buf[0] != TUSB_DESC_STRING)) {
|
||||||
|
desc_req_buf[desc_req_idx++] = TUSB_DESC_STRING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Each OS request descriptors differently:
|
||||||
|
// Windows 10 - 11
|
||||||
|
// Device Desc
|
||||||
|
// Config Desc
|
||||||
|
// BOS Desc
|
||||||
|
// String Desc
|
||||||
|
// Linux 3.16 - 6.8
|
||||||
|
// Device Desc
|
||||||
|
// BOS Desc
|
||||||
|
// Config Desc
|
||||||
|
// String Desc
|
||||||
|
// OS X Ventura - Sonoma
|
||||||
|
// Device Desc
|
||||||
|
// String Desc
|
||||||
|
// Config Desc || BOS Desc
|
||||||
|
// BOS Desc || Config Desc
|
||||||
|
quirk_os_guessing_t quirk_os_guessing_get(void) {
|
||||||
|
if (desc_req_idx < 2) {
|
||||||
|
return QUIRK_OS_GUESSING_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desc_req_buf[0] == TUSB_DESC_BOS && desc_req_buf[1] == TUSB_DESC_CONFIGURATION) {
|
||||||
|
return QUIRK_OS_GUESSING_LINUX;
|
||||||
|
} else if (desc_req_buf[0] == TUSB_DESC_CONFIGURATION && desc_req_buf[1] == TUSB_DESC_BOS) {
|
||||||
|
return QUIRK_OS_GUESSING_WINDOWS;
|
||||||
|
} else if (desc_req_buf[0] == TUSB_DESC_STRING && (desc_req_buf[1] == TUSB_DESC_BOS || desc_req_buf[1] == TUSB_DESC_CONFIGURATION)) {
|
||||||
|
return QUIRK_OS_GUESSING_OSX;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QUIRK_OS_GUESSING_UNKNOWN;
|
||||||
|
}
|
75
examples/device/uac2_speaker_fb/src/quirk_os_guessing.h
Normal file
75
examples/device/uac2_speaker_fb/src/quirk_os_guessing.h
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2024 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _QUIRK_OS_GUESSING_H_
|
||||||
|
#define _QUIRK_OS_GUESSING_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "tusb.h"
|
||||||
|
|
||||||
|
//================================== !!! WARNING !!! ====================================
|
||||||
|
// This quirk operate out of USB specification in order to workaround specific issues.
|
||||||
|
// It may not work on your platform.
|
||||||
|
//=======================================================================================
|
||||||
|
//
|
||||||
|
// Prerequisites:
|
||||||
|
// - Set USB version to at least 2.01 in Device Descriptor
|
||||||
|
// - Has a valid BOS Descriptor, refer to webusb_serial example
|
||||||
|
//
|
||||||
|
// Attention:
|
||||||
|
// Windows detection result comes out after Configuration Descriptor request,
|
||||||
|
// meaning it will be too late to do descriptor adjustment. It's advised to make
|
||||||
|
// Windows as default configuration and adjust to other OS accordingly.
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
QUIRK_OS_GUESSING_UNKNOWN,
|
||||||
|
QUIRK_OS_GUESSING_LINUX,
|
||||||
|
QUIRK_OS_GUESSING_OSX,
|
||||||
|
QUIRK_OS_GUESSING_WINDOWS,
|
||||||
|
} quirk_os_guessing_t;
|
||||||
|
|
||||||
|
// Get Host OS type
|
||||||
|
quirk_os_guessing_t quirk_os_guessing_get(void);
|
||||||
|
|
||||||
|
// Place at the start of tud_descriptor_device_cb()
|
||||||
|
void quirk_os_guessing_desc_device_cb(void);
|
||||||
|
|
||||||
|
// Place at the start of tud_descriptor_configuration_cb()
|
||||||
|
void quirk_os_guessing_desc_configuration_cb(void);
|
||||||
|
|
||||||
|
// Place at the start of tud_descriptor_bos_cb()
|
||||||
|
void quirk_os_guessing_desc_bos_cb(void);
|
||||||
|
|
||||||
|
// Place at the start of tud_descriptor_string_cb()
|
||||||
|
void quirk_os_guessing_desc_string_cb(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _QUIRK_OS_GUESSING_H_ */
|
168
examples/device/uac2_speaker_fb/src/tusb_config.h
Normal file
168
examples/device/uac2_speaker_fb/src/tusb_config.h
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Ha Thach (tinyusb.org)
|
||||||
|
* Copyright (c) 2020 Jerzy Kasenberg
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
#include "usb_descriptors.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
|
||||||
|
#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
|
||||||
|
|
||||||
|
// It's recommended to disable debug unless for control requests debugging,
|
||||||
|
// as the extra time needed will impact data stream !
|
||||||
|
#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
|
||||||
|
|
||||||
|
/* (Needed for Full-Speed only)
|
||||||
|
* Enable host OS guessing to workaround UAC2 compatibility issues between Windows and OS X
|
||||||
|
* The default configuration only support Windows and Linux, enable this option for OS X
|
||||||
|
* support. Otherwise if you don't need Windows support you can make OS X's configuration as
|
||||||
|
* default.
|
||||||
|
*/
|
||||||
|
#define CFG_QUIRK_OS_GUESSING 1
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// DEVICE CONFIGURATION
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Expose audio class debug information via HID interface
|
||||||
|
#ifndef CFG_AUDIO_DEBUG
|
||||||
|
#define CFG_AUDIO_DEBUG 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CFG_TUD_ENDPOINT0_SIZE
|
||||||
|
#define CFG_TUD_ENDPOINT0_SIZE 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CFG_TUD_HID_EP_BUFSIZE 64
|
||||||
|
|
||||||
|
//------------- CLASS -------------//
|
||||||
|
#define CFG_TUD_AUDIO 1
|
||||||
|
|
||||||
|
#if CFG_AUDIO_DEBUG
|
||||||
|
#define CFG_TUD_HID 1
|
||||||
|
#else
|
||||||
|
#define CFG_TUD_HID 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CFG_TUD_CDC 0
|
||||||
|
#define CFG_TUD_MSC 0
|
||||||
|
#define CFG_TUD_MIDI 0
|
||||||
|
#define CFG_TUD_VENDOR 0
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// AUDIO CLASS DRIVER CONFIGURATION
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_SPEAKER_STEREO_FB_DESC_LEN
|
||||||
|
|
||||||
|
// Enable if Full-Speed on OSX, also set feedback EP size to 3
|
||||||
|
#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION 0
|
||||||
|
|
||||||
|
// Audio format type I specifications
|
||||||
|
#if defined(__RX__)
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE 48000
|
||||||
|
#else
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE 96000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX 2
|
||||||
|
|
||||||
|
// 16bit in 16bit slots
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX 2
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_RESOLUTION_RX 16
|
||||||
|
|
||||||
|
// 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_FUNC_1_EP_OUT_SZ_MAX TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX)
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX // Example read FIFO every 1ms, so it should be 8 times larger for HS device
|
||||||
|
|
||||||
|
// Enable feedback EP
|
||||||
|
#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP 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_N_AS_INT 1
|
||||||
|
|
||||||
|
// Size of control request buffer
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _TUSB_CONFIG_H_ */
|
295
examples/device/uac2_speaker_fb/src/usb_descriptors.c
Normal file
295
examples/device/uac2_speaker_fb/src/usb_descriptors.c
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "bsp/board_api.h"
|
||||||
|
#include "tusb.h"
|
||||||
|
#include "usb_descriptors.h"
|
||||||
|
#include "common_types.h"
|
||||||
|
|
||||||
|
#ifdef CFG_QUIRK_OS_GUESSING
|
||||||
|
#include "quirk_os_guessing.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 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 = 0x0201,
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
#if CFG_QUIRK_OS_GUESSING
|
||||||
|
quirk_os_guessing_desc_device_cb();
|
||||||
|
#endif
|
||||||
|
return (uint8_t const *)&desc_device;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CFG_AUDIO_DEBUG
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// HID Report Descriptor
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
uint8_t const desc_hid_report[] =
|
||||||
|
{
|
||||||
|
HID_USAGE_PAGE_N ( HID_USAGE_PAGE_VENDOR, 2 ),\
|
||||||
|
HID_USAGE ( 0x01 ),\
|
||||||
|
HID_COLLECTION ( HID_COLLECTION_APPLICATION ),\
|
||||||
|
HID_USAGE ( 0x02 ),\
|
||||||
|
HID_LOGICAL_MIN ( 0x00 ),\
|
||||||
|
HID_LOGICAL_MAX_N ( 0xff, 2 ),\
|
||||||
|
HID_REPORT_SIZE ( 8 ),\
|
||||||
|
HID_REPORT_COUNT( sizeof(audio_debug_info_t) ),\
|
||||||
|
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\
|
||||||
|
HID_COLLECTION_END
|
||||||
|
};
|
||||||
|
|
||||||
|
// Invoked when received GET HID REPORT DESCRIPTOR
|
||||||
|
// Application return pointer to descriptor
|
||||||
|
// Descriptor contents must exist long enough for transfer to complete
|
||||||
|
uint8_t const * tud_hid_descriptor_report_cb(uint8_t itf)
|
||||||
|
{
|
||||||
|
(void) itf;
|
||||||
|
return desc_hid_report;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Configuration Descriptor
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
#if CFG_AUDIO_DEBUG
|
||||||
|
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_AUDIO_SPEAKER_STEREO_FB_DESC_LEN + TUD_HID_DESC_LEN)
|
||||||
|
#else
|
||||||
|
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_AUDIO_SPEAKER_STEREO_FB_DESC_LEN)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#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_FB 0x03
|
||||||
|
#define EPNUM_AUDIO_OUT 0x03
|
||||||
|
#define EPNUM_DEBUG 0x04
|
||||||
|
|
||||||
|
#elif CFG_TUSB_MCU == OPT_MCU_NRF5X
|
||||||
|
// ISO endpoints for NRF5x are fixed to 0x08 (0x88)
|
||||||
|
#define EPNUM_AUDIO_FB 0x08
|
||||||
|
#define EPNUM_AUDIO_OUT 0x08
|
||||||
|
#define EPNUM_DEBUG 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_FB 0x01
|
||||||
|
#define EPNUM_AUDIO_OUT 0x02
|
||||||
|
#define EPNUM_DEBUG 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_FB 0x01
|
||||||
|
#define EPNUM_AUDIO_OUT 0x02
|
||||||
|
#define EPNUM_DEBUG 0x03
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define EPNUM_AUDIO_FB 0x01
|
||||||
|
#define EPNUM_AUDIO_OUT 0x01
|
||||||
|
#define EPNUM_DEBUG 0x02
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint8_t const desc_configuration_default[] =
|
||||||
|
{
|
||||||
|
// 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, byte per sample, bit per sample, EP Out, EP size, EP feedback, feedback EP size,
|
||||||
|
TUD_AUDIO_SPEAKER_STEREO_FB_DESCRIPTOR(0, 4, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_RESOLUTION_RX, EPNUM_AUDIO_OUT, CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX, EPNUM_AUDIO_FB | 0x80, 4),
|
||||||
|
|
||||||
|
#if CFG_AUDIO_DEBUG
|
||||||
|
// Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval
|
||||||
|
TUD_HID_DESCRIPTOR(ITF_NUM_DEBUG, 0, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_DEBUG | 0x80, CFG_TUD_HID_EP_BUFSIZE, 7)
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#if CFG_QUIRK_OS_GUESSING
|
||||||
|
// OS X needs 3 bytes feedback endpoint on FS
|
||||||
|
uint8_t const desc_configuration_osx_fs[] =
|
||||||
|
{
|
||||||
|
// 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, byte per sample, bit per sample, EP Out, EP size, EP feedback, feedback EP size,
|
||||||
|
TUD_AUDIO_SPEAKER_STEREO_FB_DESCRIPTOR(0, 4, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_RESOLUTION_RX, EPNUM_AUDIO_OUT, CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX, EPNUM_AUDIO_FB | 0x80, 3),
|
||||||
|
|
||||||
|
#if CFG_AUDIO_DEBUG
|
||||||
|
// Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval
|
||||||
|
TUD_HID_DESCRIPTOR(ITF_NUM_DEBUG, 0, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_DEBUG | 0x80, CFG_TUD_HID_EP_BUFSIZE, 7)
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 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 CFG_QUIRK_OS_GUESSING
|
||||||
|
quirk_os_guessing_desc_configuration_cb();
|
||||||
|
if(tud_speed_get() == TUSB_SPEED_FULL && quirk_os_guessing_get() == QUIRK_OS_GUESSING_OSX) {
|
||||||
|
return desc_configuration_osx_fs;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return desc_configuration_default;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// BOS Descriptor, required for OS guessing quirk
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
#define TUD_BOS_USB20_EXT_DESC_LEN 7
|
||||||
|
|
||||||
|
#define BOS_TOTAL_LEN (TUD_BOS_DESC_LEN + TUD_BOS_USB20_EXT_DESC_LEN)
|
||||||
|
|
||||||
|
// BOS Descriptor is required for webUSB
|
||||||
|
uint8_t const desc_bos[] =
|
||||||
|
{
|
||||||
|
// total length, number of device caps
|
||||||
|
TUD_BOS_DESCRIPTOR(BOS_TOTAL_LEN, 1),
|
||||||
|
|
||||||
|
// USB 2.0 Extension Descriptor
|
||||||
|
0x07, TUSB_DESC_DEVICE_CAPABILITY, DEVICE_CAPABILITY_USB20_EXTENSION, 0x00, 0x00, 0x00,0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t const * tud_descriptor_bos_cb(void)
|
||||||
|
{
|
||||||
|
#if CFG_QUIRK_OS_GUESSING
|
||||||
|
quirk_os_guessing_desc_bos_cb();
|
||||||
|
#endif
|
||||||
|
return desc_bos;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// 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 Speaker", // 2: Product
|
||||||
|
NULL, // 3: Serials will use unique ID if possible
|
||||||
|
"UAC2 Speaker", // 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;
|
||||||
|
|
||||||
|
#if CFG_QUIRK_OS_GUESSING
|
||||||
|
quirk_os_guessing_desc_string_cb();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
82
examples/device/uac2_speaker_fb/src/usb_descriptors.h
Normal file
82
examples/device/uac2_speaker_fb/src/usb_descriptors.h
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _USB_DESCRIPTORS_H_
|
||||||
|
#define _USB_DESCRIPTORS_H_
|
||||||
|
|
||||||
|
// Defined in TUD_AUDIO_SPEAKER_STEREO_FB_DESCRIPTOR
|
||||||
|
#define UAC2_ENTITY_CLOCK 0x04
|
||||||
|
#define UAC2_ENTITY_INPUT_TERMINAL 0x01
|
||||||
|
#define UAC2_ENTITY_FEATURE_UNIT 0x02
|
||||||
|
#define UAC2_ENTITY_OUTPUT_TERMINAL 0x03
|
||||||
|
|
||||||
|
#define TUD_AUDIO_SPEAKER_STEREO_FB_DESC_LEN (TUD_AUDIO_DESC_IAD_LEN\
|
||||||
|
+ TUD_AUDIO_DESC_STD_AC_LEN\
|
||||||
|
+ TUD_AUDIO_DESC_CS_AC_LEN\
|
||||||
|
+ TUD_AUDIO_DESC_CLK_SRC_LEN\
|
||||||
|
+ TUD_AUDIO_DESC_INPUT_TERM_LEN\
|
||||||
|
+ TUD_AUDIO_DESC_OUTPUT_TERM_LEN\
|
||||||
|
+ TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL_LEN\
|
||||||
|
+ TUD_AUDIO_DESC_STD_AS_INT_LEN\
|
||||||
|
+ TUD_AUDIO_DESC_STD_AS_INT_LEN\
|
||||||
|
+ TUD_AUDIO_DESC_CS_AS_INT_LEN\
|
||||||
|
+ TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN\
|
||||||
|
+ TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN\
|
||||||
|
+ TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN\
|
||||||
|
+ TUD_AUDIO_DESC_STD_AS_ISO_FB_EP_LEN)
|
||||||
|
|
||||||
|
#define TUD_AUDIO_SPEAKER_STEREO_FB_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epout, _epoutsize, _epfb, _epfbsize) \
|
||||||
|
/* Standard Interface Association Descriptor (IAD) */\
|
||||||
|
TUD_AUDIO_DESC_IAD(/*_firstitf*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00),\
|
||||||
|
/* Standard AC Interface Descriptor(4.7.1) */\
|
||||||
|
TUD_AUDIO_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\
|
||||||
|
/* Class-Specific AC Interface Header Descriptor(4.7.2) */\
|
||||||
|
TUD_AUDIO_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO_FUNC_DESKTOP_SPEAKER, /*_totallen*/ TUD_AUDIO_DESC_CLK_SRC_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+TUD_AUDIO_DESC_OUTPUT_TERM_LEN+TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL_LEN, /*_ctrl*/ AUDIO_CS_AS_INTERFACE_CTRL_LATENCY_POS),\
|
||||||
|
/* Clock Source Descriptor(4.7.2.1) */\
|
||||||
|
TUD_AUDIO_DESC_CLK_SRC(/*_clkid*/ 0x04, /*_attr*/ AUDIO_CLOCK_SOURCE_ATT_INT_PRO_CLK, /*_ctrl*/ (AUDIO_CTRL_RW << AUDIO_CLOCK_SOURCE_CTRL_CLK_FRQ_POS), /*_assocTerm*/ 0x01, /*_stridx*/ 0x00),\
|
||||||
|
/* Input Terminal Descriptor(4.7.2.4) */\
|
||||||
|
TUD_AUDIO_DESC_INPUT_TERM(/*_termid*/ 0x01, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_clkid*/ 0x04, /*_nchannelslogical*/ 0x02, /*_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*/ 0x03, /*_termtype*/ AUDIO_TERM_TYPE_OUT_DESKTOP_SPEAKER, /*_assocTerm*/ 0x01, /*_srcid*/ 0x02, /*_clkid*/ 0x04, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00),\
|
||||||
|
/* Feature Unit Descriptor(4.7.2.8) */\
|
||||||
|
TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL(/*_unitid*/ 0x02, /*_srcid*/ 0x01, /*_ctrlch0master*/ AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch1*/ AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch2*/ AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS,/*_stridx*/ 0x00),\
|
||||||
|
/* 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)((_itfnum) + 1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00),\
|
||||||
|
/* Standard AS Interface Descriptor(4.9.1) */\
|
||||||
|
/* Interface 1, Alternate 1 - alternate interface for data streaming */\
|
||||||
|
TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x01, /*_nEPs*/ 0x02, /*_stridx*/ 0x00),\
|
||||||
|
/* Class-Specific AS Interface Descriptor(4.9.2) */\
|
||||||
|
TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ 0x01, /*_ctrl*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, /*_formats*/ AUDIO_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x02, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\
|
||||||
|
/* 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) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epoutsize, /*_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 Isochronous Feedback Endpoint Descriptor(4.10.2.1) */\
|
||||||
|
TUD_AUDIO_DESC_STD_AS_ISO_FB_EP(/*_ep*/ _epfb, /*_epsize*/ _epfbsize, /*_interval*/ TUD_OPT_HIGH_SPEED ? 4 : 1)\
|
||||||
|
|
||||||
|
#endif
|
@ -1,3 +1,4 @@
|
|||||||
|
mcu:CH32V103
|
||||||
mcu:CH32V20X
|
mcu:CH32V20X
|
||||||
mcu:MSP430x5xx
|
mcu:MSP430x5xx
|
||||||
mcu:NUC121
|
mcu:NUC121
|
||||||
|
@ -2,6 +2,7 @@ mcu:MSP430x5xx
|
|||||||
mcu:NUC121
|
mcu:NUC121
|
||||||
mcu:SAMD11
|
mcu:SAMD11
|
||||||
mcu:GD32VF103
|
mcu:GD32VF103
|
||||||
|
mcu:CH32V103
|
||||||
mcu:CH32V20X
|
mcu:CH32V20X
|
||||||
mcu:CH32V307
|
mcu:CH32V307
|
||||||
mcu:STM32L0
|
mcu:STM32L0
|
||||||
|
@ -10,4 +10,5 @@ if (FAMILY STREQUAL "rp2040" AND NOT TARGET tinyusb_pico_pio_usb)
|
|||||||
else ()
|
else ()
|
||||||
# family_add_subdirectory will filter what to actually add based on selected FAMILY
|
# family_add_subdirectory will filter what to actually add based on selected FAMILY
|
||||||
family_add_subdirectory(host_hid_to_device_cdc)
|
family_add_subdirectory(host_hid_to_device_cdc)
|
||||||
|
family_add_subdirectory(host_info_to_device_cdc)
|
||||||
endif ()
|
endif ()
|
||||||
|
@ -55,14 +55,14 @@ const uint8_t colemak[128] = {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static uint8_t const keycode2ascii[128][2] = { HID_KEYCODE_TO_ASCII };
|
static uint8_t const keycode2ascii[128][2] = {HID_KEYCODE_TO_ASCII};
|
||||||
|
|
||||||
/* Blink pattern
|
/* Blink pattern
|
||||||
* - 250 ms : device not mounted
|
* - 250 ms : device not mounted
|
||||||
* - 1000 ms : device mounted
|
* - 1000 ms : device mounted
|
||||||
* - 2500 ms : device is suspended
|
* - 2500 ms : device is suspended
|
||||||
*/
|
*/
|
||||||
enum {
|
enum {
|
||||||
BLINK_NOT_MOUNTED = 250,
|
BLINK_NOT_MOUNTED = 250,
|
||||||
BLINK_MOUNTED = 1000,
|
BLINK_MOUNTED = 1000,
|
||||||
BLINK_SUSPENDED = 2500,
|
BLINK_SUSPENDED = 2500,
|
||||||
@ -73,8 +73,7 @@ static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
|
|||||||
void led_blinking_task(void);
|
void led_blinking_task(void);
|
||||||
|
|
||||||
/*------------- MAIN -------------*/
|
/*------------- MAIN -------------*/
|
||||||
int main(void)
|
int main(void) {
|
||||||
{
|
|
||||||
board_init();
|
board_init();
|
||||||
|
|
||||||
printf("TinyUSB Host HID <-> Device CDC Example\r\n");
|
printf("TinyUSB Host HID <-> Device CDC Example\r\n");
|
||||||
@ -87,8 +86,7 @@ int main(void)
|
|||||||
board_init_after_tusb();
|
board_init_after_tusb();
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1)
|
while (1) {
|
||||||
{
|
|
||||||
tud_task(); // tinyusb device task
|
tud_task(); // tinyusb device task
|
||||||
tuh_task(); // tinyusb host task
|
tuh_task(); // tinyusb host task
|
||||||
led_blinking_task();
|
led_blinking_task();
|
||||||
@ -102,35 +100,30 @@ int main(void)
|
|||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
// Invoked when device is mounted
|
// Invoked when device is mounted
|
||||||
void tud_mount_cb(void)
|
void tud_mount_cb(void) {
|
||||||
{
|
|
||||||
blink_interval_ms = BLINK_MOUNTED;
|
blink_interval_ms = BLINK_MOUNTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoked when device is unmounted
|
// Invoked when device is unmounted
|
||||||
void tud_umount_cb(void)
|
void tud_umount_cb(void) {
|
||||||
{
|
|
||||||
blink_interval_ms = BLINK_NOT_MOUNTED;
|
blink_interval_ms = BLINK_NOT_MOUNTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoked when usb bus is suspended
|
// Invoked when usb bus is suspended
|
||||||
// remote_wakeup_en : if host allow us to perform remote wakeup
|
// 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
|
// 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;
|
(void) remote_wakeup_en;
|
||||||
blink_interval_ms = BLINK_SUSPENDED;
|
blink_interval_ms = BLINK_SUSPENDED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoked when usb bus is resumed
|
// Invoked when usb bus is resumed
|
||||||
void tud_resume_cb(void)
|
void tud_resume_cb(void) {
|
||||||
{
|
|
||||||
blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED;
|
blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoked when CDC interface received data from host
|
// 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;
|
(void) itf;
|
||||||
|
|
||||||
char buf[64];
|
char buf[64];
|
||||||
@ -149,38 +142,36 @@ void tud_cdc_rx_cb(uint8_t itf)
|
|||||||
// can be used to parse common/simple enough descriptor.
|
// can be used to parse common/simple enough descriptor.
|
||||||
// Note: if report descriptor length > CFG_TUH_ENUMERATION_BUFSIZE, it will be skipped
|
// Note: if report descriptor length > CFG_TUH_ENUMERATION_BUFSIZE, it will be skipped
|
||||||
// therefore report_desc = NULL, desc_len = 0
|
// 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)
|
void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len) {
|
||||||
{
|
(void) desc_report;
|
||||||
(void)desc_report;
|
(void) desc_len;
|
||||||
(void)desc_len;
|
|
||||||
|
|
||||||
// Interface protocol (hid_interface_protocol_enum_t)
|
// Interface protocol (hid_interface_protocol_enum_t)
|
||||||
const char* protocol_str[] = { "None", "Keyboard", "Mouse" };
|
const char* protocol_str[] = {"None", "Keyboard", "Mouse"};
|
||||||
uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance);
|
uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance);
|
||||||
|
|
||||||
uint16_t vid, pid;
|
uint16_t vid, pid;
|
||||||
tuh_vid_pid_get(dev_addr, &vid, &pid);
|
tuh_vid_pid_get(dev_addr, &vid, &pid);
|
||||||
|
|
||||||
char tempbuf[256];
|
char tempbuf[256];
|
||||||
int count = sprintf(tempbuf, "[%04x:%04x][%u] HID Interface%u, Protocol = %s\r\n", vid, pid, dev_addr, instance, protocol_str[itf_protocol]);
|
int count = sprintf(
|
||||||
|
tempbuf, "[%04x:%04x][%u] HID Interface%u, Protocol = %s\r\n", vid, pid, dev_addr, instance,
|
||||||
|
protocol_str[itf_protocol]);
|
||||||
|
|
||||||
tud_cdc_write(tempbuf, (uint32_t) count);
|
tud_cdc_write(tempbuf, (uint32_t) count);
|
||||||
tud_cdc_write_flush();
|
tud_cdc_write_flush();
|
||||||
|
|
||||||
// Receive report from boot keyboard & mouse only
|
// Receive report from boot keyboard & mouse only
|
||||||
// tuh_hid_report_received_cb() will be invoked when report is available
|
// tuh_hid_report_received_cb() will be invoked when report is available
|
||||||
if (itf_protocol == HID_ITF_PROTOCOL_KEYBOARD || itf_protocol == HID_ITF_PROTOCOL_MOUSE)
|
if (itf_protocol == HID_ITF_PROTOCOL_KEYBOARD || itf_protocol == HID_ITF_PROTOCOL_MOUSE) {
|
||||||
{
|
if (!tuh_hid_receive_report(dev_addr, instance)) {
|
||||||
if ( !tuh_hid_receive_report(dev_addr, instance) )
|
|
||||||
{
|
|
||||||
tud_cdc_write_str("Error: cannot request report\r\n");
|
tud_cdc_write_str("Error: cannot request report\r\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoked when device with hid interface is un-mounted
|
// Invoked when device with hid interface is un-mounted
|
||||||
void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance)
|
void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) {
|
||||||
{
|
|
||||||
char tempbuf[256];
|
char tempbuf[256];
|
||||||
int count = sprintf(tempbuf, "[%u] HID Interface%u is unmounted\r\n", dev_addr, instance);
|
int count = sprintf(tempbuf, "[%u] HID Interface%u is unmounted\r\n", dev_addr, instance);
|
||||||
tud_cdc_write(tempbuf, (uint32_t) count);
|
tud_cdc_write(tempbuf, (uint32_t) count);
|
||||||
@ -188,11 +179,9 @@ void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// look up new key in previous keys
|
// look up new key in previous keys
|
||||||
static inline bool find_key_in_report(hid_keyboard_report_t const *report, uint8_t keycode)
|
static inline bool find_key_in_report(hid_keyboard_report_t const* report, uint8_t keycode) {
|
||||||
{
|
for (uint8_t i = 0; i < 6; i++) {
|
||||||
for(uint8_t i=0; i<6; i++)
|
if (report->keycode[i] == keycode) return true;
|
||||||
{
|
|
||||||
if (report->keycode[i] == keycode) return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -200,22 +189,17 @@ static inline bool find_key_in_report(hid_keyboard_report_t const *report, uint8
|
|||||||
|
|
||||||
|
|
||||||
// convert hid keycode to ascii and print via usb device CDC (ignore non-printable)
|
// convert hid keycode to ascii and print via usb device CDC (ignore non-printable)
|
||||||
static void process_kbd_report(uint8_t dev_addr, hid_keyboard_report_t const *report)
|
static void process_kbd_report(uint8_t dev_addr, hid_keyboard_report_t const* report) {
|
||||||
{
|
|
||||||
(void) dev_addr;
|
(void) dev_addr;
|
||||||
static hid_keyboard_report_t prev_report = { 0, 0, {0} }; // previous report to check key released
|
static hid_keyboard_report_t prev_report = {0, 0, {0}}; // previous report to check key released
|
||||||
bool flush = false;
|
bool flush = false;
|
||||||
|
|
||||||
for(uint8_t i=0; i<6; i++)
|
for (uint8_t i = 0; i < 6; i++) {
|
||||||
{
|
|
||||||
uint8_t keycode = report->keycode[i];
|
uint8_t keycode = report->keycode[i];
|
||||||
if ( keycode )
|
if (keycode) {
|
||||||
{
|
if (find_key_in_report(&prev_report, keycode)) {
|
||||||
if ( find_key_in_report(&prev_report, keycode) )
|
|
||||||
{
|
|
||||||
// exist in previous report means the current key is holding
|
// exist in previous report means the current key is holding
|
||||||
}else
|
} else {
|
||||||
{
|
|
||||||
// not existed in previous report means the current key is pressed
|
// not existed in previous report means the current key is pressed
|
||||||
|
|
||||||
// remap the key code for Colemak layout
|
// remap the key code for Colemak layout
|
||||||
@ -227,8 +211,7 @@ static void process_kbd_report(uint8_t dev_addr, hid_keyboard_report_t const *re
|
|||||||
bool const is_shift = report->modifier & (KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT);
|
bool const is_shift = report->modifier & (KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT);
|
||||||
uint8_t ch = keycode2ascii[keycode][is_shift ? 1 : 0];
|
uint8_t ch = keycode2ascii[keycode][is_shift ? 1 : 0];
|
||||||
|
|
||||||
if (ch)
|
if (ch) {
|
||||||
{
|
|
||||||
if (ch == '\n') tud_cdc_write("\r", 1);
|
if (ch == '\n') tud_cdc_write("\r", 1);
|
||||||
tud_cdc_write(&ch, 1);
|
tud_cdc_write(&ch, 1);
|
||||||
flush = true;
|
flush = true;
|
||||||
@ -244,13 +227,12 @@ static void process_kbd_report(uint8_t dev_addr, hid_keyboard_report_t const *re
|
|||||||
}
|
}
|
||||||
|
|
||||||
// send mouse report to usb device CDC
|
// send mouse report to usb device CDC
|
||||||
static void process_mouse_report(uint8_t dev_addr, hid_mouse_report_t const * report)
|
static void process_mouse_report(uint8_t dev_addr, hid_mouse_report_t const* report) {
|
||||||
{
|
|
||||||
//------------- button state -------------//
|
//------------- button state -------------//
|
||||||
//uint8_t button_changed_mask = report->buttons ^ prev_report.buttons;
|
//uint8_t button_changed_mask = report->buttons ^ prev_report.buttons;
|
||||||
char l = report->buttons & MOUSE_BUTTON_LEFT ? 'L' : '-';
|
char l = report->buttons & MOUSE_BUTTON_LEFT ? 'L' : '-';
|
||||||
char m = report->buttons & MOUSE_BUTTON_MIDDLE ? 'M' : '-';
|
char m = report->buttons & MOUSE_BUTTON_MIDDLE ? 'M' : '-';
|
||||||
char r = report->buttons & MOUSE_BUTTON_RIGHT ? 'R' : '-';
|
char r = report->buttons & MOUSE_BUTTON_RIGHT ? 'R' : '-';
|
||||||
|
|
||||||
char tempbuf[32];
|
char tempbuf[32];
|
||||||
int count = sprintf(tempbuf, "[%u] %c%c%c %d %d %d\r\n", dev_addr, l, m, r, report->x, report->y, report->wheel);
|
int count = sprintf(tempbuf, "[%u] %c%c%c %d %d %d\r\n", dev_addr, l, m, r, report->x, report->y, report->wheel);
|
||||||
@ -260,27 +242,25 @@ static void process_mouse_report(uint8_t dev_addr, hid_mouse_report_t const * re
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Invoked when received report from device via interrupt endpoint
|
// 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)
|
void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len) {
|
||||||
{
|
|
||||||
(void) len;
|
(void) len;
|
||||||
uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance);
|
uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance);
|
||||||
|
|
||||||
switch(itf_protocol)
|
switch (itf_protocol) {
|
||||||
{
|
|
||||||
case HID_ITF_PROTOCOL_KEYBOARD:
|
case HID_ITF_PROTOCOL_KEYBOARD:
|
||||||
process_kbd_report(dev_addr, (hid_keyboard_report_t const*) report );
|
process_kbd_report(dev_addr, (hid_keyboard_report_t const*) report);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HID_ITF_PROTOCOL_MOUSE:
|
case HID_ITF_PROTOCOL_MOUSE:
|
||||||
process_mouse_report(dev_addr, (hid_mouse_report_t const*) report );
|
process_mouse_report(dev_addr, (hid_mouse_report_t const*) report);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: break;
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// continue to request to receive report
|
// continue to request to receive report
|
||||||
if ( !tuh_hid_receive_report(dev_addr, instance) )
|
if (!tuh_hid_receive_report(dev_addr, instance)) {
|
||||||
{
|
|
||||||
tud_cdc_write_str("Error: cannot request report\r\n");
|
tud_cdc_write_str("Error: cannot request report\r\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -288,13 +268,12 @@ void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t cons
|
|||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Blinking Task
|
// Blinking Task
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
void led_blinking_task(void)
|
void led_blinking_task(void) {
|
||||||
{
|
|
||||||
static uint32_t start_ms = 0;
|
static uint32_t start_ms = 0;
|
||||||
static bool led_state = false;
|
static bool led_state = false;
|
||||||
|
|
||||||
// Blink every interval ms
|
// 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;
|
start_ms += blink_interval_ms;
|
||||||
|
|
||||||
board_led_write(led_state);
|
board_led_write(led_state);
|
||||||
|
@ -23,8 +23,8 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _TUSB_CONFIG_H_
|
#ifndef TUSB_CONFIG_H_
|
||||||
#define _TUSB_CONFIG_H_
|
#define TUSB_CONFIG_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -144,4 +144,4 @@
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _TUSB_CONFIG_H_ */
|
#endif
|
||||||
|
@ -42,44 +42,41 @@
|
|||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Device Descriptors
|
// Device Descriptors
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
tusb_desc_device_t const desc_device =
|
tusb_desc_device_t const desc_device = {
|
||||||
{
|
.bLength = sizeof(tusb_desc_device_t),
|
||||||
.bLength = sizeof(tusb_desc_device_t),
|
.bDescriptorType = TUSB_DESC_DEVICE,
|
||||||
.bDescriptorType = TUSB_DESC_DEVICE,
|
.bcdUSB = USB_BCD,
|
||||||
.bcdUSB = USB_BCD,
|
|
||||||
|
|
||||||
// Use Interface Association Descriptor (IAD) for CDC
|
// Use Interface Association Descriptor (IAD) for CDC
|
||||||
// As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1)
|
// As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1)
|
||||||
.bDeviceClass = TUSB_CLASS_MISC,
|
.bDeviceClass = TUSB_CLASS_MISC,
|
||||||
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
|
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
|
||||||
.bDeviceProtocol = MISC_PROTOCOL_IAD,
|
.bDeviceProtocol = MISC_PROTOCOL_IAD,
|
||||||
|
|
||||||
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
|
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
|
||||||
|
|
||||||
.idVendor = USB_VID,
|
.idVendor = USB_VID,
|
||||||
.idProduct = USB_PID,
|
.idProduct = USB_PID,
|
||||||
.bcdDevice = 0x0100,
|
.bcdDevice = 0x0100,
|
||||||
|
|
||||||
.iManufacturer = 0x01,
|
.iManufacturer = 0x01,
|
||||||
.iProduct = 0x02,
|
.iProduct = 0x02,
|
||||||
.iSerialNumber = 0x03,
|
.iSerialNumber = 0x03,
|
||||||
|
|
||||||
.bNumConfigurations = 0x01
|
.bNumConfigurations = 0x01
|
||||||
};
|
};
|
||||||
|
|
||||||
// Invoked when received GET DEVICE DESCRIPTOR
|
// Invoked when received GET DEVICE DESCRIPTOR
|
||||||
// Application return pointer to descriptor
|
// Application return pointer to descriptor
|
||||||
uint8_t const * tud_descriptor_device_cb(void)
|
uint8_t const* tud_descriptor_device_cb(void) {
|
||||||
{
|
return (uint8_t const*) &desc_device;
|
||||||
return (uint8_t const *) &desc_device;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Configuration Descriptor
|
// Configuration Descriptor
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
ITF_NUM_CDC = 0,
|
ITF_NUM_CDC = 0,
|
||||||
ITF_NUM_CDC_DATA,
|
ITF_NUM_CDC_DATA,
|
||||||
ITF_NUM_TOTAL
|
ITF_NUM_TOTAL
|
||||||
@ -92,7 +89,7 @@ enum
|
|||||||
#define EPNUM_CDC_OUT 0x02
|
#define EPNUM_CDC_OUT 0x02
|
||||||
#define EPNUM_CDC_IN 0x82
|
#define EPNUM_CDC_IN 0x82
|
||||||
|
|
||||||
#elif CFG_TUSB_MCU == OPT_MCU_SAMG || CFG_TUSB_MCU == OPT_MCU_SAMX7X
|
#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
|
// SAMG & SAME70 don't support a same endpoint number with different direction IN and OUT
|
||||||
// e.g EP1 OUT & EP1 IN cannot exist together
|
// e.g EP1 OUT & EP1 IN cannot exist together
|
||||||
#define EPNUM_CDC_NOTIF 0x81
|
#define EPNUM_CDC_NOTIF 0x81
|
||||||
@ -109,7 +106,7 @@ enum
|
|||||||
#define EPNUM_CDC_IN 0x81
|
#define EPNUM_CDC_IN 0x81
|
||||||
|
|
||||||
#elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X
|
#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
|
// FT9XX doesn't support a same endpoint number with different direction IN and OUT
|
||||||
// e.g EP1 OUT & EP1 IN cannot exist together
|
// e.g EP1 OUT & EP1 IN cannot exist together
|
||||||
#define EPNUM_CDC_NOTIF 0x81
|
#define EPNUM_CDC_NOTIF 0x81
|
||||||
#define EPNUM_CDC_OUT 0x02
|
#define EPNUM_CDC_OUT 0x02
|
||||||
@ -125,21 +122,19 @@ enum
|
|||||||
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN)
|
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN)
|
||||||
|
|
||||||
// full speed configuration
|
// full speed configuration
|
||||||
uint8_t const desc_fs_configuration[] =
|
uint8_t const desc_fs_configuration[] = {
|
||||||
{
|
// Config number, interface count, string index, total length, attribute, power in mA
|
||||||
// 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),
|
||||||
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
|
|
||||||
|
|
||||||
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
|
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
|
||||||
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64),
|
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64),
|
||||||
};
|
};
|
||||||
|
|
||||||
#if TUD_OPT_HIGH_SPEED
|
#if TUD_OPT_HIGH_SPEED
|
||||||
// Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration
|
// Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration
|
||||||
|
|
||||||
// high speed configuration
|
// high speed configuration
|
||||||
uint8_t const desc_hs_configuration[] =
|
uint8_t const desc_hs_configuration[] = {
|
||||||
{
|
|
||||||
// Config number, interface count, string index, total length, attribute, power in mA
|
// 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),
|
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
|
||||||
|
|
||||||
@ -151,8 +146,7 @@ uint8_t const desc_hs_configuration[] =
|
|||||||
uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN];
|
uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN];
|
||||||
|
|
||||||
// device qualifier is mostly similar to device descriptor since we don't change configuration based on speed
|
// 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 =
|
tusb_desc_device_qualifier_t const desc_device_qualifier = {
|
||||||
{
|
|
||||||
.bLength = sizeof(tusb_desc_device_qualifier_t),
|
.bLength = sizeof(tusb_desc_device_qualifier_t),
|
||||||
.bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER,
|
.bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER,
|
||||||
.bcdUSB = USB_BCD,
|
.bcdUSB = USB_BCD,
|
||||||
@ -170,16 +164,14 @@ tusb_desc_device_qualifier_t const desc_device_qualifier =
|
|||||||
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete.
|
// 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
|
// 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.
|
// 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)
|
uint8_t const* tud_descriptor_device_qualifier_cb(void) {
|
||||||
{
|
|
||||||
return (uint8_t const*) &desc_device_qualifier;
|
return (uint8_t const*) &desc_device_qualifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request
|
// Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request
|
||||||
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
|
// 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
|
// 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)
|
uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index) {
|
||||||
{
|
|
||||||
(void) index; // for multiple configurations
|
(void) index; // for multiple configurations
|
||||||
|
|
||||||
// if link speed is high return fullspeed config, and vice versa
|
// if link speed is high return fullspeed config, and vice versa
|
||||||
@ -199,8 +191,7 @@ uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index)
|
|||||||
// Invoked when received GET CONFIGURATION DESCRIPTOR
|
// Invoked when received GET CONFIGURATION DESCRIPTOR
|
||||||
// Application return pointer to descriptor
|
// Application return pointer to descriptor
|
||||||
// Descriptor contents must exist long enough for transfer to complete
|
// 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
|
(void) index; // for multiple configurations
|
||||||
|
|
||||||
#if TUD_OPT_HIGH_SPEED
|
#if TUD_OPT_HIGH_SPEED
|
||||||
@ -224,24 +215,23 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// array of pointer to string descriptors
|
// array of pointer to string descriptors
|
||||||
char const *string_desc_arr[] =
|
char const* string_desc_arr[] = {
|
||||||
{
|
(const char[]) {0x09, 0x04}, // 0: is supported language is English (0x0409)
|
||||||
(const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409)
|
"TinyUSB", // 1: Manufacturer
|
||||||
"TinyUSB", // 1: Manufacturer
|
"TinyUSB Device", // 2: Product
|
||||||
"TinyUSB Device", // 2: Product
|
NULL, // 3: Serials will use unique ID if possible
|
||||||
NULL, // 3: Serials will use unique ID if possible
|
"TinyUSB CDC", // 4: CDC Interface
|
||||||
"TinyUSB CDC", // 4: CDC Interface
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint16_t _desc_str[32 + 1];
|
static uint16_t _desc_str[32 + 1];
|
||||||
|
|
||||||
// Invoked when received GET STRING DESCRIPTOR request
|
// Invoked when received GET STRING DESCRIPTOR request
|
||||||
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
|
// 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;
|
(void) langid;
|
||||||
size_t chr_count;
|
size_t chr_count;
|
||||||
|
|
||||||
switch ( index ) {
|
switch (index) {
|
||||||
case STRID_LANGID:
|
case STRID_LANGID:
|
||||||
memcpy(&_desc_str[1], string_desc_arr[0], 2);
|
memcpy(&_desc_str[1], string_desc_arr[0], 2);
|
||||||
chr_count = 1;
|
chr_count = 1;
|
||||||
@ -255,17 +245,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.
|
// 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
|
// 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
|
// Cap at max char
|
||||||
chr_count = strlen(str);
|
chr_count = strlen(str);
|
||||||
size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type
|
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
|
// 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];
|
_desc_str[1 + i] = str[i];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
40
examples/dual/host_info_to_device_cdc/CMakeLists.txt
Normal file
40
examples/dual/host_info_to_device_cdc/CMakeLists.txt
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.17)
|
||||||
|
|
||||||
|
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
|
||||||
|
|
||||||
|
# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
|
||||||
|
family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
|
||||||
|
|
||||||
|
project(${PROJECT} C CXX ASM)
|
||||||
|
|
||||||
|
# Checks this example is valid for the family and initializes the project
|
||||||
|
family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
|
||||||
|
|
||||||
|
add_executable(${PROJECT})
|
||||||
|
|
||||||
|
# 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_dual_usb_example(${PROJECT} noos)
|
||||||
|
|
||||||
|
# due to warnings from Pico-PIO-USB
|
||||||
|
target_compile_options(${PROJECT} PUBLIC
|
||||||
|
-Wno-error=shadow
|
||||||
|
-Wno-error=cast-align
|
||||||
|
-Wno-error=cast-qual
|
||||||
|
-Wno-error=redundant-decls
|
||||||
|
-Wno-error=sign-conversion
|
||||||
|
-Wno-error=conversion
|
||||||
|
-Wno-error=sign-compare
|
||||||
|
-Wno-error=unused-function
|
||||||
|
)
|
17
examples/dual/host_info_to_device_cdc/Makefile
Normal file
17
examples/dual/host_info_to_device_cdc/Makefile
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
include ../../build_system/make/make.mk
|
||||||
|
|
||||||
|
INC += \
|
||||||
|
src \
|
||||||
|
$(TOP)/hw \
|
||||||
|
|
||||||
|
# Example source
|
||||||
|
EXAMPLE_SOURCE += $(wildcard src/*.c)
|
||||||
|
SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE))
|
||||||
|
|
||||||
|
CFLAGS += -Wno-error=cast-align -Wno-error=null-dereference
|
||||||
|
|
||||||
|
SRC_C += \
|
||||||
|
src/host/hub.c \
|
||||||
|
src/host/usbh.c
|
||||||
|
|
||||||
|
include ../../build_system/make/rules.mk
|
6
examples/dual/host_info_to_device_cdc/only.txt
Normal file
6
examples/dual/host_info_to_device_cdc/only.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
board:mimxrt1060_evk
|
||||||
|
board:mimxrt1064_evk
|
||||||
|
board:mcb1800
|
||||||
|
mcu:RP2040
|
||||||
|
mcu:ra6m5
|
||||||
|
mcu:MAX3421
|
285
examples/dual/host_info_to_device_cdc/src/main.c
Normal file
285
examples/dual/host_info_to_device_cdc/src/main.c
Normal file
@ -0,0 +1,285 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Host example will get device descriptors of attached devices and print it out via device cdc as follows:
|
||||||
|
* Device 1: ID 046d:c52f
|
||||||
|
Device Descriptor:
|
||||||
|
bLength 18
|
||||||
|
bDescriptorType 1
|
||||||
|
bcdUSB 0200
|
||||||
|
bDeviceClass 0
|
||||||
|
bDeviceSubClass 0
|
||||||
|
bDeviceProtocol 0
|
||||||
|
bMaxPacketSize0 8
|
||||||
|
idVendor 0x046d
|
||||||
|
idProduct 0xc52f
|
||||||
|
bcdDevice 2200
|
||||||
|
iManufacturer 1 Logitech
|
||||||
|
iProduct 2 USB Receiver
|
||||||
|
iSerialNumber 0
|
||||||
|
bNumConfigurations 1
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "bsp/board_api.h"
|
||||||
|
#include "tusb.h"
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// MACRO CONSTANT TYPEDEF PROTYPES
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Language ID: English
|
||||||
|
#define LANGUAGE_ID 0x0409
|
||||||
|
|
||||||
|
/* 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 bool is_print[CFG_TUH_DEVICE_MAX+1] = { 0 };
|
||||||
|
|
||||||
|
static void print_utf16(uint16_t *temp_buf, size_t buf_len);
|
||||||
|
void led_blinking_task(void);
|
||||||
|
void cdc_task(void);
|
||||||
|
|
||||||
|
/*------------- MAIN -------------*/
|
||||||
|
int main(void) {
|
||||||
|
board_init();
|
||||||
|
|
||||||
|
printf("TinyUSB Host Information -> Device CDC Example\r\n");
|
||||||
|
|
||||||
|
// init device and host stack on configured roothub port
|
||||||
|
tud_init(BOARD_TUD_RHPORT);
|
||||||
|
tuh_init(BOARD_TUH_RHPORT);
|
||||||
|
|
||||||
|
if (board_init_after_tusb) {
|
||||||
|
board_init_after_tusb();
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
tud_task(); // tinyusb device task
|
||||||
|
tuh_task(); // tinyusb host task
|
||||||
|
cdc_task();
|
||||||
|
led_blinking_task();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Device CDC
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
#define cdc_printf(...) \
|
||||||
|
do { \
|
||||||
|
char _tempbuf[256]; \
|
||||||
|
int count = sprintf(_tempbuf, __VA_ARGS__); \
|
||||||
|
tud_cdc_write(_tempbuf, (uint32_t) count); \
|
||||||
|
tud_cdc_write_flush(); \
|
||||||
|
tud_task(); \
|
||||||
|
} while(0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//#define cdc_printf printf
|
||||||
|
|
||||||
|
void print_device_info(uint8_t daddr) {
|
||||||
|
tusb_desc_device_t desc_device;
|
||||||
|
uint8_t xfer_result = tuh_descriptor_get_device_sync(daddr, &desc_device, 18);
|
||||||
|
if (XFER_RESULT_SUCCESS != xfer_result) {
|
||||||
|
tud_cdc_write_str("Failed to get device descriptor\r\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cdc_printf("Device %u: ID %04x:%04x\r\n", daddr, desc_device.idVendor, desc_device.idProduct);
|
||||||
|
cdc_printf("Device Descriptor:\r\n");
|
||||||
|
cdc_printf(" bLength %u\r\n" , desc_device.bLength);
|
||||||
|
cdc_printf(" bDescriptorType %u\r\n" , desc_device.bDescriptorType);
|
||||||
|
cdc_printf(" bcdUSB %04x\r\n" , desc_device.bcdUSB);
|
||||||
|
cdc_printf(" bDeviceClass %u\r\n" , desc_device.bDeviceClass);
|
||||||
|
cdc_printf(" bDeviceSubClass %u\r\n" , desc_device.bDeviceSubClass);
|
||||||
|
cdc_printf(" bDeviceProtocol %u\r\n" , desc_device.bDeviceProtocol);
|
||||||
|
cdc_printf(" bMaxPacketSize0 %u\r\n" , desc_device.bMaxPacketSize0);
|
||||||
|
cdc_printf(" idVendor 0x%04x\r\n" , desc_device.idVendor);
|
||||||
|
cdc_printf(" idProduct 0x%04x\r\n" , desc_device.idProduct);
|
||||||
|
cdc_printf(" bcdDevice %04x\r\n" , desc_device.bcdDevice);
|
||||||
|
|
||||||
|
// Get String descriptor using Sync API
|
||||||
|
uint16_t buf[128];
|
||||||
|
|
||||||
|
cdc_printf(" iManufacturer %u " , desc_device.iManufacturer);
|
||||||
|
xfer_result = tuh_descriptor_get_manufacturer_string_sync(daddr, LANGUAGE_ID, buf, sizeof(buf));
|
||||||
|
if (XFER_RESULT_SUCCESS == xfer_result ) {
|
||||||
|
print_utf16(buf, TU_ARRAY_SIZE(buf));
|
||||||
|
}
|
||||||
|
tud_cdc_write_str("\r\n");
|
||||||
|
|
||||||
|
cdc_printf(" iProduct %u " , desc_device.iProduct);
|
||||||
|
xfer_result = tuh_descriptor_get_product_string_sync(daddr, LANGUAGE_ID, buf, sizeof(buf));
|
||||||
|
if (XFER_RESULT_SUCCESS == xfer_result) {
|
||||||
|
print_utf16(buf, TU_ARRAY_SIZE(buf));
|
||||||
|
}
|
||||||
|
tud_cdc_write_str("\r\n");
|
||||||
|
|
||||||
|
cdc_printf(" iSerialNumber %u " , desc_device.iSerialNumber);
|
||||||
|
xfer_result = tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, buf, sizeof(buf));
|
||||||
|
if (XFER_RESULT_SUCCESS == xfer_result) {
|
||||||
|
print_utf16(buf, TU_ARRAY_SIZE(buf));
|
||||||
|
}
|
||||||
|
tud_cdc_write_str("\r\n");
|
||||||
|
|
||||||
|
cdc_printf(" bNumConfigurations %u\r\n" , desc_device.bNumConfigurations);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cdc_task(void) {
|
||||||
|
if (tud_cdc_connected()) {
|
||||||
|
for (uint8_t daddr = 1; daddr <= CFG_TUH_DEVICE_MAX; daddr++) {
|
||||||
|
if (tuh_mounted(daddr)) {
|
||||||
|
if (is_print[daddr]) {
|
||||||
|
is_print[daddr] = false;
|
||||||
|
print_device_info(daddr);
|
||||||
|
tud_cdc_write_flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Host Get device information
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
void tuh_mount_cb(uint8_t daddr) {
|
||||||
|
printf("mounted device %u\r\n", daddr);
|
||||||
|
is_print[daddr] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tuh_umount_cb(uint8_t daddr) {
|
||||||
|
printf("unmounted device %u\r\n", daddr);
|
||||||
|
is_print[daddr] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Blinking Task
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
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
|
||||||
|
start_ms += blink_interval_ms;
|
||||||
|
|
||||||
|
board_led_write(led_state);
|
||||||
|
led_state = 1 - led_state; // toggle
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// String Descriptor Helper
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
static void _convert_utf16le_to_utf8(const uint16_t *utf16, size_t utf16_len, uint8_t *utf8, size_t utf8_len) {
|
||||||
|
// TODO: Check for runover.
|
||||||
|
(void)utf8_len;
|
||||||
|
// Get the UTF-16 length out of the data itself.
|
||||||
|
|
||||||
|
for (size_t i = 0; i < utf16_len; i++) {
|
||||||
|
uint16_t chr = utf16[i];
|
||||||
|
if (chr < 0x80) {
|
||||||
|
*utf8++ = chr & 0xffu;
|
||||||
|
} else if (chr < 0x800) {
|
||||||
|
*utf8++ = (uint8_t)(0xC0 | (chr >> 6 & 0x1F));
|
||||||
|
*utf8++ = (uint8_t)(0x80 | (chr >> 0 & 0x3F));
|
||||||
|
} else {
|
||||||
|
// TODO: Verify surrogate.
|
||||||
|
*utf8++ = (uint8_t)(0xE0 | (chr >> 12 & 0x0F));
|
||||||
|
*utf8++ = (uint8_t)(0x80 | (chr >> 6 & 0x3F));
|
||||||
|
*utf8++ = (uint8_t)(0x80 | (chr >> 0 & 0x3F));
|
||||||
|
}
|
||||||
|
// TODO: Handle UTF-16 code points that take two entries.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count how many bytes a utf-16-le encoded string will take in utf-8.
|
||||||
|
static int _count_utf8_bytes(const uint16_t *buf, size_t len) {
|
||||||
|
size_t total_bytes = 0;
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
uint16_t chr = buf[i];
|
||||||
|
if (chr < 0x80) {
|
||||||
|
total_bytes += 1;
|
||||||
|
} else if (chr < 0x800) {
|
||||||
|
total_bytes += 2;
|
||||||
|
} else {
|
||||||
|
total_bytes += 3;
|
||||||
|
}
|
||||||
|
// TODO: Handle UTF-16 code points that take two entries.
|
||||||
|
}
|
||||||
|
return (int) total_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_utf16(uint16_t *temp_buf, size_t buf_len) {
|
||||||
|
if ((temp_buf[0] & 0xff) == 0) return; // empty
|
||||||
|
size_t utf16_len = ((temp_buf[0] & 0xff) - 2) / sizeof(uint16_t);
|
||||||
|
size_t utf8_len = (size_t) _count_utf8_bytes(temp_buf + 1, utf16_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';
|
||||||
|
|
||||||
|
tud_cdc_write(temp_buf, utf8_len);
|
||||||
|
tud_cdc_write_flush();
|
||||||
|
tud_task();
|
||||||
|
}
|
143
examples/dual/host_info_to_device_cdc/src/tusb_config.h
Normal file
143
examples/dual/host_info_to_device_cdc/src/tusb_config.h
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
// RHPort number used for host can be defined by board.mk, default to port 1
|
||||||
|
#ifndef BOARD_TUH_RHPORT
|
||||||
|
#define BOARD_TUH_RHPORT 1
|
||||||
|
#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
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
#ifndef CFG_TUSB_DEBUG
|
||||||
|
#define CFG_TUSB_DEBUG 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Enable Device stack, Default is max speed that hardware controller could support with on-chip PHY
|
||||||
|
#define CFG_TUD_ENABLED 1
|
||||||
|
#define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED
|
||||||
|
|
||||||
|
// Enable Host stack, Default is max speed that hardware controller could support with on-chip PHY
|
||||||
|
#define CFG_TUH_ENABLED 1
|
||||||
|
#define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED
|
||||||
|
|
||||||
|
#if CFG_TUSB_MCU == OPT_MCU_RP2040
|
||||||
|
// Use pico-pio-usb as host controller for raspberry rp2040
|
||||||
|
#define CFG_TUH_RPI_PIO_USB 1
|
||||||
|
#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_TUD_MEM_SECTION
|
||||||
|
#define CFG_TUD_MEM_SECTION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CFG_TUD_MEM_ALIGN
|
||||||
|
#define CFG_TUD_MEM_ALIGN __attribute__ ((aligned(4)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// DEVICE CONFIGURATION
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef CFG_TUD_ENDPOINT0_SIZE
|
||||||
|
#define CFG_TUD_ENDPOINT0_SIZE 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------- CLASS -------------//
|
||||||
|
#define CFG_TUD_CDC 1
|
||||||
|
|
||||||
|
// CDC FIFO size of TX and RX
|
||||||
|
#define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
|
||||||
|
#define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
|
||||||
|
|
||||||
|
// CDC Endpoint transfer buffer size, more is faster
|
||||||
|
#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// HOST CONFIGURATION
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Size of buffer to hold descriptors and other data used for enumeration
|
||||||
|
#define CFG_TUH_ENUMERATION_BUFSIZE 256
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
#define CFG_TUH_HUB 1
|
||||||
|
// max device support (excluding hub device)
|
||||||
|
#define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB ? 4 : 1) // hub typically has 4 ports
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
268
examples/dual/host_info_to_device_cdc/src/usb_descriptors.c
Normal file
268
examples/dual/host_info_to_device_cdc/src/usb_descriptors.c
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
/*
|
||||||
|
* 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] 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(VENDOR, 4) )
|
||||||
|
|
||||||
|
#define USB_VID 0xCafe
|
||||||
|
#define USB_BCD 0x0200
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// 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 CDC
|
||||||
|
// 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 = 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_CDC = 0,
|
||||||
|
ITF_NUM_CDC_DATA,
|
||||||
|
ITF_NUM_TOTAL
|
||||||
|
};
|
||||||
|
|
||||||
|
#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, 5 Bulk etc ...
|
||||||
|
#define EPNUM_CDC_NOTIF 0x81
|
||||||
|
#define EPNUM_CDC_OUT 0x02
|
||||||
|
#define EPNUM_CDC_IN 0x82
|
||||||
|
|
||||||
|
#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_CDC_NOTIF 0x81
|
||||||
|
#define EPNUM_CDC_OUT 0x02
|
||||||
|
#define EPNUM_CDC_IN 0x83
|
||||||
|
|
||||||
|
#elif CFG_TUSB_MCU == OPT_MCU_CXD56
|
||||||
|
// CXD56 doesn't support a same endpoint number with different direction IN and OUT
|
||||||
|
// e.g EP1 OUT & EP1 IN cannot exist together
|
||||||
|
// CXD56 USB driver has fixed endpoint type (bulk/interrupt/iso) and direction (IN/OUT) by its number
|
||||||
|
// 0 control (IN/OUT), 1 Bulk (IN), 2 Bulk (OUT), 3 In (IN), 4 Bulk (IN), 5 Bulk (OUT), 6 In (IN)
|
||||||
|
#define EPNUM_CDC_NOTIF 0x83
|
||||||
|
#define EPNUM_CDC_OUT 0x02
|
||||||
|
#define EPNUM_CDC_IN 0x81
|
||||||
|
|
||||||
|
#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_CDC_NOTIF 0x81
|
||||||
|
#define EPNUM_CDC_OUT 0x02
|
||||||
|
#define EPNUM_CDC_IN 0x83
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define EPNUM_CDC_NOTIF 0x81
|
||||||
|
#define EPNUM_CDC_OUT 0x02
|
||||||
|
#define EPNUM_CDC_IN 0x82
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN)
|
||||||
|
|
||||||
|
// full speed configuration
|
||||||
|
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, 0x00, 100),
|
||||||
|
|
||||||
|
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
|
||||||
|
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64),
|
||||||
|
};
|
||||||
|
|
||||||
|
#if TUD_OPT_HIGH_SPEED
|
||||||
|
// Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration
|
||||||
|
|
||||||
|
// high speed configuration
|
||||||
|
uint8_t const desc_hs_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 notification address and size, EP data address (out, in) and size.
|
||||||
|
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 512),
|
||||||
|
};
|
||||||
|
|
||||||
|
// other speed configuration
|
||||||
|
uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN];
|
||||||
|
|
||||||
|
// 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_qualifier_t),
|
||||||
|
.bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER,
|
||||||
|
.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
|
||||||
|
// Note: the descriptor type is OHER_SPEED_CONFIG instead of CONFIG
|
||||||
|
memcpy(desc_other_speed_config,
|
||||||
|
(tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration,
|
||||||
|
CONFIG_TOTAL_LEN);
|
||||||
|
|
||||||
|
desc_other_speed_config[1] = TUSB_DESC_OTHER_SPEED_CONFIG;
|
||||||
|
|
||||||
|
return desc_other_speed_config;
|
||||||
|
}
|
||||||
|
|
||||||
|
#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.
|
||||||
|
return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration;
|
||||||
|
#else
|
||||||
|
return desc_fs_configuration;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// 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 CDC", // 4: CDC 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;
|
||||||
|
}
|
@ -9,5 +9,6 @@ family_initialize_project(tinyusb_host_examples ${CMAKE_CURRENT_LIST_DIR})
|
|||||||
family_add_subdirectory(bare_api)
|
family_add_subdirectory(bare_api)
|
||||||
family_add_subdirectory(cdc_msc_hid)
|
family_add_subdirectory(cdc_msc_hid)
|
||||||
family_add_subdirectory(cdc_msc_hid_freertos)
|
family_add_subdirectory(cdc_msc_hid_freertos)
|
||||||
|
family_add_subdirectory(device_info)
|
||||||
family_add_subdirectory(hid_controller)
|
family_add_subdirectory(hid_controller)
|
||||||
family_add_subdirectory(msc_file_explorer)
|
family_add_subdirectory(msc_file_explorer)
|
||||||
|
@ -23,10 +23,6 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* This example current worked and tested with following controller
|
|
||||||
* - Sony DualShock 4 [CUH-ZCT2x] VID = 0x054c, PID = 0x09cc
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -23,8 +23,8 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _TUSB_CONFIG_H_
|
#ifndef TUSB_CONFIG_H_
|
||||||
#define _TUSB_CONFIG_H_
|
#define TUSB_CONFIG_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -118,4 +118,4 @@
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _TUSB_CONFIG_H_ */
|
#endif
|
||||||
|
@ -235,6 +235,7 @@ 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)
|
static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len)
|
||||||
{
|
{
|
||||||
(void) dev_addr;
|
(void) dev_addr;
|
||||||
|
(void) len;
|
||||||
|
|
||||||
uint8_t const rpt_count = hid_info[instance].report_count;
|
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_arr = hid_info[instance].report_info;
|
||||||
|
32
examples/host/device_info/CMakeLists.txt
Normal file
32
examples/host/device_info/CMakeLists.txt
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.17)
|
||||||
|
|
||||||
|
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
|
||||||
|
|
||||||
|
# gets PROJECT name for the example
|
||||||
|
family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
|
||||||
|
|
||||||
|
project(${PROJECT} 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/main.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} noos)
|
13
examples/host/device_info/Makefile
Normal file
13
examples/host/device_info/Makefile
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
include ../../build_system/make/make.mk
|
||||||
|
|
||||||
|
INC += \
|
||||||
|
src \
|
||||||
|
$(TOP)/hw \
|
||||||
|
|
||||||
|
# Example source
|
||||||
|
EXAMPLE_SOURCE += \
|
||||||
|
src/main.c
|
||||||
|
|
||||||
|
SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE))
|
||||||
|
|
||||||
|
include ../../build_system/make/rules.mk
|
14
examples/host/device_info/only.txt
Normal file
14
examples/host/device_info/only.txt
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
mcu:KINETIS_KL
|
||||||
|
mcu:LPC175X_6X
|
||||||
|
mcu:LPC177X_8X
|
||||||
|
mcu:LPC18XX
|
||||||
|
mcu:LPC40XX
|
||||||
|
mcu:LPC43XX
|
||||||
|
mcu:MIMXRT1XXX
|
||||||
|
mcu:MIMXRT10XX
|
||||||
|
mcu:MIMXRT11XX
|
||||||
|
mcu:RP2040
|
||||||
|
mcu:MSP432E4
|
||||||
|
mcu:RX65X
|
||||||
|
mcu:RAXXX
|
||||||
|
mcu:MAX3421
|
210
examples/host/device_info/src/main.c
Normal file
210
examples/host/device_info/src/main.c
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Host example will get device descriptors of attached devices and print it out via uart/rtt (logger) as follows:
|
||||||
|
* Device 1: ID 046d:c52f
|
||||||
|
Device Descriptor:
|
||||||
|
bLength 18
|
||||||
|
bDescriptorType 1
|
||||||
|
bcdUSB 0200
|
||||||
|
bDeviceClass 0
|
||||||
|
bDeviceSubClass 0
|
||||||
|
bDeviceProtocol 0
|
||||||
|
bMaxPacketSize0 8
|
||||||
|
idVendor 0x046d
|
||||||
|
idProduct 0xc52f
|
||||||
|
bcdDevice 2200
|
||||||
|
iManufacturer 1 Logitech
|
||||||
|
iProduct 2 USB Receiver
|
||||||
|
iSerialNumber 0
|
||||||
|
bNumConfigurations 1
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "bsp/board_api.h"
|
||||||
|
#include "tusb.h"
|
||||||
|
|
||||||
|
// English
|
||||||
|
#define LANGUAGE_ID 0x0409
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// MACRO CONSTANT TYPEDEF PROTYPES
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
void led_blinking_task(void);
|
||||||
|
static void print_utf16(uint16_t* temp_buf, size_t buf_len);
|
||||||
|
|
||||||
|
/*------------- MAIN -------------*/
|
||||||
|
int main(void) {
|
||||||
|
board_init();
|
||||||
|
|
||||||
|
printf("TinyUSB Device Info Example\r\n");
|
||||||
|
|
||||||
|
// init host stack on configured roothub port
|
||||||
|
tuh_init(BOARD_TUH_RHPORT);
|
||||||
|
|
||||||
|
if (board_init_after_tusb) {
|
||||||
|
board_init_after_tusb();
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
// tinyusb host task
|
||||||
|
tuh_task();
|
||||||
|
led_blinking_task();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------- TinyUSB Callbacks -------------*/
|
||||||
|
|
||||||
|
// Invoked when device is mounted (configured)
|
||||||
|
void tuh_mount_cb(uint8_t daddr) {
|
||||||
|
// Get Device Descriptor
|
||||||
|
tusb_desc_device_t desc_device;
|
||||||
|
uint8_t xfer_result = tuh_descriptor_get_device_sync(daddr, &desc_device, 18);
|
||||||
|
if (XFER_RESULT_SUCCESS != xfer_result) {
|
||||||
|
printf("Failed to get device descriptor\r\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t buf[256];
|
||||||
|
|
||||||
|
printf("Device %u: ID %04x:%04x\r\n", daddr, desc_device.idVendor, desc_device.idProduct);
|
||||||
|
printf("Device Descriptor:\r\n");
|
||||||
|
printf(" bLength %u\r\n", desc_device.bLength);
|
||||||
|
printf(" bDescriptorType %u\r\n", desc_device.bDescriptorType);
|
||||||
|
printf(" bcdUSB %04x\r\n", desc_device.bcdUSB);
|
||||||
|
printf(" bDeviceClass %u\r\n", desc_device.bDeviceClass);
|
||||||
|
printf(" bDeviceSubClass %u\r\n", desc_device.bDeviceSubClass);
|
||||||
|
printf(" bDeviceProtocol %u\r\n", desc_device.bDeviceProtocol);
|
||||||
|
printf(" bMaxPacketSize0 %u\r\n", desc_device.bMaxPacketSize0);
|
||||||
|
printf(" idVendor 0x%04x\r\n", desc_device.idVendor);
|
||||||
|
printf(" idProduct 0x%04x\r\n", desc_device.idProduct);
|
||||||
|
printf(" bcdDevice %04x\r\n", desc_device.bcdDevice);
|
||||||
|
|
||||||
|
// Get String descriptor using Sync API
|
||||||
|
|
||||||
|
printf(" iManufacturer %u ", desc_device.iManufacturer);
|
||||||
|
xfer_result = tuh_descriptor_get_manufacturer_string_sync(daddr, LANGUAGE_ID, buf, sizeof(buf));
|
||||||
|
if (XFER_RESULT_SUCCESS == xfer_result) {
|
||||||
|
print_utf16(buf, TU_ARRAY_SIZE(buf));
|
||||||
|
}
|
||||||
|
printf("\r\n");
|
||||||
|
|
||||||
|
printf(" iProduct %u ", desc_device.iProduct);
|
||||||
|
xfer_result = tuh_descriptor_get_product_string_sync(daddr, LANGUAGE_ID, buf, sizeof(buf));
|
||||||
|
if (XFER_RESULT_SUCCESS == xfer_result) {
|
||||||
|
print_utf16(buf, TU_ARRAY_SIZE(buf));
|
||||||
|
}
|
||||||
|
printf("\r\n");
|
||||||
|
|
||||||
|
printf(" iSerialNumber %u ", desc_device.iSerialNumber);
|
||||||
|
xfer_result = tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, buf, sizeof(buf));
|
||||||
|
if (XFER_RESULT_SUCCESS == xfer_result) {
|
||||||
|
print_utf16(buf, TU_ARRAY_SIZE(buf));
|
||||||
|
}
|
||||||
|
printf("\r\n");
|
||||||
|
|
||||||
|
printf(" bNumConfigurations %u\r\n", desc_device.bNumConfigurations);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Invoked when device is unmounted (bus reset/unplugged)
|
||||||
|
void tuh_umount_cb(uint8_t daddr) {
|
||||||
|
printf("Device removed, address = %d\r\n", daddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Blinking Task
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
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
|
||||||
|
start_ms += interval_ms;
|
||||||
|
|
||||||
|
board_led_write(led_state);
|
||||||
|
led_state = 1 - led_state; // toggle
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// String Descriptor Helper
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
static void _convert_utf16le_to_utf8(const uint16_t* utf16, size_t utf16_len, uint8_t* utf8, size_t utf8_len) {
|
||||||
|
// TODO: Check for runover.
|
||||||
|
(void) utf8_len;
|
||||||
|
// Get the UTF-16 length out of the data itself.
|
||||||
|
|
||||||
|
for (size_t i = 0; i < utf16_len; i++) {
|
||||||
|
uint16_t chr = utf16[i];
|
||||||
|
if (chr < 0x80) {
|
||||||
|
*utf8++ = chr & 0xffu;
|
||||||
|
} else if (chr < 0x800) {
|
||||||
|
*utf8++ = (uint8_t) (0xC0 | (chr >> 6 & 0x1F));
|
||||||
|
*utf8++ = (uint8_t) (0x80 | (chr >> 0 & 0x3F));
|
||||||
|
} else {
|
||||||
|
// TODO: Verify surrogate.
|
||||||
|
*utf8++ = (uint8_t) (0xE0 | (chr >> 12 & 0x0F));
|
||||||
|
*utf8++ = (uint8_t) (0x80 | (chr >> 6 & 0x3F));
|
||||||
|
*utf8++ = (uint8_t) (0x80 | (chr >> 0 & 0x3F));
|
||||||
|
}
|
||||||
|
// TODO: Handle UTF-16 code points that take two entries.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count how many bytes a utf-16-le encoded string will take in utf-8.
|
||||||
|
static int _count_utf8_bytes(const uint16_t* buf, size_t len) {
|
||||||
|
size_t total_bytes = 0;
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
uint16_t chr = buf[i];
|
||||||
|
if (chr < 0x80) {
|
||||||
|
total_bytes += 1;
|
||||||
|
} else if (chr < 0x800) {
|
||||||
|
total_bytes += 2;
|
||||||
|
} else {
|
||||||
|
total_bytes += 3;
|
||||||
|
}
|
||||||
|
// TODO: Handle UTF-16 code points that take two entries.
|
||||||
|
}
|
||||||
|
return (int) total_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_utf16(uint16_t* temp_buf, size_t buf_len) {
|
||||||
|
if ((temp_buf[0] & 0xff) == 0) return; // empty
|
||||||
|
size_t utf16_len = ((temp_buf[0] & 0xff) - 2) / sizeof(uint16_t);
|
||||||
|
size_t utf8_len = (size_t) _count_utf8_bytes(temp_buf + 1, utf16_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("%s", (char*) temp_buf);
|
||||||
|
}
|
115
examples/host/device_info/src/tusb_config.h
Normal file
115
examples/host/device_info/src/tusb_config.h
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* 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_NONE
|
||||||
|
#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
|
||||||
|
|
||||||
|
// only hub class is enabled
|
||||||
|
#define CFG_TUH_HUB 1
|
||||||
|
|
||||||
|
// max device support (excluding hub device)
|
||||||
|
// 1 hub typically has 4 ports
|
||||||
|
#define CFG_TUH_DEVICE_MAX (3*CFG_TUH_HUB + 1)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@ -253,6 +253,7 @@ bool diff_report(sony_ds4_report_t const* rpt1, sony_ds4_report_t const* rpt2)
|
|||||||
|
|
||||||
void process_sony_ds4(uint8_t const* report, uint16_t len)
|
void process_sony_ds4(uint8_t const* report, uint16_t len)
|
||||||
{
|
{
|
||||||
|
(void)len;
|
||||||
const char* dpad_str[] = { "N", "NE", "E", "SE", "S", "SW", "W", "NW", "none" };
|
const char* dpad_str[] = { "N", "NE", "E", "SE", "S", "SW", "W", "NW", "none" };
|
||||||
|
|
||||||
// previous report used to compare for changes
|
// previous report used to compare for changes
|
||||||
|
@ -24,8 +24,8 @@
|
|||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _BOARD_API_H_
|
#ifndef BOARD_API_H_
|
||||||
#define _BOARD_API_H_
|
#define BOARD_API_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -72,6 +72,9 @@ void board_init(void);
|
|||||||
// Init board after tinyusb is initialized
|
// Init board after tinyusb is initialized
|
||||||
void board_init_after_tusb(void) TU_ATTR_WEAK;
|
void board_init_after_tusb(void) TU_ATTR_WEAK;
|
||||||
|
|
||||||
|
// Jump to bootloader
|
||||||
|
void board_reset_to_bootloader(void) TU_ATTR_WEAK;
|
||||||
|
|
||||||
// Turn LED on or off
|
// Turn LED on or off
|
||||||
void board_led_write(bool state);
|
void board_led_write(bool state);
|
||||||
|
|
||||||
|
8
hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.cmake
Normal file
8
hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.cmake
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
set(LD_FLASH_SIZE 64K)
|
||||||
|
set(LD_RAM_SIZE 20K)
|
||||||
|
|
||||||
|
function(update_board TARGET)
|
||||||
|
target_compile_definitions(${TARGET} PUBLIC
|
||||||
|
CFG_EXAMPLE_MSC_DUAL_READONLY
|
||||||
|
)
|
||||||
|
endfunction()
|
@ -6,9 +6,13 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LED_PORT GPIOA
|
#define LED_PORT GPIOA
|
||||||
#define LED_PIN GPIO_Pin_15
|
#define LED_PIN GPIO_Pin_10
|
||||||
#define LED_STATE_ON 0
|
#define LED_STATE_ON 0
|
||||||
|
|
||||||
|
#define BUTTON_PORT GPIOA
|
||||||
|
#define BUTTON_PIN GPIO_Pin_1
|
||||||
|
#define BUTTON_STATE_ACTIVE 0
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
5
hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk
Normal file
5
hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
CFLAGS += -DCFG_EXAMPLE_MSC_DUAL_READONLY
|
||||||
|
|
||||||
|
LDFLAGS += \
|
||||||
|
-Wl,--defsym=__FLASH_SIZE=64K \
|
||||||
|
-Wl,--defsym=__RAM_SIZE=20K \
|
37
hw/bsp/ch32v10x/ch32v10x_conf.h
Normal file
37
hw/bsp/ch32v10x/ch32v10x_conf.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : ch32v10x_conf.h
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0.0
|
||||||
|
* Date : 2020/04/30
|
||||||
|
* 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 __CH32V10x_CONF_H
|
||||||
|
#define __CH32V10x_CONF_H
|
||||||
|
|
||||||
|
#include "ch32v10x_adc.h"
|
||||||
|
#include "ch32v10x_bkp.h"
|
||||||
|
#include "ch32v10x_crc.h"
|
||||||
|
#include "ch32v10x_dbgmcu.h"
|
||||||
|
#include "ch32v10x_dma.h"
|
||||||
|
#include "ch32v10x_exti.h"
|
||||||
|
#include "ch32v10x_flash.h"
|
||||||
|
#include "ch32v10x_gpio.h"
|
||||||
|
#include "ch32v10x_i2c.h"
|
||||||
|
#include "ch32v10x_iwdg.h"
|
||||||
|
#include "ch32v10x_pwr.h"
|
||||||
|
#include "ch32v10x_rcc.h"
|
||||||
|
#include "ch32v10x_rtc.h"
|
||||||
|
#include "ch32v10x_spi.h"
|
||||||
|
#include "ch32v10x_tim.h"
|
||||||
|
#include "ch32v10x_usart.h"
|
||||||
|
#include "ch32v10x_wwdg.h"
|
||||||
|
#include "ch32v10x_usb.h"
|
||||||
|
#include "ch32v10x_usb_host.h"
|
||||||
|
#include "ch32v10x_it.h"
|
||||||
|
#include "ch32v10x_misc.h"
|
||||||
|
|
||||||
|
#endif /* __CH32V10x_CONF_H */
|
15
hw/bsp/ch32v10x/ch32v10x_it.h
Normal file
15
hw/bsp/ch32v10x/ch32v10x_it.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : ch32v10x_it.h
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0.0
|
||||||
|
* Date : 2022/08/20
|
||||||
|
* 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 __CH32V10x_IT_H
|
||||||
|
#define __CH32V10x_IT_H
|
||||||
|
|
||||||
|
#endif /* __CH32V10x_IT_H */
|
148
hw/bsp/ch32v10x/family.c
Normal file
148
hw/bsp/ch32v10x/family.c
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
// https://github.com/openwch/ch32v307/pull/90
|
||||||
|
// https://github.com/openwch/ch32v20x/pull/12
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wstrict-prototypes"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "ch32v10x.h"
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "bsp/board_api.h"
|
||||||
|
#include "board.h"
|
||||||
|
|
||||||
|
__attribute__((interrupt)) __attribute__((used))
|
||||||
|
void USBHD_IRQHandler(void) {
|
||||||
|
#if CFG_TUD_WCH_USBIP_USBFS
|
||||||
|
tud_int_handler(0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((interrupt)) __attribute__((used))
|
||||||
|
void USBWakeUp_IRQHandler(void) {
|
||||||
|
#if CFG_TUD_WCH_USBIP_USBFS
|
||||||
|
tud_int_handler(0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
|
volatile uint32_t system_ticks = 0;
|
||||||
|
|
||||||
|
__attribute__((interrupt)) __attribute__((used))
|
||||||
|
void SysTick_Handler(void) {
|
||||||
|
SysTick->CNTL0 = SysTick->CNTL1 = SysTick->CNTL2 = SysTick->CNTL3 = 0;
|
||||||
|
SysTick->CNTH0 = SysTick->CNTH1 = SysTick->CNTH2 = SysTick->CNTH3 = 0;
|
||||||
|
system_ticks++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t SysTick_Config(uint32_t ticks) {
|
||||||
|
NVIC_EnableIRQ(SysTicK_IRQn);
|
||||||
|
SysTick->CTLR = 0;
|
||||||
|
SysTick->CNTL0 = SysTick->CNTL1 = SysTick->CNTL2 = SysTick->CNTL3 = 0;
|
||||||
|
SysTick->CNTH0 = SysTick->CNTH1 = SysTick->CNTH2 = SysTick->CNTH3 = 0;
|
||||||
|
|
||||||
|
SysTick->CMPLR0 = (u8)(ticks & 0xFF);
|
||||||
|
SysTick->CMPLR1 = (u8)(ticks >> 8);
|
||||||
|
SysTick->CMPLR2 = (u8)(ticks >> 16);
|
||||||
|
SysTick->CMPLR3 = (u8)(ticks >> 24);
|
||||||
|
|
||||||
|
SysTick->CMPHR0 = SysTick->CMPHR1 = SysTick->CMPHR2 = SysTick->CMPHR3 = 0;
|
||||||
|
SysTick->CTLR = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t board_millis(void) {
|
||||||
|
return system_ticks;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void board_init(void) {
|
||||||
|
__disable_irq();
|
||||||
|
|
||||||
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
|
SysTick_Config(SystemCoreClock / 1000);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
|
||||||
|
|
||||||
|
EXTEN->EXTEN_CTR |= EXTEN_USBFS_IO_EN;
|
||||||
|
uint8_t usb_div;
|
||||||
|
switch (SystemCoreClock) {
|
||||||
|
case 48000000: usb_div = RCC_USBCLKSource_PLLCLK_Div1; break;
|
||||||
|
case 72000000: usb_div = RCC_USBCLKSource_PLLCLK_1Div5; break;
|
||||||
|
default: TU_ASSERT(0,); break;
|
||||||
|
}
|
||||||
|
RCC_USBCLKConfig(usb_div);
|
||||||
|
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_USBFS, ENABLE);
|
||||||
|
|
||||||
|
#ifdef LED_PIN
|
||||||
|
GPIO_InitTypeDef led_init = {
|
||||||
|
.GPIO_Pin = LED_PIN,
|
||||||
|
.GPIO_Mode = GPIO_Mode_Out_OD,
|
||||||
|
.GPIO_Speed = GPIO_Speed_50MHz,
|
||||||
|
};
|
||||||
|
GPIO_Init(LED_PORT, &led_init);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BUTTON_PIN
|
||||||
|
GPIO_InitTypeDef button_init = {
|
||||||
|
.GPIO_Pin = BUTTON_PIN,
|
||||||
|
.GPIO_Mode = GPIO_Mode_IPU,
|
||||||
|
.GPIO_Speed = GPIO_Speed_50MHz,
|
||||||
|
};
|
||||||
|
GPIO_Init(BUTTON_PORT, &button_init);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// UART TX is PA9
|
||||||
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
|
||||||
|
GPIO_InitTypeDef usart_init = {
|
||||||
|
.GPIO_Pin = GPIO_Pin_9,
|
||||||
|
.GPIO_Speed = GPIO_Speed_50MHz,
|
||||||
|
.GPIO_Mode = GPIO_Mode_AF_PP,
|
||||||
|
};
|
||||||
|
GPIO_Init(GPIOA, &usart_init);
|
||||||
|
|
||||||
|
USART_InitTypeDef usart = {
|
||||||
|
.USART_BaudRate = 115200,
|
||||||
|
.USART_WordLength = USART_WordLength_8b,
|
||||||
|
.USART_StopBits = USART_StopBits_1,
|
||||||
|
.USART_Parity = USART_Parity_No,
|
||||||
|
.USART_Mode = USART_Mode_Tx,
|
||||||
|
.USART_HardwareFlowControl = USART_HardwareFlowControl_None,
|
||||||
|
};
|
||||||
|
USART_Init(USART1, &usart);
|
||||||
|
USART_Cmd(USART1, ENABLE);
|
||||||
|
|
||||||
|
__enable_irq();
|
||||||
|
|
||||||
|
board_led_write(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
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) {
|
||||||
|
const char *bufc = (const char *) buf;
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
|
||||||
|
USART_SendData(USART1, *bufc++);
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
117
hw/bsp/ch32v10x/family.cmake
Normal file
117
hw/bsp/ch32v10x/family.cmake
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
include_guard()
|
||||||
|
|
||||||
|
#set(UF2_FAMILY_ID 0x699b62ec)
|
||||||
|
set(CH32_FAMILY ch32v10x)
|
||||||
|
set(SDK_DIR ${TOP}/hw/mcu/wch/ch32v103)
|
||||||
|
set(SDK_SRC_DIR ${SDK_DIR}/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 CH32V103 CACHE INTERNAL "")
|
||||||
|
set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg")
|
||||||
|
|
||||||
|
#------------------------------------
|
||||||
|
# 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}/linker/${CH32_FAMILY}.ld)
|
||||||
|
endif ()
|
||||||
|
set(LD_FILE_Clang ${LD_FILE_GNU})
|
||||||
|
|
||||||
|
if (NOT DEFINED STARTUP_FILE_GNU)
|
||||||
|
set(STARTUP_FILE_GNU ${SDK_SRC_DIR}/Startup/startup_${CH32_FAMILY}.S)
|
||||||
|
endif ()
|
||||||
|
set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU})
|
||||||
|
|
||||||
|
add_library(${BOARD_TARGET} STATIC
|
||||||
|
${SDK_SRC_DIR}/Core/core_riscv.c
|
||||||
|
${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_gpio.c
|
||||||
|
${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_misc.c
|
||||||
|
${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_rcc.c
|
||||||
|
${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_usart.c
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_${CH32_FAMILY}.c
|
||||||
|
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||||
|
)
|
||||||
|
target_include_directories(${BOARD_TARGET} PUBLIC
|
||||||
|
${SDK_SRC_DIR}/Core
|
||||||
|
${SDK_SRC_DIR}/Peripheral/inc
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}
|
||||||
|
)
|
||||||
|
target_compile_definitions(${BOARD_TARGET} PUBLIC
|
||||||
|
)
|
||||||
|
|
||||||
|
update_board(${BOARD_TARGET})
|
||||||
|
|
||||||
|
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||||
|
target_compile_options(${BOARD_TARGET} PUBLIC
|
||||||
|
-mcmodel=medany
|
||||||
|
)
|
||||||
|
target_link_options(${BOARD_TARGET} PUBLIC
|
||||||
|
"LINKER:--script=${LD_FILE_GNU}"
|
||||||
|
-Wl,--defsym=__FLASH_SIZE=${LD_FLASH_SIZE}
|
||||||
|
-Wl,--defsym=__RAM_SIZE=${LD_RAM_SIZE}
|
||||||
|
-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_CH32V103 ${RTOS})
|
||||||
|
|
||||||
|
target_sources(${TARGET}-tinyusb PUBLIC
|
||||||
|
${TOP}/src/portable/wch/dcd_ch32_usbfs.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})
|
||||||
|
|
||||||
|
#family_add_uf2(${TARGET} ${UF2_FAMILY_ID})
|
||||||
|
#family_flash_uf2(${TARGET} ${UF2_FAMILY_ID})
|
||||||
|
endfunction()
|
53
hw/bsp/ch32v10x/family.mk
Normal file
53
hw/bsp/ch32v10x/family.mk
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
# https://www.embecosm.com/resources/tool-chain-downloads/#riscv-stable
|
||||||
|
#CROSS_COMPILE ?= riscv32-unknown-elf-
|
||||||
|
|
||||||
|
# Toolchain from https://nucleisys.com/download.php
|
||||||
|
#CROSS_COMPILE ?= riscv-nuclei-elf-
|
||||||
|
|
||||||
|
# Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack
|
||||||
|
CROSS_COMPILE ?= riscv-none-elf-
|
||||||
|
|
||||||
|
CH32_FAMILY = ch32v10x
|
||||||
|
SDK_DIR = hw/mcu/wch/ch32v103
|
||||||
|
SDK_SRC_DIR = $(SDK_DIR)/EVT/EXAM/SRC
|
||||||
|
|
||||||
|
include $(TOP)/$(BOARD_PATH)/board.mk
|
||||||
|
CPU_CORE ?= rv32imac-ilp32
|
||||||
|
|
||||||
|
# Port0 use FSDev, Port1 use USBFS
|
||||||
|
PORT ?= 0
|
||||||
|
|
||||||
|
CFLAGS += \
|
||||||
|
-mcmodel=medany \
|
||||||
|
-ffat-lto-objects \
|
||||||
|
-flto \
|
||||||
|
-DCFG_TUSB_MCU=OPT_MCU_CH32V103
|
||||||
|
|
||||||
|
# https://github.com/openwch/ch32v20x/pull/12
|
||||||
|
CFLAGS += -Wno-error=strict-prototypes
|
||||||
|
|
||||||
|
LDFLAGS_GCC += \
|
||||||
|
-nostdlib -nostartfiles \
|
||||||
|
--specs=nosys.specs --specs=nano.specs \
|
||||||
|
|
||||||
|
LD_FILE = $(FAMILY_PATH)/linker/${CH32_FAMILY}.ld
|
||||||
|
|
||||||
|
SRC_C += \
|
||||||
|
src/portable/wch/dcd_ch32_usbfs.c \
|
||||||
|
$(SDK_SRC_DIR)/Core/core_riscv.c \
|
||||||
|
$(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_gpio.c \
|
||||||
|
$(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_misc.c \
|
||||||
|
$(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_rcc.c \
|
||||||
|
$(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_usart.c \
|
||||||
|
|
||||||
|
SRC_S += $(SDK_SRC_DIR)/Startup/startup_${CH32_FAMILY}.S
|
||||||
|
|
||||||
|
INC += \
|
||||||
|
$(TOP)/$(BOARD_PATH) \
|
||||||
|
$(TOP)/$(SDK_SRC_DIR)/Core \
|
||||||
|
$(TOP)/$(SDK_SRC_DIR)/Peripheral/inc \
|
||||||
|
|
||||||
|
FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V
|
||||||
|
|
||||||
|
OPENOCD_WCH_OPTION=-f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg
|
||||||
|
flash: flash-openocd-wch
|
165
hw/bsp/ch32v10x/linker/ch32v10x.ld
Normal file
165
hw/bsp/ch32v10x/linker/ch32v10x.ld
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
/* Define default values if not already defined */
|
||||||
|
__FLASH_SIZE = DEFINED(__flash_size) ? __flash_size : 64K;
|
||||||
|
__RAM_SIZE = DEFINED(__ram_size) ? __ram_size : 20K;
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = __FLASH_SIZE
|
||||||
|
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = __RAM_SIZE
|
||||||
|
}
|
||||||
|
|
||||||
|
ENTRY( _start )
|
||||||
|
|
||||||
|
__stack_size = 2048;
|
||||||
|
|
||||||
|
PROVIDE( _stack_size = __stack_size );
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.init :
|
||||||
|
{
|
||||||
|
_sinit = .;
|
||||||
|
. = ALIGN(4);
|
||||||
|
KEEP(*(SORT_NONE(.init)))
|
||||||
|
. = ALIGN(4);
|
||||||
|
_einit = .;
|
||||||
|
} >FLASH AT>FLASH
|
||||||
|
|
||||||
|
.vector :
|
||||||
|
{
|
||||||
|
*(.vector);
|
||||||
|
. = ALIGN(64);
|
||||||
|
} >FLASH AT>FLASH
|
||||||
|
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
*(.text)
|
||||||
|
*(.text.*)
|
||||||
|
*(.rodata)
|
||||||
|
*(.rodata*)
|
||||||
|
*(.gnu.linkonce.t.*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >FLASH AT>FLASH
|
||||||
|
|
||||||
|
.fini :
|
||||||
|
{
|
||||||
|
KEEP(*(SORT_NONE(.fini)))
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >FLASH AT>FLASH
|
||||||
|
|
||||||
|
PROVIDE( _etext = . );
|
||||||
|
PROVIDE( _eitcm = . );
|
||||||
|
|
||||||
|
.preinit_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||||
|
KEEP (*(.preinit_array))
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||||
|
} >FLASH AT>FLASH
|
||||||
|
|
||||||
|
.init_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__init_array_start = .);
|
||||||
|
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
|
||||||
|
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
|
||||||
|
PROVIDE_HIDDEN (__init_array_end = .);
|
||||||
|
} >FLASH AT>FLASH
|
||||||
|
|
||||||
|
.fini_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||||
|
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
|
||||||
|
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
|
||||||
|
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||||
|
} >FLASH AT>FLASH
|
||||||
|
|
||||||
|
.ctors :
|
||||||
|
{
|
||||||
|
/* 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
|
||||||
|
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))
|
||||||
|
} >FLASH AT>FLASH
|
||||||
|
|
||||||
|
.dtors :
|
||||||
|
{
|
||||||
|
KEEP (*crtbegin.o(.dtors))
|
||||||
|
KEEP (*crtbegin?.o(.dtors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
|
||||||
|
KEEP (*(SORT(.dtors.*)))
|
||||||
|
KEEP (*(.dtors))
|
||||||
|
} >FLASH AT>FLASH
|
||||||
|
|
||||||
|
.dalign :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE(_data_vma = .);
|
||||||
|
} >RAM AT>FLASH
|
||||||
|
|
||||||
|
.dlalign :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE(_data_lma = .);
|
||||||
|
} >FLASH AT>FLASH
|
||||||
|
|
||||||
|
.data :
|
||||||
|
{
|
||||||
|
*(.gnu.linkonce.r.*)
|
||||||
|
*(.data .data.*)
|
||||||
|
*(.gnu.linkonce.d.*)
|
||||||
|
. = ALIGN(8);
|
||||||
|
PROVIDE( __global_pointer$ = . + 0x800 );
|
||||||
|
*(.sdata .sdata.*)
|
||||||
|
*(.sdata2.*)
|
||||||
|
*(.gnu.linkonce.s.*)
|
||||||
|
. = ALIGN(8);
|
||||||
|
*(.srodata.cst16)
|
||||||
|
*(.srodata.cst8)
|
||||||
|
*(.srodata.cst4)
|
||||||
|
*(.srodata.cst2)
|
||||||
|
*(.srodata .srodata.*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE( _edata = .);
|
||||||
|
} >RAM AT>FLASH
|
||||||
|
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE( _sbss = .);
|
||||||
|
*(.sbss*)
|
||||||
|
*(.gnu.linkonce.sb.*)
|
||||||
|
*(.bss*)
|
||||||
|
*(.gnu.linkonce.b.*)
|
||||||
|
*(COMMON*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE( _ebss = .);
|
||||||
|
} >RAM AT>FLASH
|
||||||
|
|
||||||
|
PROVIDE( _end = _ebss);
|
||||||
|
PROVIDE( end = . );
|
||||||
|
|
||||||
|
.stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size :
|
||||||
|
{
|
||||||
|
PROVIDE( _heap_end = . );
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE(_susrstack = . );
|
||||||
|
. = . + __stack_size;
|
||||||
|
PROVIDE( _eusrstack = .);
|
||||||
|
} >RAM
|
||||||
|
|
||||||
|
}
|
600
hw/bsp/ch32v10x/system_ch32v10x.c
Normal file
600
hw/bsp/ch32v10x/system_ch32v10x.c
Normal file
@ -0,0 +1,600 @@
|
|||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : system_ch32v10x.c
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0.0
|
||||||
|
* Date : 2020/04/30
|
||||||
|
* Description : CH32V10x Device Peripheral Access Layer System Source 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.
|
||||||
|
*******************************************************************************/
|
||||||
|
#include "ch32v10x.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_HSI HSI_VALUE
|
||||||
|
//#define SYSCLK_FREQ_48MHz_HSI 48000000
|
||||||
|
//#define SYSCLK_FREQ_56MHz_HSI 56000000
|
||||||
|
//#define SYSCLK_FREQ_72MHz_HSI 72000000
|
||||||
|
|
||||||
|
/* 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_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) */
|
||||||
|
#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};
|
||||||
|
|
||||||
|
/* ch32v10x_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_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 );
|
||||||
|
|
||||||
|
#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;
|
||||||
|
RCC->CFGR0 &= (uint32_t)0xF8FF0000;
|
||||||
|
RCC->CTLR &= (uint32_t)0xFEF6FFFF;
|
||||||
|
RCC->CTLR &= (uint32_t)0xFFFBFFFF;
|
||||||
|
RCC->CFGR0 &= (uint32_t)0xFF80FFFF;
|
||||||
|
RCC->INTR = 0x009F0000;
|
||||||
|
SetSysClock();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* @fn SystemCoreClockUpdate
|
||||||
|
*
|
||||||
|
* @brief Update SystemCoreClock variable according to Clock Register Values.
|
||||||
|
*
|
||||||
|
* @return none
|
||||||
|
*/
|
||||||
|
void SystemCoreClockUpdate(void)
|
||||||
|
{
|
||||||
|
uint32_t tmp = 0, pllmull = 0, pllsource = 0;
|
||||||
|
|
||||||
|
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(pllsource == 0x00)
|
||||||
|
{
|
||||||
|
if( EXTEN->EXTEN_CTR & EXTEN_PLL_HSI_PRE )
|
||||||
|
{
|
||||||
|
SystemCoreClock = ( HSI_VALUE ) * pllmull;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SystemCoreClock = ( HSI_VALUE >> 1 ) * pllmull;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if((RCC->CFGR0 & RCC_PLLXTPRE) != (uint32_t)RESET)
|
||||||
|
{
|
||||||
|
SystemCoreClock = (HSE_VALUE >> 1) * pllmull;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SystemCoreClock = HSE_VALUE * pllmull;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
//GPIO_IPD_Unused();
|
||||||
|
#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_48MHz_HSI
|
||||||
|
SetSysClockTo48_HSI();
|
||||||
|
#elif defined SYSCLK_FREQ_56MHz_HSI
|
||||||
|
SetSysClockTo56_HSI();
|
||||||
|
#elif defined SYSCLK_FREQ_72MHz_HSI
|
||||||
|
SetSysClockTo72_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)
|
||||||
|
{
|
||||||
|
FLASH->ACTLR |= FLASH_ACTLR_PRFTBE;
|
||||||
|
/* Flash 0 wait state */
|
||||||
|
FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY);
|
||||||
|
FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_0;
|
||||||
|
|
||||||
|
/* 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 */
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
/* Enable Prefetch Buffer */
|
||||||
|
FLASH->ACTLR |= FLASH_ACTLR_PRFTBE;
|
||||||
|
|
||||||
|
/* Flash 1 wait state */
|
||||||
|
FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY);
|
||||||
|
FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_1;
|
||||||
|
|
||||||
|
/* 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 = HSE * 6 = 48 MHz */
|
||||||
|
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||||
|
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLMULL6);
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
{
|
||||||
|
/* Enable Prefetch Buffer */
|
||||||
|
FLASH->ACTLR |= FLASH_ACTLR_PRFTBE;
|
||||||
|
|
||||||
|
/* Flash 2 wait state */
|
||||||
|
FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY);
|
||||||
|
FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_2;
|
||||||
|
|
||||||
|
/* 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 = HSE * 7 = 56 MHz */
|
||||||
|
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||||
|
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLMULL7);
|
||||||
|
/* 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)
|
||||||
|
{
|
||||||
|
/* Enable Prefetch Buffer */
|
||||||
|
FLASH->ACTLR |= FLASH_ACTLR_PRFTBE;
|
||||||
|
|
||||||
|
/* Flash 2 wait state */
|
||||||
|
FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY);
|
||||||
|
FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_2;
|
||||||
|
|
||||||
|
/* 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 = HSE * 9 = 72 MHz */
|
||||||
|
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||||
|
RCC_PLLMULL));
|
||||||
|
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLMULL9);
|
||||||
|
/* 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;
|
||||||
|
|
||||||
|
/* Enable Prefetch Buffer */
|
||||||
|
FLASH->ACTLR |= FLASH_ACTLR_PRFTBE;
|
||||||
|
|
||||||
|
/* Flash 1 wait state */
|
||||||
|
FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY);
|
||||||
|
FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_1;
|
||||||
|
|
||||||
|
/* 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));
|
||||||
|
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL6);
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
|
||||||
|
/* Enable Prefetch Buffer */
|
||||||
|
FLASH->ACTLR |= FLASH_ACTLR_PRFTBE;
|
||||||
|
|
||||||
|
/* Flash 1 wait state */
|
||||||
|
FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY);
|
||||||
|
FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_1;
|
||||||
|
|
||||||
|
/* 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));
|
||||||
|
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL7);
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
|
||||||
|
/* Enable Prefetch Buffer */
|
||||||
|
FLASH->ACTLR |= FLASH_ACTLR_PRFTBE;
|
||||||
|
|
||||||
|
/* Flash 1 wait state */
|
||||||
|
FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY);
|
||||||
|
FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_1;
|
||||||
|
|
||||||
|
/* 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));
|
||||||
|
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL9);
|
||||||
|
|
||||||
|
/* 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
|
29
hw/bsp/ch32v10x/system_ch32v10x.h
Normal file
29
hw/bsp/ch32v10x/system_ch32v10x.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/********************************** (C) COPYRIGHT *******************************
|
||||||
|
* File Name : system_ch32v10x.h
|
||||||
|
* Author : WCH
|
||||||
|
* Version : V1.0.0
|
||||||
|
* Date : 2020/04/30
|
||||||
|
* Description : CH32V10x Device Peripheral Access Layer System Header 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 __SYSTEM_CH32V10x_H
|
||||||
|
#define __SYSTEM_CH32V10x_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 /*__CH32V10x_SYSTEM_H */
|
17
hw/bsp/ch32v10x/wch-riscv.cfg
Normal file
17
hw/bsp/ch32v10x/wch-riscv.cfg
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
adapter driver wlinke
|
||||||
|
adapter speed 6000
|
||||||
|
transport select sdi
|
||||||
|
|
||||||
|
wlink_set_address 0x00000000
|
||||||
|
set _CHIPNAME wch_riscv
|
||||||
|
sdi newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00001
|
||||||
|
|
||||||
|
set _TARGETNAME $_CHIPNAME.cpu
|
||||||
|
|
||||||
|
target create $_TARGETNAME.0 wch_riscv -chain-position $_TARGETNAME
|
||||||
|
$_TARGETNAME.0 configure -work-area-phys 0x20000000 -work-area-size 10000 -work-area-backup 1
|
||||||
|
set _FLASHNAME $_CHIPNAME.flash
|
||||||
|
|
||||||
|
flash bank $_FLASHNAME wch_riscv 0x00000000 0 0 0 $_TARGETNAME.0
|
||||||
|
|
||||||
|
echo "Ready for Remote Connections"
|
@ -1,7 +0,0 @@
|
|||||||
MCU_VARIANT = D6
|
|
||||||
|
|
||||||
CFLAGS += -DCFG_EXAMPLE_MSC_DUAL_READONLY
|
|
||||||
|
|
||||||
LDFLAGS += \
|
|
||||||
-Wl,--defsym=__flash_size=64K \
|
|
||||||
-Wl,--defsym=__ram_size=20K \
|
|
@ -1,12 +1,15 @@
|
|||||||
set(MCU_VARIANT D6)
|
set(MCU_VARIANT D6)
|
||||||
|
|
||||||
set(LD_FLASH_SIZE 64K)
|
# 64KB zero-wait, 224KB total flash
|
||||||
|
#set(LD_FLASH_SIZE 64K)
|
||||||
|
set(LD_FLASH_SIZE 224K)
|
||||||
set(LD_RAM_SIZE 20K)
|
set(LD_RAM_SIZE 20K)
|
||||||
|
|
||||||
# set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/${CH32_FAMILY}_tinyuf2.ld)
|
# set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/${CH32_FAMILY}_tinyuf2.ld)
|
||||||
|
|
||||||
function(update_board TARGET)
|
function(update_board TARGET)
|
||||||
target_compile_definitions(${TARGET} PUBLIC
|
target_compile_definitions(${TARGET} PUBLIC
|
||||||
|
SYSCLK_FREQ_144MHz_HSE=144000000
|
||||||
CFG_EXAMPLE_MSC_DUAL_READONLY
|
CFG_EXAMPLE_MSC_DUAL_READONLY
|
||||||
)
|
)
|
||||||
endfunction()
|
endfunction()
|
21
hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.h
Normal file
21
hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#ifndef BOARD_H_
|
||||||
|
#define BOARD_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LED_PORT GPIOA
|
||||||
|
#define LED_PIN GPIO_Pin_0
|
||||||
|
#define LED_STATE_ON 0
|
||||||
|
|
||||||
|
#define UART_DEV USART1
|
||||||
|
#define UART_CLOCK_EN() RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE)
|
||||||
|
#define UART_TX_PIN GPIO_Pin_9
|
||||||
|
#define UART_RX_PIN GPIO_Pin_10
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
11
hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.mk
Normal file
11
hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.mk
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
MCU_VARIANT = D6
|
||||||
|
|
||||||
|
CFLAGS += \
|
||||||
|
-DSYSCLK_FREQ_144MHz_HSE=144000000 \
|
||||||
|
-DCH32_FLASH_ENHANCE_READ_MODE=1 \
|
||||||
|
-DCFG_EXAMPLE_MSC_DUAL_READONLY \
|
||||||
|
|
||||||
|
# 64KB zero-wait, 224KB total flash
|
||||||
|
LDFLAGS += \
|
||||||
|
-Wl,--defsym=__FLASH_SIZE=224K \
|
||||||
|
-Wl,--defsym=__RAM_SIZE=20K \
|
13
hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.cmake
Normal file
13
hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.cmake
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
set(MCU_VARIANT D6)
|
||||||
|
|
||||||
|
# 32KB zero-wait, 224KB total flash
|
||||||
|
#set(LD_FLASH_SIZE 32K)
|
||||||
|
set(LD_FLASH_SIZE 224K)
|
||||||
|
set(LD_RAM_SIZE 10K)
|
||||||
|
|
||||||
|
function(update_board TARGET)
|
||||||
|
target_compile_definitions(${TARGET} PUBLIC
|
||||||
|
SYSCLK_FREQ_144MHz_HSI=144000000
|
||||||
|
CFG_EXAMPLE_MSC_DUAL_READONLY
|
||||||
|
)
|
||||||
|
endfunction()
|
21
hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.h
Normal file
21
hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#ifndef BOARD_H_
|
||||||
|
#define BOARD_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LED_PORT GPIOA
|
||||||
|
#define LED_PIN GPIO_Pin_0
|
||||||
|
#define LED_STATE_ON 0
|
||||||
|
|
||||||
|
#define UART_DEV USART2
|
||||||
|
#define UART_CLOCK_EN() RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE)
|
||||||
|
#define UART_TX_PIN GPIO_Pin_2
|
||||||
|
#define UART_RX_PIN GPIO_Pin_3
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
11
hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.mk
Normal file
11
hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.mk
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
MCU_VARIANT = D6
|
||||||
|
|
||||||
|
CFLAGS += \
|
||||||
|
-DSYSCLK_FREQ_144MHz_HSI=144000000 \
|
||||||
|
-DCH32_FLASH_ENHANCE_READ_MODE=1 \
|
||||||
|
-DCFG_EXAMPLE_MSC_DUAL_READONLY \
|
||||||
|
|
||||||
|
# 32KB zero-wait, 224KB total flash
|
||||||
|
LDFLAGS += \
|
||||||
|
-Wl,--defsym=__FLASH_SIZE=224K \
|
||||||
|
-Wl,--defsym=__RAM_SIZE=10K \
|
@ -1,10 +1,13 @@
|
|||||||
set(MCU_VARIANT D6)
|
set(MCU_VARIANT D6)
|
||||||
|
|
||||||
|
# 64KB zero-wait, 224KB total flash
|
||||||
set(LD_FLASH_SIZE 64K)
|
set(LD_FLASH_SIZE 64K)
|
||||||
|
#set(LD_FLASH_SIZE 224K)
|
||||||
set(LD_RAM_SIZE 20K)
|
set(LD_RAM_SIZE 20K)
|
||||||
|
|
||||||
function(update_board TARGET)
|
function(update_board TARGET)
|
||||||
target_compile_definitions(${TARGET} PUBLIC
|
target_compile_definitions(${TARGET} PUBLIC
|
||||||
|
SYSCLK_FREQ_144MHz_HSE=144000000
|
||||||
CFG_EXAMPLE_MSC_DUAL_READONLY
|
CFG_EXAMPLE_MSC_DUAL_READONLY
|
||||||
)
|
)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
@ -8,7 +8,11 @@ extern "C" {
|
|||||||
#define LED_PORT GPIOA
|
#define LED_PORT GPIOA
|
||||||
#define LED_PIN GPIO_Pin_15
|
#define LED_PIN GPIO_Pin_15
|
||||||
#define LED_STATE_ON 0
|
#define LED_STATE_ON 0
|
||||||
#define LED_CLOCK_EN() RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE)
|
|
||||||
|
#define UART_DEV USART1
|
||||||
|
#define UART_CLOCK_EN() RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE)
|
||||||
|
#define UART_TX_PIN GPIO_Pin_9
|
||||||
|
#define UART_RX_PIN GPIO_Pin_10
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
MCU_VARIANT = D6
|
MCU_VARIANT = D6
|
||||||
|
|
||||||
CFLAGS += -DCFG_EXAMPLE_MSC_DUAL_READONLY
|
CFLAGS += \
|
||||||
|
-DSYSCLK_FREQ_144MHz_HSE=144000000 \
|
||||||
|
-DCH32_FLASH_ENHANCE_READ_MODE=1 \
|
||||||
|
-DCFG_EXAMPLE_MSC_DUAL_READONLY \
|
||||||
|
|
||||||
|
# 64KB zero-wait , 224KB total flash
|
||||||
LDFLAGS += \
|
LDFLAGS += \
|
||||||
-Wl,--defsym=__flash_size=64K \
|
-Wl,--defsym=__FLASH_SIZE=224K \
|
||||||
-Wl,--defsym=__ram_size=20K \
|
-Wl,--defsym=__RAM_SIZE=20K \
|
||||||
|
@ -1,572 +0,0 @@
|
|||||||
/********************************** (C) COPYRIGHT *******************************
|
|
||||||
* File Name : core_riscv.h
|
|
||||||
* Author : WCH
|
|
||||||
* Version : V1.0.0
|
|
||||||
* Date : 2021/06/06
|
|
||||||
* Description : RISC-V Core Peripheral Access Layer Header File for CH32V20x
|
|
||||||
*********************************************************************************
|
|
||||||
* 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 __CORE_RISCV_H__
|
|
||||||
#define __CORE_RISCV_H__
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* IO definitions */
|
|
||||||
#ifdef __cplusplus
|
|
||||||
#define __I volatile /* defines 'read only' permissions */
|
|
||||||
#else
|
|
||||||
#define __I volatile const /* defines 'read only' permissions */
|
|
||||||
#endif
|
|
||||||
#define __O volatile /* defines 'write only' permissions */
|
|
||||||
#define __IO volatile /* defines 'read / write' permissions */
|
|
||||||
|
|
||||||
/* Standard Peripheral Library old types (maintained for legacy purpose) */
|
|
||||||
typedef __I uint64_t vuc64; /* Read Only */
|
|
||||||
typedef __I uint32_t vuc32; /* Read Only */
|
|
||||||
typedef __I uint16_t vuc16; /* Read Only */
|
|
||||||
typedef __I uint8_t vuc8; /* Read Only */
|
|
||||||
|
|
||||||
typedef const uint64_t uc64; /* Read Only */
|
|
||||||
typedef const uint32_t uc32; /* Read Only */
|
|
||||||
typedef const uint16_t uc16; /* Read Only */
|
|
||||||
typedef const uint8_t uc8; /* Read Only */
|
|
||||||
|
|
||||||
typedef __I int64_t vsc64; /* Read Only */
|
|
||||||
typedef __I int32_t vsc32; /* Read Only */
|
|
||||||
typedef __I int16_t vsc16; /* Read Only */
|
|
||||||
typedef __I int8_t vsc8; /* Read Only */
|
|
||||||
|
|
||||||
typedef const int64_t sc64; /* Read Only */
|
|
||||||
typedef const int32_t sc32; /* Read Only */
|
|
||||||
typedef const int16_t sc16; /* Read Only */
|
|
||||||
typedef const int8_t sc8; /* Read Only */
|
|
||||||
|
|
||||||
typedef __IO uint64_t vu64;
|
|
||||||
typedef __IO uint32_t vu32;
|
|
||||||
typedef __IO uint16_t vu16;
|
|
||||||
typedef __IO uint8_t vu8;
|
|
||||||
|
|
||||||
typedef uint64_t u64;
|
|
||||||
typedef uint32_t u32;
|
|
||||||
typedef uint16_t u16;
|
|
||||||
typedef uint8_t u8;
|
|
||||||
|
|
||||||
typedef __IO int64_t vs64;
|
|
||||||
typedef __IO int32_t vs32;
|
|
||||||
typedef __IO int16_t vs16;
|
|
||||||
typedef __IO int8_t vs8;
|
|
||||||
|
|
||||||
typedef int64_t s64;
|
|
||||||
typedef int32_t s32;
|
|
||||||
typedef int16_t s16;
|
|
||||||
typedef int8_t s8;
|
|
||||||
|
|
||||||
typedef enum {NoREADY = 0, READY = !NoREADY} ErrorStatus;
|
|
||||||
|
|
||||||
typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
|
|
||||||
|
|
||||||
typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;
|
|
||||||
|
|
||||||
#define RV_STATIC_INLINE static inline
|
|
||||||
|
|
||||||
/* memory mapped structure for Program Fast Interrupt Controller (PFIC) */
|
|
||||||
typedef struct{
|
|
||||||
__I uint32_t ISR[8];
|
|
||||||
__I uint32_t IPR[8];
|
|
||||||
__IO uint32_t ITHRESDR;
|
|
||||||
__IO uint32_t RESERVED;
|
|
||||||
__IO uint32_t CFGR;
|
|
||||||
__I uint32_t GISR;
|
|
||||||
__IO uint8_t VTFIDR[4];
|
|
||||||
uint8_t RESERVED0[12];
|
|
||||||
__IO uint32_t VTFADDR[4];
|
|
||||||
uint8_t RESERVED1[0x90];
|
|
||||||
__O uint32_t IENR[8];
|
|
||||||
uint8_t RESERVED2[0x60];
|
|
||||||
__O uint32_t IRER[8];
|
|
||||||
uint8_t RESERVED3[0x60];
|
|
||||||
__O uint32_t IPSR[8];
|
|
||||||
uint8_t RESERVED4[0x60];
|
|
||||||
__O uint32_t IPRR[8];
|
|
||||||
uint8_t RESERVED5[0x60];
|
|
||||||
__IO uint32_t IACTR[8];
|
|
||||||
uint8_t RESERVED6[0xE0];
|
|
||||||
__IO uint8_t IPRIOR[256];
|
|
||||||
uint8_t RESERVED7[0x810];
|
|
||||||
__IO uint32_t SCTLR;
|
|
||||||
}PFIC_Type;
|
|
||||||
|
|
||||||
/* memory mapped structure for SysTick */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
__IO uint32_t CTLR;
|
|
||||||
__IO uint32_t SR;
|
|
||||||
__IO uint64_t CNT;
|
|
||||||
__IO uint64_t CMP;
|
|
||||||
}SysTick_Type;
|
|
||||||
|
|
||||||
#define PFIC ((PFIC_Type *) 0xE000E000 )
|
|
||||||
#define NVIC PFIC
|
|
||||||
#define NVIC_KEY1 ((uint32_t)0xFA050000)
|
|
||||||
#define NVIC_KEY2 ((uint32_t)0xBCAF0000)
|
|
||||||
#define NVIC_KEY3 ((uint32_t)0xBEEF0000)
|
|
||||||
|
|
||||||
#define SysTick ((SysTick_Type *) 0xE000F000)
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn __enable_irq
|
|
||||||
*
|
|
||||||
* @brief Enable Global Interrupt
|
|
||||||
*
|
|
||||||
* @return none
|
|
||||||
*/
|
|
||||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __enable_irq(void)
|
|
||||||
{
|
|
||||||
__asm volatile ("csrw 0x800, %0" : : "r" (0x6088) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn __disable_irq
|
|
||||||
*
|
|
||||||
* @brief Disable Global Interrupt
|
|
||||||
*
|
|
||||||
* @return none
|
|
||||||
*/
|
|
||||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __disable_irq(void)
|
|
||||||
{
|
|
||||||
__asm volatile ("csrw 0x800, %0" : : "r" (0x6000) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn __NOP
|
|
||||||
*
|
|
||||||
* @brief nop
|
|
||||||
*
|
|
||||||
* @return none
|
|
||||||
*/
|
|
||||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __NOP(void)
|
|
||||||
{
|
|
||||||
__asm volatile ("nop");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn NVIC_EnableIRQ
|
|
||||||
*
|
|
||||||
* @brief Disable Interrupt
|
|
||||||
*
|
|
||||||
* @param IRQn - Interrupt Numbers
|
|
||||||
*
|
|
||||||
* @return none
|
|
||||||
*/
|
|
||||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
|
|
||||||
{
|
|
||||||
NVIC->IENR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn NVIC_DisableIRQ
|
|
||||||
*
|
|
||||||
* @brief Disable Interrupt
|
|
||||||
*
|
|
||||||
* @param IRQn - Interrupt Numbers
|
|
||||||
*
|
|
||||||
* @return none
|
|
||||||
*/
|
|
||||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
|
|
||||||
{
|
|
||||||
NVIC->IRER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn NVIC_GetStatusIRQ
|
|
||||||
*
|
|
||||||
* @brief Get Interrupt Enable State
|
|
||||||
*
|
|
||||||
* @param IRQn - Interrupt Numbers
|
|
||||||
*
|
|
||||||
* @return 1 - Interrupt Pending Enable
|
|
||||||
* 0 - Interrupt Pending Disable
|
|
||||||
*/
|
|
||||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetStatusIRQ(IRQn_Type IRQn)
|
|
||||||
{
|
|
||||||
return((uint32_t) ((NVIC->ISR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn NVIC_GetPendingIRQ
|
|
||||||
*
|
|
||||||
* @brief Get Interrupt Pending State
|
|
||||||
*
|
|
||||||
* @param IRQn - Interrupt Numbers
|
|
||||||
*
|
|
||||||
* @return 1 - Interrupt Pending Enable
|
|
||||||
* 0 - Interrupt Pending Disable
|
|
||||||
*/
|
|
||||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
|
|
||||||
{
|
|
||||||
return((uint32_t) ((NVIC->IPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn NVIC_SetPendingIRQ
|
|
||||||
*
|
|
||||||
* @brief Set Interrupt Pending
|
|
||||||
*
|
|
||||||
* @param IRQn - Interrupt Numbers
|
|
||||||
*
|
|
||||||
* @return none
|
|
||||||
*/
|
|
||||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
|
|
||||||
{
|
|
||||||
NVIC->IPSR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn NVIC_ClearPendingIRQ
|
|
||||||
*
|
|
||||||
* @brief Clear Interrupt Pending
|
|
||||||
*
|
|
||||||
* @param IRQn - Interrupt Numbers
|
|
||||||
*
|
|
||||||
* @return none
|
|
||||||
*/
|
|
||||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
|
|
||||||
{
|
|
||||||
NVIC->IPRR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn NVIC_GetActive
|
|
||||||
*
|
|
||||||
* @brief Get Interrupt Active State
|
|
||||||
*
|
|
||||||
* @param IRQn - Interrupt Numbers
|
|
||||||
*
|
|
||||||
* @return 1 - Interrupt Active
|
|
||||||
* 0 - Interrupt No Active
|
|
||||||
*/
|
|
||||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
|
|
||||||
{
|
|
||||||
return((uint32_t)((NVIC->IACTR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn NVIC_SetPriority
|
|
||||||
*
|
|
||||||
* @brief Set Interrupt Priority
|
|
||||||
*
|
|
||||||
* @param IRQn - Interrupt Numbers
|
|
||||||
* priority - bit7 - Pre-emption Priority
|
|
||||||
* bit[6:5] - Subpriority
|
|
||||||
*
|
|
||||||
* @return none
|
|
||||||
*/
|
|
||||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint8_t priority)
|
|
||||||
{
|
|
||||||
NVIC->IPRIOR[(uint32_t)(IRQn)] = priority;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn __WFI
|
|
||||||
*
|
|
||||||
* @brief Wait for Interrupt
|
|
||||||
*
|
|
||||||
* @return none
|
|
||||||
*/
|
|
||||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFI(void)
|
|
||||||
{
|
|
||||||
NVIC->SCTLR &= ~(1<<3); // wfi
|
|
||||||
asm volatile ("wfi");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn _SEV
|
|
||||||
*
|
|
||||||
* @brief Set Event
|
|
||||||
*
|
|
||||||
* @return none
|
|
||||||
*/
|
|
||||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void _SEV(void)
|
|
||||||
{
|
|
||||||
uint32_t t;
|
|
||||||
|
|
||||||
t = NVIC->SCTLR;
|
|
||||||
NVIC->SCTLR |= (1<<3)|(1<<5);
|
|
||||||
NVIC->SCTLR = (NVIC->SCTLR & ~(1<<5)) | ( t & (1<<5));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn _WFE
|
|
||||||
*
|
|
||||||
* @brief Wait for Events
|
|
||||||
*
|
|
||||||
* @return none
|
|
||||||
*/
|
|
||||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void _WFE(void)
|
|
||||||
{
|
|
||||||
NVIC->SCTLR |= (1<<3);
|
|
||||||
asm volatile ("wfi");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn __WFE
|
|
||||||
*
|
|
||||||
* @brief Wait for Events
|
|
||||||
*
|
|
||||||
* @return none
|
|
||||||
*/
|
|
||||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFE(void)
|
|
||||||
{
|
|
||||||
_SEV();
|
|
||||||
_WFE();
|
|
||||||
_WFE();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn SetVTFIRQ
|
|
||||||
*
|
|
||||||
* @brief Set VTF Interrupt
|
|
||||||
*
|
|
||||||
* @param addr - VTF interrupt service function base address.
|
|
||||||
* IRQn - Interrupt Numbers
|
|
||||||
* num - VTF Interrupt Numbers
|
|
||||||
* NewState - DISABLE or ENABLE
|
|
||||||
*
|
|
||||||
* @return none
|
|
||||||
*/
|
|
||||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void SetVTFIRQ(uint32_t addr, IRQn_Type IRQn, uint8_t num, FunctionalState NewState){
|
|
||||||
if(num > 3) return ;
|
|
||||||
|
|
||||||
if (NewState != DISABLE)
|
|
||||||
{
|
|
||||||
NVIC->VTFIDR[num] = IRQn;
|
|
||||||
NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)|0x1);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
NVIC->VTFIDR[num] = IRQn;
|
|
||||||
NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)&(~0x1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn NVIC_SystemReset
|
|
||||||
*
|
|
||||||
* @brief Initiate a system reset request
|
|
||||||
*
|
|
||||||
* @return none
|
|
||||||
*/
|
|
||||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_SystemReset(void)
|
|
||||||
{
|
|
||||||
NVIC->CFGR = NVIC_KEY3|(1<<7);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn __AMOADD_W
|
|
||||||
*
|
|
||||||
* @brief Atomic Add with 32bit value
|
|
||||||
* Atomically ADD 32bit value with value in memory using amoadd.d.
|
|
||||||
*
|
|
||||||
* @param addr - Address pointer to data, address need to be 4byte aligned
|
|
||||||
* value - value to be ADDed
|
|
||||||
*
|
|
||||||
* @return return memory value + add value
|
|
||||||
*/
|
|
||||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOADD_W(volatile int32_t *addr, int32_t value)
|
|
||||||
{
|
|
||||||
int32_t result;
|
|
||||||
|
|
||||||
__asm volatile ("amoadd.w %0, %2, %1" : \
|
|
||||||
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
|
|
||||||
return *addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn __AMOAND_W
|
|
||||||
*
|
|
||||||
* @brief Atomic And with 32bit value
|
|
||||||
* Atomically AND 32bit value with value in memory using amoand.d.
|
|
||||||
*
|
|
||||||
* @param addr - Address pointer to data, address need to be 4byte aligned
|
|
||||||
* value - value to be ANDed
|
|
||||||
*
|
|
||||||
* @return return memory value & and value
|
|
||||||
*/
|
|
||||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOAND_W(volatile int32_t *addr, int32_t value)
|
|
||||||
{
|
|
||||||
int32_t result;
|
|
||||||
|
|
||||||
__asm volatile ("amoand.w %0, %2, %1" : \
|
|
||||||
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
|
|
||||||
return *addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn __AMOMAX_W
|
|
||||||
*
|
|
||||||
* @brief Atomic signed MAX with 32bit value
|
|
||||||
* Atomically signed max compare 32bit value with value in memory using amomax.d.
|
|
||||||
*
|
|
||||||
* @param addr - Address pointer to data, address need to be 4byte aligned
|
|
||||||
* value - value to be compared
|
|
||||||
*
|
|
||||||
* @return the bigger value
|
|
||||||
*/
|
|
||||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOMAX_W(volatile int32_t *addr, int32_t value)
|
|
||||||
{
|
|
||||||
int32_t result;
|
|
||||||
|
|
||||||
__asm volatile ("amomax.w %0, %2, %1" : \
|
|
||||||
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
|
|
||||||
return *addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn __AMOMAXU_W
|
|
||||||
*
|
|
||||||
* @brief Atomic unsigned MAX with 32bit value
|
|
||||||
* Atomically unsigned max compare 32bit value with value in memory using amomaxu.d.
|
|
||||||
*
|
|
||||||
* @param addr - Address pointer to data, address need to be 4byte aligned
|
|
||||||
* value - value to be compared
|
|
||||||
*
|
|
||||||
* @return return the bigger value
|
|
||||||
*/
|
|
||||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __AMOMAXU_W(volatile uint32_t *addr, uint32_t value)
|
|
||||||
{
|
|
||||||
uint32_t result;
|
|
||||||
|
|
||||||
__asm volatile ("amomaxu.w %0, %2, %1" : \
|
|
||||||
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
|
|
||||||
return *addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn __AMOMIN_W
|
|
||||||
*
|
|
||||||
* @brief Atomic signed MIN with 32bit value
|
|
||||||
* Atomically signed min compare 32bit value with value in memory using amomin.d.
|
|
||||||
*
|
|
||||||
* @param addr - Address pointer to data, address need to be 4byte aligned
|
|
||||||
* value - value to be compared
|
|
||||||
*
|
|
||||||
* @return the smaller value
|
|
||||||
*/
|
|
||||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOMIN_W(volatile int32_t *addr, int32_t value)
|
|
||||||
{
|
|
||||||
int32_t result;
|
|
||||||
|
|
||||||
__asm volatile ("amomin.w %0, %2, %1" : \
|
|
||||||
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
|
|
||||||
return *addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn __AMOMINU_W
|
|
||||||
*
|
|
||||||
* @brief Atomic unsigned MIN with 32bit value
|
|
||||||
* Atomically unsigned min compare 32bit value with value in memory using amominu.d.
|
|
||||||
*
|
|
||||||
* @param addr - Address pointer to data, address need to be 4byte aligned
|
|
||||||
* value - value to be compared
|
|
||||||
*
|
|
||||||
* @return the smaller value
|
|
||||||
*/
|
|
||||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __AMOMINU_W(volatile uint32_t *addr, uint32_t value)
|
|
||||||
{
|
|
||||||
uint32_t result;
|
|
||||||
|
|
||||||
__asm volatile ("amominu.w %0, %2, %1" : \
|
|
||||||
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
|
|
||||||
return *addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn __AMOOR_W
|
|
||||||
*
|
|
||||||
* @brief Atomic OR with 32bit value
|
|
||||||
* Atomically OR 32bit value with value in memory using amoor.d.
|
|
||||||
*
|
|
||||||
* @param addr - Address pointer to data, address need to be 4byte aligned
|
|
||||||
* value - value to be ORed
|
|
||||||
*
|
|
||||||
* @return return memory value | and value
|
|
||||||
*/
|
|
||||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOOR_W(volatile int32_t *addr, int32_t value)
|
|
||||||
{
|
|
||||||
int32_t result;
|
|
||||||
|
|
||||||
__asm volatile ("amoor.w %0, %2, %1" : \
|
|
||||||
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
|
|
||||||
return *addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn __AMOSWAP_W
|
|
||||||
*
|
|
||||||
* @brief Atomically swap new 32bit value into memory using amoswap.d.
|
|
||||||
*
|
|
||||||
* @param addr - Address pointer to data, address need to be 4byte aligned
|
|
||||||
* newval - New value to be stored into the address
|
|
||||||
*
|
|
||||||
* @return return the original value in memory
|
|
||||||
*/
|
|
||||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __AMOSWAP_W(volatile uint32_t *addr, uint32_t newval)
|
|
||||||
{
|
|
||||||
uint32_t result;
|
|
||||||
|
|
||||||
__asm volatile ("amoswap.w %0, %2, %1" : \
|
|
||||||
"=r"(result), "+A"(*addr) : "r"(newval) : "memory");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn __AMOXOR_W
|
|
||||||
*
|
|
||||||
* @brief Atomic XOR with 32bit value
|
|
||||||
* Atomically XOR 32bit value with value in memory using amoxor.d.
|
|
||||||
*
|
|
||||||
* @param addr - Address pointer to data, address need to be 4byte aligned
|
|
||||||
* value - value to be XORed
|
|
||||||
*
|
|
||||||
* @return return memory value ^ and value
|
|
||||||
*/
|
|
||||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOXOR_W(volatile int32_t *addr, int32_t value)
|
|
||||||
{
|
|
||||||
int32_t result;
|
|
||||||
|
|
||||||
__asm volatile ("amoxor.w %0, %2, %1" : \
|
|
||||||
"=r"(result), "+A"(*addr) : "r"(value) : "memory");
|
|
||||||
return *addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Core_Exported_Functions */
|
|
||||||
extern uint32_t __get_MSTATUS(void);
|
|
||||||
extern void __set_MSTATUS(uint32_t value);
|
|
||||||
extern uint32_t __get_MISA(void);
|
|
||||||
extern void __set_MISA(uint32_t value);
|
|
||||||
extern uint32_t __get_MTVEC(void);
|
|
||||||
extern void __set_MTVEC(uint32_t value);
|
|
||||||
extern uint32_t __get_MSCRATCH(void);
|
|
||||||
extern void __set_MSCRATCH(uint32_t value);
|
|
||||||
extern uint32_t __get_MEPC(void);
|
|
||||||
extern void __set_MEPC(uint32_t value);
|
|
||||||
extern uint32_t __get_MCAUSE(void);
|
|
||||||
extern void __set_MCAUSE(uint32_t value);
|
|
||||||
extern uint32_t __get_MTVAL(void);
|
|
||||||
extern void __set_MTVAL(uint32_t value);
|
|
||||||
extern uint32_t __get_MVENDORID(void);
|
|
||||||
extern uint32_t __get_MARCHID(void);
|
|
||||||
extern uint32_t __get_MIMPID(void);
|
|
||||||
extern uint32_t __get_MHARTID(void);
|
|
||||||
extern uint32_t __get_SP(void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,6 +1,18 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
// https://github.com/openwch/ch32v307/pull/90
|
||||||
|
// https://github.com/openwch/ch32v20x/pull/12
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wstrict-prototypes"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "ch32v20x.h"
|
#include "ch32v20x.h"
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "bsp/board_api.h"
|
#include "bsp/board_api.h"
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
|
|
||||||
@ -50,7 +62,6 @@ void USBWakeUp_IRQHandler(void) {
|
|||||||
|
|
||||||
|
|
||||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
|
|
||||||
volatile uint32_t system_ticks = 0;
|
volatile uint32_t system_ticks = 0;
|
||||||
|
|
||||||
__attribute__((interrupt))
|
__attribute__((interrupt))
|
||||||
@ -72,7 +83,6 @@ uint32_t SysTick_Config(uint32_t ticks) {
|
|||||||
uint32_t board_millis(void) {
|
uint32_t board_millis(void) {
|
||||||
return system_ticks;
|
return system_ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void board_init(void) {
|
void board_init(void) {
|
||||||
@ -84,28 +94,17 @@ void board_init(void) {
|
|||||||
|
|
||||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
|
||||||
|
|
||||||
uint8_t usb_div;
|
|
||||||
switch (SystemCoreClock) {
|
|
||||||
case 48000000: usb_div = RCC_USBCLKSource_PLLCLK_Div1; break;
|
|
||||||
case 96000000: usb_div = RCC_USBCLKSource_PLLCLK_Div2; break;
|
|
||||||
case 144000000: usb_div = RCC_USBCLKSource_PLLCLK_Div3; break;
|
|
||||||
default: TU_ASSERT(0,); break;
|
|
||||||
}
|
|
||||||
RCC_USBCLKConfig(usb_div);
|
|
||||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE); // FSDEV
|
|
||||||
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_OTG_FS, ENABLE); // USB FS
|
|
||||||
|
|
||||||
GPIO_InitTypeDef GPIO_InitStructure = {
|
GPIO_InitTypeDef GPIO_InitStructure = {
|
||||||
.GPIO_Pin = LED_PIN,
|
.GPIO_Pin = LED_PIN,
|
||||||
.GPIO_Mode = GPIO_Mode_Out_OD,
|
.GPIO_Mode = GPIO_Mode_Out_OD,
|
||||||
.GPIO_Speed = GPIO_Speed_50MHz,
|
.GPIO_Speed = GPIO_Speed_10MHz,
|
||||||
};
|
};
|
||||||
GPIO_Init(LED_PORT, &GPIO_InitStructure);
|
GPIO_Init(LED_PORT, &GPIO_InitStructure);
|
||||||
|
|
||||||
// UART TX is PA9
|
#ifdef UART_DEV
|
||||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
|
UART_CLOCK_EN();
|
||||||
GPIO_InitTypeDef usart_init = {
|
GPIO_InitTypeDef usart_init = {
|
||||||
.GPIO_Pin = GPIO_Pin_9,
|
.GPIO_Pin = UART_TX_PIN,
|
||||||
.GPIO_Speed = GPIO_Speed_50MHz,
|
.GPIO_Speed = GPIO_Speed_50MHz,
|
||||||
.GPIO_Mode = GPIO_Mode_AF_PP,
|
.GPIO_Mode = GPIO_Mode_AF_PP,
|
||||||
};
|
};
|
||||||
@ -119,11 +118,51 @@ void board_init(void) {
|
|||||||
.USART_Mode = USART_Mode_Tx,
|
.USART_Mode = USART_Mode_Tx,
|
||||||
.USART_HardwareFlowControl = USART_HardwareFlowControl_None,
|
.USART_HardwareFlowControl = USART_HardwareFlowControl_None,
|
||||||
};
|
};
|
||||||
USART_Init(USART1, &usart);
|
USART_Init(UART_DEV, &usart);
|
||||||
USART_Cmd(USART1, ENABLE);
|
USART_Cmd(UART_DEV, ENABLE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// USB init
|
||||||
|
uint8_t usb_div;
|
||||||
|
switch (SystemCoreClock) {
|
||||||
|
case 48000000: usb_div = RCC_USBCLKSource_PLLCLK_Div1; break;
|
||||||
|
case 96000000: usb_div = RCC_USBCLKSource_PLLCLK_Div2; break;
|
||||||
|
case 144000000: usb_div = RCC_USBCLKSource_PLLCLK_Div3; break;
|
||||||
|
default: TU_ASSERT(0,); break;
|
||||||
|
}
|
||||||
|
RCC_USBCLKConfig(usb_div);
|
||||||
|
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE); // FSDEV
|
||||||
|
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_OTG_FS, ENABLE); // USB FS
|
||||||
|
|
||||||
__enable_irq();
|
__enable_irq();
|
||||||
board_delay(2);
|
}
|
||||||
|
|
||||||
|
void board_reset_to_bootloader(void) {
|
||||||
|
// board_led_write(true);
|
||||||
|
//
|
||||||
|
// __disable_irq();
|
||||||
|
//
|
||||||
|
// #if CFG_TUD_ENABLED
|
||||||
|
// tud_deinit(0);
|
||||||
|
// RCC_APB1PeriphResetCmd(RCC_APB1Periph_USB, ENABLE);
|
||||||
|
// RCC_APB1PeriphResetCmd(RCC_APB1Periph_USB, DISABLE);
|
||||||
|
// #endif
|
||||||
|
//
|
||||||
|
// SysTick->CTLR = 0;
|
||||||
|
// for (int i = WWDG_IRQn; i< DMA1_Channel8_IRQn; i++) {
|
||||||
|
// NVIC_DisableIRQ(i);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// __enable_irq();
|
||||||
|
//
|
||||||
|
// // define function pointer to BOOT ROM address
|
||||||
|
// void (*bootloader_entry)(void) = (void (*)(void))0x1FFF8000;
|
||||||
|
//
|
||||||
|
// bootloader_entry();
|
||||||
|
//
|
||||||
|
// board_led_write(false);
|
||||||
|
|
||||||
|
// while(1) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
void board_led_write(bool state) {
|
void board_led_write(bool state) {
|
||||||
@ -134,6 +173,17 @@ uint32_t board_button_read(void) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t board_get_unique_id(uint8_t id[], size_t max_len) {
|
||||||
|
(void) max_len;
|
||||||
|
volatile uint32_t* ch32_uuid = ((volatile uint32_t*) 0x1FFFF7E8UL);
|
||||||
|
uint32_t* serial_32 = (uint32_t*) (uintptr_t) id;
|
||||||
|
serial_32[0] = ch32_uuid[0];
|
||||||
|
serial_32[1] = ch32_uuid[1];
|
||||||
|
serial_32[2] = ch32_uuid[2];
|
||||||
|
|
||||||
|
return 12;
|
||||||
|
}
|
||||||
|
|
||||||
int board_uart_read(uint8_t *buf, int len) {
|
int board_uart_read(uint8_t *buf, int len) {
|
||||||
(void) buf;
|
(void) buf;
|
||||||
(void) len;
|
(void) len;
|
||||||
@ -141,11 +191,19 @@ int board_uart_read(uint8_t *buf, int len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int board_uart_write(void const *buf, int len) {
|
int board_uart_write(void const *buf, int len) {
|
||||||
|
#ifdef UART_DEV
|
||||||
const char *bufc = (const char *) buf;
|
const char *bufc = (const char *) buf;
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
|
while (USART_GetFlagStatus(UART_DEV, USART_FLAG_TC) == RESET);
|
||||||
USART_SendData(USART1, *bufc++);
|
USART_SendData(UART_DEV, *bufc++);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
(void) buf; (void) len;
|
||||||
|
#endif
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// Neopixel
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
@ -41,6 +41,7 @@ function(add_board_target BOARD_TARGET)
|
|||||||
|
|
||||||
add_library(${BOARD_TARGET} STATIC
|
add_library(${BOARD_TARGET} STATIC
|
||||||
${SDK_SRC_DIR}/Core/core_riscv.c
|
${SDK_SRC_DIR}/Core/core_riscv.c
|
||||||
|
${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_flash.c
|
||||||
${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_gpio.c
|
${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_gpio.c
|
||||||
${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_misc.c
|
${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_misc.c
|
||||||
${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_rcc.c
|
${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_rcc.c
|
||||||
@ -49,6 +50,7 @@ function(add_board_target BOARD_TARGET)
|
|||||||
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||||
)
|
)
|
||||||
target_include_directories(${BOARD_TARGET} PUBLIC
|
target_include_directories(${BOARD_TARGET} PUBLIC
|
||||||
|
${SDK_SRC_DIR}/Core
|
||||||
${SDK_SRC_DIR}/Peripheral/inc
|
${SDK_SRC_DIR}/Peripheral/inc
|
||||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}
|
||||||
)
|
)
|
||||||
@ -70,19 +72,25 @@ function(add_board_target BOARD_TARGET)
|
|||||||
|
|
||||||
update_board(${BOARD_TARGET})
|
update_board(${BOARD_TARGET})
|
||||||
|
|
||||||
|
if (LD_FLASH_SIZE STREQUAL 224K)
|
||||||
|
target_compile_definitions(${BOARD_TARGET} PUBLIC
|
||||||
|
CH32_FLASH_ENHANCE_READ_MODE=1
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||||
target_compile_options(${BOARD_TARGET} PUBLIC
|
target_compile_options(${BOARD_TARGET} PUBLIC
|
||||||
-mcmodel=medany
|
-mcmodel=medany
|
||||||
)
|
)
|
||||||
target_link_options(${BOARD_TARGET} PUBLIC
|
target_link_options(${BOARD_TARGET} PUBLIC
|
||||||
"LINKER:--script=${LD_FILE_GNU}"
|
|
||||||
-Wl,--defsym=__flash_size=${LD_FLASH_SIZE}
|
|
||||||
-Wl,--defsym=__ram_size=${LD_RAM_SIZE}
|
|
||||||
-nostartfiles
|
-nostartfiles
|
||||||
--specs=nosys.specs --specs=nano.specs
|
--specs=nosys.specs --specs=nano.specs
|
||||||
|
-Wl,--defsym=__FLASH_SIZE=${LD_FLASH_SIZE}
|
||||||
|
-Wl,--defsym=__RAM_SIZE=${LD_RAM_SIZE}
|
||||||
|
"LINKER:--script=${LD_FILE_GNU}"
|
||||||
)
|
)
|
||||||
elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||||
message(FATAL_ERROR "Clang is not supported for MSP432E4")
|
message(FATAL_ERROR "Clang is not supported for CH32v")
|
||||||
elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR")
|
elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR")
|
||||||
target_link_options(${BOARD_TARGET} PUBLIC
|
target_link_options(${BOARD_TARGET} PUBLIC
|
||||||
"LINKER:--config=${LD_FILE_IAR}"
|
"LINKER:--config=${LD_FILE_IAR}"
|
||||||
@ -129,6 +137,7 @@ function(family_configure_example TARGET RTOS)
|
|||||||
# Flashing
|
# Flashing
|
||||||
family_add_bin_hex(${TARGET})
|
family_add_bin_hex(${TARGET})
|
||||||
family_flash_openocd_wch(${TARGET})
|
family_flash_openocd_wch(${TARGET})
|
||||||
|
family_flash_wlink_rs(${TARGET})
|
||||||
|
|
||||||
#family_add_uf2(${TARGET} ${UF2_FAMILY_ID})
|
#family_add_uf2(${TARGET} ${UF2_FAMILY_ID})
|
||||||
#family_flash_uf2(${TARGET} ${UF2_FAMILY_ID})
|
#family_flash_uf2(${TARGET} ${UF2_FAMILY_ID})
|
||||||
|
@ -24,6 +24,9 @@ CFLAGS += \
|
|||||||
-DCH32V20x_${MCU_VARIANT} \
|
-DCH32V20x_${MCU_VARIANT} \
|
||||||
-DCFG_TUSB_MCU=OPT_MCU_CH32V20X
|
-DCFG_TUSB_MCU=OPT_MCU_CH32V20X
|
||||||
|
|
||||||
|
# https://github.com/openwch/ch32v20x/pull/12
|
||||||
|
CFLAGS += -Wno-error=strict-prototypes
|
||||||
|
|
||||||
ifeq ($(PORT),0)
|
ifeq ($(PORT),0)
|
||||||
$(info "Using FSDEV driver")
|
$(info "Using FSDEV driver")
|
||||||
CFLAGS += -DCFG_TUD_WCH_USBIP_FSDEV=1
|
CFLAGS += -DCFG_TUD_WCH_USBIP_FSDEV=1
|
||||||
@ -42,18 +45,20 @@ SRC_C += \
|
|||||||
src/portable/wch/dcd_ch32_usbfs.c \
|
src/portable/wch/dcd_ch32_usbfs.c \
|
||||||
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
||||||
$(SDK_SRC_DIR)/Core/core_riscv.c \
|
$(SDK_SRC_DIR)/Core/core_riscv.c \
|
||||||
$(SDK_SRC_DIR)/Peripheral/src/ch32v20x_gpio.c \
|
$(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_gpio.c \
|
||||||
$(SDK_SRC_DIR)/Peripheral/src/ch32v20x_misc.c \
|
$(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_misc.c \
|
||||||
$(SDK_SRC_DIR)/Peripheral/src/ch32v20x_rcc.c \
|
$(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_rcc.c \
|
||||||
$(SDK_SRC_DIR)/Peripheral/src/ch32v20x_usart.c \
|
$(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_usart.c \
|
||||||
|
|
||||||
SRC_S += $(SDK_SRC_DIR)/Startup/startup_ch32v20x_${MCU_VARIANT}.S
|
SRC_S += $(SDK_SRC_DIR)/Startup/startup_${CH32_FAMILY}_${MCU_VARIANT}.S
|
||||||
|
|
||||||
INC += \
|
INC += \
|
||||||
$(TOP)/$(BOARD_PATH) \
|
$(TOP)/$(BOARD_PATH) \
|
||||||
|
$(TOP)/$(SDK_SRC_DIR)/Core \
|
||||||
$(TOP)/$(SDK_SRC_DIR)/Peripheral/inc \
|
$(TOP)/$(SDK_SRC_DIR)/Peripheral/inc \
|
||||||
|
|
||||||
FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V
|
FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V
|
||||||
|
|
||||||
OPENOCD_WCH_OPTION=-f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg
|
OPENOCD_WCH_OPTION=-f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg
|
||||||
flash: flash-openocd-wch
|
flash: flash-wlink-rs
|
||||||
|
#flash: flash-openocd-wch
|
||||||
|
@ -1,17 +1,16 @@
|
|||||||
/* Define default values if not already defined */
|
/* Define default values if not already defined */
|
||||||
__FLASH_SIZE = DEFINED(__flash_size) ? __flash_size : 64K;
|
__flash_size = DEFINED(__FLASH_SIZE) ? __FLASH_SIZE : 64K;
|
||||||
__RAM_SIZE = DEFINED(__ram_size) ? __ram_size : 20K;
|
__ram_size = DEFINED(__RAM_SIZE) ? __RAM_SIZE : 20K;
|
||||||
|
__stack_size = DEFINED(__STACK_SIZE) ? __STACK_SIZE : 2048;
|
||||||
|
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = __FLASH_SIZE
|
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = __flash_size
|
||||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = __RAM_SIZE
|
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = __ram_size
|
||||||
}
|
}
|
||||||
|
|
||||||
ENTRY( _start )
|
ENTRY( _start )
|
||||||
|
|
||||||
__stack_size = 2048;
|
|
||||||
|
|
||||||
PROVIDE( _stack_size = __stack_size );
|
PROVIDE( _stack_size = __stack_size );
|
||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
|
@ -19,12 +19,12 @@
|
|||||||
* If none of the define below is enabled, the HSI is used as System clock 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_HSE HSE_VALUE
|
||||||
//#define SYSCLK_FREQ_48MHz_HSE 48000000
|
// #define SYSCLK_FREQ_48MHz_HSE 48000000
|
||||||
//#define SYSCLK_FREQ_56MHz_HSE 56000000
|
//#define SYSCLK_FREQ_56MHz_HSE 56000000
|
||||||
//#define SYSCLK_FREQ_72MHz_HSE 72000000
|
// #define SYSCLK_FREQ_72MHz_HSE 72000000
|
||||||
// #define SYSCLK_FREQ_96MHz_HSE 96000000
|
// #define SYSCLK_FREQ_96MHz_HSE 96000000
|
||||||
//#define SYSCLK_FREQ_120MHz_HSE 120000000
|
//#define SYSCLK_FREQ_120MHz_HSE 120000000
|
||||||
#define SYSCLK_FREQ_144MHz_HSE 144000000
|
//#define SYSCLK_FREQ_144MHz_HSE 144000000
|
||||||
//#define SYSCLK_FREQ_HSI HSI_VALUE
|
//#define SYSCLK_FREQ_HSI HSI_VALUE
|
||||||
//#define SYSCLK_FREQ_48MHz_HSI 48000000
|
//#define SYSCLK_FREQ_48MHz_HSI 48000000
|
||||||
//#define SYSCLK_FREQ_56MHz_HSI 56000000
|
//#define SYSCLK_FREQ_56MHz_HSI 56000000
|
||||||
@ -109,6 +109,16 @@ static void SetSysClockTo144_HSI( void );
|
|||||||
*/
|
*/
|
||||||
void SystemInit (void)
|
void SystemInit (void)
|
||||||
{
|
{
|
||||||
|
// Enable Flash enhance read mode for full 224KB
|
||||||
|
#if defined(CH32_FLASH_ENHANCE_READ_MODE) && CH32_FLASH_ENHANCE_READ_MODE == 1
|
||||||
|
FLASH->KEYR = 0x45670123; // FLASH_Unlock_Fast();
|
||||||
|
FLASH->KEYR = 0xCDEF89AB;
|
||||||
|
|
||||||
|
FLASH->CTLR |= (1 << 24); // Enhanced Read Mode
|
||||||
|
|
||||||
|
FLASH->CTLR |= (1 << 15); // FLASH_Lock_Fast();
|
||||||
|
#endif
|
||||||
|
|
||||||
RCC->CTLR |= (uint32_t)0x00000001;
|
RCC->CTLR |= (uint32_t)0x00000001;
|
||||||
RCC->CFGR0 &= (uint32_t)0xF8FF0000;
|
RCC->CFGR0 &= (uint32_t)0xF8FF0000;
|
||||||
RCC->CTLR &= (uint32_t)0xFEF6FFFF;
|
RCC->CTLR &= (uint32_t)0xFEF6FFFF;
|
||||||
|
@ -1,379 +0,0 @@
|
|||||||
/********************************** (C) COPYRIGHT *******************************
|
|
||||||
* File Name : core_riscv.h
|
|
||||||
* Author : WCH
|
|
||||||
* Version : V1.0.0
|
|
||||||
* Date : 2021/06/06
|
|
||||||
* Description : RISC-V Core Peripheral Access Layer Header File for CH32V30x
|
|
||||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*******************************************************************************/
|
|
||||||
#ifndef __CORE_RISCV_H__
|
|
||||||
#define __CORE_RISCV_H__
|
|
||||||
|
|
||||||
/* IO definitions */
|
|
||||||
#ifdef __cplusplus
|
|
||||||
#define __I volatile /* defines 'read only' permissions */
|
|
||||||
#else
|
|
||||||
#define __I volatile const /* defines 'read only' permissions */
|
|
||||||
#endif
|
|
||||||
#define __O volatile /* defines 'write only' permissions */
|
|
||||||
#define __IO volatile /* defines 'read / write' permissions */
|
|
||||||
|
|
||||||
/* Standard Peripheral Library old types (maintained for legacy purpose) */
|
|
||||||
typedef __I uint64_t vuc64; /* Read Only */
|
|
||||||
typedef __I uint32_t vuc32; /* Read Only */
|
|
||||||
typedef __I uint16_t vuc16; /* Read Only */
|
|
||||||
typedef __I uint8_t vuc8; /* Read Only */
|
|
||||||
|
|
||||||
typedef const uint64_t uc64; /* Read Only */
|
|
||||||
typedef const uint32_t uc32; /* Read Only */
|
|
||||||
typedef const uint16_t uc16; /* Read Only */
|
|
||||||
typedef const uint8_t uc8; /* Read Only */
|
|
||||||
|
|
||||||
typedef __I int64_t vsc64; /* Read Only */
|
|
||||||
typedef __I int32_t vsc32; /* Read Only */
|
|
||||||
typedef __I int16_t vsc16; /* Read Only */
|
|
||||||
typedef __I int8_t vsc8; /* Read Only */
|
|
||||||
|
|
||||||
typedef const int64_t sc64; /* Read Only */
|
|
||||||
typedef const int32_t sc32; /* Read Only */
|
|
||||||
typedef const int16_t sc16; /* Read Only */
|
|
||||||
typedef const int8_t sc8; /* Read Only */
|
|
||||||
|
|
||||||
typedef __IO uint64_t vu64;
|
|
||||||
typedef __IO uint32_t vu32;
|
|
||||||
typedef __IO uint16_t vu16;
|
|
||||||
typedef __IO uint8_t vu8;
|
|
||||||
|
|
||||||
typedef uint64_t u64;
|
|
||||||
typedef uint32_t u32;
|
|
||||||
typedef uint16_t u16;
|
|
||||||
typedef uint8_t u8;
|
|
||||||
|
|
||||||
typedef __IO int64_t vs64;
|
|
||||||
typedef __IO int32_t vs32;
|
|
||||||
typedef __IO int16_t vs16;
|
|
||||||
typedef __IO int8_t vs8;
|
|
||||||
|
|
||||||
typedef int64_t s64;
|
|
||||||
typedef int32_t s32;
|
|
||||||
typedef int16_t s16;
|
|
||||||
typedef int8_t s8;
|
|
||||||
|
|
||||||
typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus;
|
|
||||||
|
|
||||||
typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
|
|
||||||
|
|
||||||
typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;
|
|
||||||
|
|
||||||
#define RV_STATIC_INLINE static inline
|
|
||||||
|
|
||||||
/* memory mapped structure for Program Fast Interrupt Controller (PFIC) */
|
|
||||||
typedef struct{
|
|
||||||
__I uint32_t ISR[8];
|
|
||||||
__I uint32_t IPR[8];
|
|
||||||
__IO uint32_t ITHRESDR;
|
|
||||||
__IO uint32_t RESERVED;
|
|
||||||
__IO uint32_t CFGR;
|
|
||||||
__I uint32_t GISR;
|
|
||||||
uint8_t VTFIDR[4];
|
|
||||||
uint8_t RESERVED0[12];
|
|
||||||
__IO uint32_t VTFADDR[4];
|
|
||||||
uint8_t RESERVED1[0x90];
|
|
||||||
__O uint32_t IENR[8];
|
|
||||||
uint8_t RESERVED2[0x60];
|
|
||||||
__O uint32_t IRER[8];
|
|
||||||
uint8_t RESERVED3[0x60];
|
|
||||||
__O uint32_t IPSR[8];
|
|
||||||
uint8_t RESERVED4[0x60];
|
|
||||||
__O uint32_t IPRR[8];
|
|
||||||
uint8_t RESERVED5[0x60];
|
|
||||||
__IO uint32_t IACTR[8];
|
|
||||||
uint8_t RESERVED6[0xE0];
|
|
||||||
__IO uint8_t IPRIOR[256];
|
|
||||||
uint8_t RESERVED7[0x810];
|
|
||||||
__IO uint32_t SCTLR;
|
|
||||||
}PFIC_Type;
|
|
||||||
|
|
||||||
/* memory mapped structure for SysTick */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
__IO u32 CTLR;
|
|
||||||
__IO u32 SR;
|
|
||||||
__IO u64 CNT;
|
|
||||||
__IO u64 CMP;
|
|
||||||
}SysTick_Type;
|
|
||||||
|
|
||||||
|
|
||||||
#define PFIC ((PFIC_Type *) 0xE000E000 )
|
|
||||||
#define NVIC PFIC
|
|
||||||
#define NVIC_KEY1 ((uint32_t)0xFA050000)
|
|
||||||
#define NVIC_KEY2 ((uint32_t)0xBCAF0000)
|
|
||||||
#define NVIC_KEY3 ((uint32_t)0xBEEF0000)
|
|
||||||
|
|
||||||
#define SysTick ((SysTick_Type *) 0xE000F000)
|
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn __enable_irq
|
|
||||||
*
|
|
||||||
* @brief Enable Global Interrupt
|
|
||||||
*
|
|
||||||
* @return none
|
|
||||||
*/
|
|
||||||
RV_STATIC_INLINE void __enable_irq(void)
|
|
||||||
{
|
|
||||||
__asm volatile ("csrw 0x800, %0" : : "r" (0x6088) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn __disable_irq
|
|
||||||
*
|
|
||||||
* @brief Disable Global Interrupt
|
|
||||||
*
|
|
||||||
* @return none
|
|
||||||
*/
|
|
||||||
RV_STATIC_INLINE void __disable_irq(void)
|
|
||||||
{
|
|
||||||
__asm volatile ("csrw 0x800, %0" : : "r" (0x6000) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn __NOP
|
|
||||||
*
|
|
||||||
* @brief nop
|
|
||||||
*
|
|
||||||
* @return none
|
|
||||||
*/
|
|
||||||
RV_STATIC_INLINE void __NOP(void)
|
|
||||||
{
|
|
||||||
__asm volatile ("nop");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn NVIC_EnableIRQ
|
|
||||||
*
|
|
||||||
* @brief Enable Interrupt
|
|
||||||
*
|
|
||||||
* @param IRQn: Interrupt Numbers
|
|
||||||
*
|
|
||||||
* @return none
|
|
||||||
*/
|
|
||||||
RV_STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
|
|
||||||
{
|
|
||||||
NVIC->IENR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn NVIC_DisableIRQ
|
|
||||||
*
|
|
||||||
* @brief Disable Interrupt
|
|
||||||
*
|
|
||||||
* @param IRQn: Interrupt Numbers
|
|
||||||
*
|
|
||||||
* @return none
|
|
||||||
*/
|
|
||||||
RV_STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
|
|
||||||
{
|
|
||||||
NVIC->IRER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn NVIC_GetStatusIRQ
|
|
||||||
*
|
|
||||||
* @brief Get Interrupt Enable State
|
|
||||||
*
|
|
||||||
* @param IRQn: Interrupt Numbers
|
|
||||||
*
|
|
||||||
* @return 1 - Interrupt Enable
|
|
||||||
* 0 - Interrupt Disable
|
|
||||||
*/
|
|
||||||
RV_STATIC_INLINE uint32_t NVIC_GetStatusIRQ(IRQn_Type IRQn)
|
|
||||||
{
|
|
||||||
return((uint32_t) ((NVIC->ISR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn NVIC_GetPendingIRQ
|
|
||||||
*
|
|
||||||
* @brief Get Interrupt Pending State
|
|
||||||
*
|
|
||||||
* @param IRQn: Interrupt Numbers
|
|
||||||
*
|
|
||||||
* @return 1 - Interrupt Pending Enable
|
|
||||||
* 0 - Interrupt Pending Disable
|
|
||||||
*/
|
|
||||||
RV_STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
|
|
||||||
{
|
|
||||||
return((uint32_t) ((NVIC->IPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn NVIC_SetPendingIRQ
|
|
||||||
*
|
|
||||||
* @brief Set Interrupt Pending
|
|
||||||
*
|
|
||||||
* @param IRQn: Interrupt Numbers
|
|
||||||
*
|
|
||||||
* @return None
|
|
||||||
*/
|
|
||||||
RV_STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
|
|
||||||
{
|
|
||||||
NVIC->IPSR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn NVIC_ClearPendingIRQ
|
|
||||||
*
|
|
||||||
* @brief Clear Interrupt Pending
|
|
||||||
*
|
|
||||||
* @param IRQn: Interrupt Numbers
|
|
||||||
*
|
|
||||||
* @return None
|
|
||||||
*/
|
|
||||||
RV_STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
|
|
||||||
{
|
|
||||||
NVIC->IPRR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn NVIC_GetActive
|
|
||||||
*
|
|
||||||
* @brief Get Interrupt Active State
|
|
||||||
*
|
|
||||||
* @param IRQn: Interrupt Numbers
|
|
||||||
*
|
|
||||||
* @return 1 - Interrupt Active
|
|
||||||
* 0 - Interrupt No Active
|
|
||||||
*/
|
|
||||||
RV_STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
|
|
||||||
{
|
|
||||||
return((uint32_t)((NVIC->IACTR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn NVIC_SetPriority
|
|
||||||
*
|
|
||||||
* @brief Set Interrupt Priority
|
|
||||||
*
|
|
||||||
* @param IRQn - Interrupt Numbers
|
|
||||||
* priority -
|
|
||||||
* bit7 - pre-emption priority
|
|
||||||
* bit6~bit4 - subpriority
|
|
||||||
* @return None
|
|
||||||
*/
|
|
||||||
RV_STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint8_t priority)
|
|
||||||
{
|
|
||||||
NVIC->IPRIOR[(uint32_t)(IRQn)] = priority;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn __WFI
|
|
||||||
*
|
|
||||||
* @brief Wait for Interrupt
|
|
||||||
*
|
|
||||||
* @return None
|
|
||||||
*/
|
|
||||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFI(void)
|
|
||||||
{
|
|
||||||
NVIC->SCTLR &= ~(1<<3); // wfi
|
|
||||||
asm volatile ("wfi");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn __WFE
|
|
||||||
*
|
|
||||||
* @brief Wait for Events
|
|
||||||
*
|
|
||||||
* @return None
|
|
||||||
*/
|
|
||||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFE(void)
|
|
||||||
{
|
|
||||||
uint32_t t;
|
|
||||||
|
|
||||||
t = NVIC->SCTLR;
|
|
||||||
NVIC->SCTLR |= (1<<3)|(1<<5); // (wfi->wfe)+(__sev)
|
|
||||||
NVIC->SCTLR = (NVIC->SCTLR & ~(1<<5)) | ( t & (1<<5));
|
|
||||||
asm volatile ("wfi");
|
|
||||||
asm volatile ("wfi");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn SetVTFIRQ
|
|
||||||
*
|
|
||||||
* @brief Set VTF Interrupt
|
|
||||||
*
|
|
||||||
* @param add - VTF interrupt service function base address.
|
|
||||||
* IRQn -Interrupt Numbers
|
|
||||||
* num - VTF Interrupt Numbers
|
|
||||||
* NewState - DISABLE or ENABLE
|
|
||||||
* @return None
|
|
||||||
*/
|
|
||||||
RV_STATIC_INLINE void SetVTFIRQ(uint32_t addr, IRQn_Type IRQn, uint8_t num, FunctionalState NewState){
|
|
||||||
if(num > 3) return ;
|
|
||||||
|
|
||||||
if (NewState != DISABLE)
|
|
||||||
{
|
|
||||||
NVIC->VTFIDR[num] = IRQn;
|
|
||||||
NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)|0x1);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
NVIC->VTFIDR[num] = IRQn;
|
|
||||||
NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)&(~0x1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* @fn NVIC_SystemReset
|
|
||||||
*
|
|
||||||
* @brief Initiate a system reset request
|
|
||||||
*
|
|
||||||
* @return None
|
|
||||||
*/
|
|
||||||
RV_STATIC_INLINE void NVIC_SystemReset(void)
|
|
||||||
{
|
|
||||||
NVIC->CFGR = NVIC_KEY3|(1<<7);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Core_Exported_Functions */
|
|
||||||
extern uint32_t __get_FFLAGS(void);
|
|
||||||
extern void __set_FFLAGS(uint32_t value);
|
|
||||||
extern uint32_t __get_FRM(void);
|
|
||||||
extern void __set_FRM(uint32_t value);
|
|
||||||
extern uint32_t __get_FCSR(void);
|
|
||||||
extern void __set_FCSR(uint32_t value);
|
|
||||||
extern uint32_t __get_MSTATUS(void);
|
|
||||||
extern void __set_MSTATUS(uint32_t value);
|
|
||||||
extern uint32_t __get_MISA(void);
|
|
||||||
extern void __set_MISA(uint32_t value);
|
|
||||||
extern uint32_t __get_MIE(void);
|
|
||||||
extern void __set_MIE(uint32_t value);
|
|
||||||
extern uint32_t __get_MTVEC(void);
|
|
||||||
extern void __set_MTVEC(uint32_t value);
|
|
||||||
extern uint32_t __get_MSCRATCH(void);
|
|
||||||
extern void __set_MSCRATCH(uint32_t value);
|
|
||||||
extern uint32_t __get_MEPC(void);
|
|
||||||
extern void __set_MEPC(uint32_t value);
|
|
||||||
extern uint32_t __get_MCAUSE(void);
|
|
||||||
extern void __set_MCAUSE(uint32_t value);
|
|
||||||
extern uint32_t __get_MTVAL(void);
|
|
||||||
extern void __set_MTVAL(uint32_t value);
|
|
||||||
extern uint32_t __get_MIP(void);
|
|
||||||
extern void __set_MIP(uint32_t value);
|
|
||||||
extern uint32_t __get_MCYCLE(void);
|
|
||||||
extern void __set_MCYCLE(uint32_t value);
|
|
||||||
extern uint32_t __get_MCYCLEH(void);
|
|
||||||
extern void __set_MCYCLEH(uint32_t value);
|
|
||||||
extern uint32_t __get_MINSTRET(void);
|
|
||||||
extern void __set_MINSTRET(uint32_t value);
|
|
||||||
extern uint32_t __get_MINSTRETH(void);
|
|
||||||
extern void __set_MINSTRETH(uint32_t value);
|
|
||||||
extern uint32_t __get_MVENDORID(void);
|
|
||||||
extern uint32_t __get_MARCHID(void);
|
|
||||||
extern uint32_t __get_MIMPID(void);
|
|
||||||
extern uint32_t __get_MHARTID(void);
|
|
||||||
extern uint32_t __get_SP(void);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
@ -25,8 +25,17 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "debug_uart.h"
|
#include "debug_uart.h"
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wstrict-prototypes"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <ch32v30x.h>
|
#include <ch32v30x.h>
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
#define UART_RINGBUFFER_SIZE_TX 128
|
#define UART_RINGBUFFER_SIZE_TX 128
|
||||||
#define UART_RINGBUFFER_MASK_TX (UART_RINGBUFFER_SIZE_TX-1)
|
#define UART_RINGBUFFER_MASK_TX (UART_RINGBUFFER_SIZE_TX-1)
|
||||||
|
@ -25,9 +25,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
|
|
||||||
|
// https://github.com/openwch/ch32v307/pull/90
|
||||||
|
// https://github.com/openwch/ch32v20x/pull/12
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wstrict-prototypes"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "debug_uart.h"
|
#include "debug_uart.h"
|
||||||
#include "ch32v30x.h"
|
#include "ch32v30x.h"
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "bsp/board_api.h"
|
#include "bsp/board_api.h"
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@ function(add_board_target BOARD_TARGET)
|
|||||||
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||||
)
|
)
|
||||||
target_include_directories(${BOARD_TARGET} PUBLIC
|
target_include_directories(${BOARD_TARGET} PUBLIC
|
||||||
|
${SDK_SRC_DIR}/Core
|
||||||
${SDK_SRC_DIR}/Peripheral/inc
|
${SDK_SRC_DIR}/Peripheral/inc
|
||||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}
|
||||||
)
|
)
|
||||||
|
@ -25,6 +25,9 @@ CFLAGS += \
|
|||||||
-fsigned-char \
|
-fsigned-char \
|
||||||
-DCFG_TUSB_MCU=OPT_MCU_CH32V307 \
|
-DCFG_TUSB_MCU=OPT_MCU_CH32V307 \
|
||||||
|
|
||||||
|
# https://github.com/openwch/ch32v307/pull/90
|
||||||
|
CFLAGS += -Wno-error=strict-prototypes
|
||||||
|
|
||||||
ifeq ($(SPEED),high)
|
ifeq ($(SPEED),high)
|
||||||
$(info "Using USBHS driver for HighSpeed mode")
|
$(info "Using USBHS driver for HighSpeed mode")
|
||||||
CFLAGS += -DCFG_TUD_WCH_USBIP_USBHS=1
|
CFLAGS += -DCFG_TUD_WCH_USBIP_USBHS=1
|
||||||
@ -51,6 +54,7 @@ SRC_S += \
|
|||||||
|
|
||||||
INC += \
|
INC += \
|
||||||
$(TOP)/$(BOARD_PATH) \
|
$(TOP)/$(BOARD_PATH) \
|
||||||
|
$(TOP)/$(SDK_SRC_DIR)/Core \
|
||||||
$(TOP)/$(SDK_SRC_DIR)/Peripheral/inc
|
$(TOP)/$(SDK_SRC_DIR)/Peripheral/inc
|
||||||
|
|
||||||
# For freeRTOS port source
|
# For freeRTOS port source
|
||||||
|
@ -1,134 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 Jerzy Kasenberg
|
|
||||||
*
|
|
||||||
* 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 <hal/hal_gpio.h>
|
|
||||||
#include <mcu/mcu.h>
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
// Forward USB interrupt events to TinyUSB IRQ Handler
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
void USB_IRQHandler(void)
|
|
||||||
{
|
|
||||||
tud_int_handler(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
// MACRO TYPEDEF CONSTANT ENUM
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
|
|
||||||
#define LED_PIN 33 // P1.1
|
|
||||||
#define LED_STATE_ON 1
|
|
||||||
#define LED_STATE_OFF (1-LED_STATE_ON)
|
|
||||||
|
|
||||||
#define BUTTON_PIN 6
|
|
||||||
|
|
||||||
void UnhandledIRQ(void)
|
|
||||||
{
|
|
||||||
CRG_TOP->SYS_CTRL_REG = 0x80;
|
|
||||||
__BKPT(1);
|
|
||||||
while(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// DA146xx driver function that must be called whenever VBUS changes.
|
|
||||||
extern void tusb_vbus_changed(bool present);
|
|
||||||
|
|
||||||
void board_init(void)
|
|
||||||
{
|
|
||||||
// LED
|
|
||||||
hal_gpio_init_out(LED_PIN, LED_STATE_ON);
|
|
||||||
|
|
||||||
hal_gpio_init_out(1, 0);
|
|
||||||
hal_gpio_init_out(2, 0);
|
|
||||||
hal_gpio_init_out(3, 0);
|
|
||||||
hal_gpio_init_out(4, 0);
|
|
||||||
hal_gpio_init_out(5, 0);
|
|
||||||
|
|
||||||
// Button
|
|
||||||
hal_gpio_init_in(BUTTON_PIN, HAL_GPIO_PULL_DOWN);
|
|
||||||
|
|
||||||
// 1ms tick timer
|
|
||||||
SysTick_Config(SystemCoreClock / 1000);
|
|
||||||
|
|
||||||
#if CFG_TUD_ENABLED
|
|
||||||
// This board is USB powered there is no need to monitor
|
|
||||||
// VBUS line. Notify driver that VBUS is present.
|
|
||||||
tusb_vbus_changed(true);
|
|
||||||
|
|
||||||
/* Setup USB IRQ */
|
|
||||||
NVIC_SetPriority(USB_IRQn, 2);
|
|
||||||
NVIC_EnableIRQ(USB_IRQn);
|
|
||||||
|
|
||||||
/* Use PLL96 / 2 clock not HCLK */
|
|
||||||
CRG_TOP->CLK_CTRL_REG &= ~CRG_TOP_CLK_CTRL_REG_USB_CLK_SRC_Msk;
|
|
||||||
|
|
||||||
mcu_gpio_set_pin_function(14, MCU_GPIO_MODE_INPUT, MCU_GPIO_FUNC_USB);
|
|
||||||
mcu_gpio_set_pin_function(15, MCU_GPIO_MODE_INPUT, MCU_GPIO_FUNC_USB);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
// Board porting API
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
|
|
||||||
void board_led_write(bool state)
|
|
||||||
{
|
|
||||||
hal_gpio_write(LED_PIN, state ? LED_STATE_ON : LED_STATE_OFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t board_button_read(void)
|
|
||||||
{
|
|
||||||
// button is active HIGH
|
|
||||||
return hal_gpio_read(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)
|
|
||||||
{
|
|
||||||
(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
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user