Merge remote-tracking branch 'tinyusb/master' into vendor_fifo

This commit is contained in:
Mengsk
2024-08-27 12:13:29 +02:00
143 changed files with 8509 additions and 4534 deletions

View File

@@ -1,92 +1,79 @@
version: 2.1
commands:
setup-toolchain:
parameters:
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 >>
setup: true
orbs:
continuation: circleci/continuation@1
jobs:
arm-clang:
parameters:
family:
type: string
build-system:
type: string
set-matrix:
executor: continuation/default
docker:
- image: cimg/base:current
resource_class: medium
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
resource_class: small
steps:
- checkout
- setup-toolchain:
toolchain: clang
toolchain_url: $TOOLCHAIN_URL
- get-deps:
family: << parameters.family >>
- run:
name: Build
name: Set matrix
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
python tools/build.py $ONE_PER_FAMILY -s << parameters.build-system >> --toolchain clang << parameters.family >>
MATRIX_JSON=$(python .github/workflows/ci_set_matrix.py)
echo "MATRIX_JSON=$MATRIX_JSON"
BUILDSYSTEM_TOOLCHAIN=(
"cmake arm-clang"
"make aarch64-gcc"
"make arm-gcc"
"make msp430-gcc"
"make riscv-gcc"
# "make rx-gcc" llvm-gcc-renesas.com seems to be down
"cmake esp-idf"
)
RESOURCE_LARGE='["nrf", "imxrt"]'
for e in "${BUILDSYSTEM_TOOLCHAIN[@]}"; do
e_arr=($e)
build_system="${e_arr[0]}"
toolchain="${e_arr[1]}"
FAMILY=$(echo $MATRIX_JSON | jq -r ".\"$toolchain\".family")
echo "FAMILY_${toolchain}=$FAMILY"
# FAMILY_LARGE = FAMILY - RESOURCE_LARGE
# Separate large from medium+ resources
FAMILY_LARGE=$(jq -n --argjson family "$FAMILY" --argjson resource "$RESOURCE_LARGE" '$family | map(select(IN($resource[])))')
FAMILY=$(jq -n --argjson family "$FAMILY" --argjson resource "$RESOURCE_LARGE" '$family | map(select(IN($resource[]) | not))')
if [[ $toolchain == esp-idf ]]; then
echo " - build-vm:" >> .circleci/config2.yml
else
echo " - build:" >> .circleci/config2.yml
fi
echo " matrix:" >> .circleci/config2.yml
echo " parameters:" >> .circleci/config2.yml
echo " build-system: ['$build_system']" >> .circleci/config2.yml
echo " toolchain: ['$toolchain']" >> .circleci/config2.yml
echo " family: $FAMILY" >> .circleci/config2.yml
#echo " resource_class: ['medium+']" >> .circleci/config2.yml
# add large resources
if [ "$(echo $FAMILY_LARGE | jq 'length')" -gt 0 ]; then
echo " - build:" >> .circleci/config2.yml
echo " matrix:" >> .circleci/config2.yml
echo " parameters:" >> .circleci/config2.yml
echo " build-system: ['$build_system']" >> .circleci/config2.yml
echo " toolchain: ['$toolchain']" >> .circleci/config2.yml
echo " family: $FAMILY_LARGE" >> .circleci/config2.yml
echo " resource_class: ['large']" >> .circleci/config2.yml
fi
done
- continuation/continue:
configuration_path: .circleci/config2.yml
workflows:
build:
set-matrix:
# Only build PR here, Push will be built by github action.
when:
and:
- not: << pipeline.git.branch.is_default >>
jobs:
- arm-clang:
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']
- set-matrix

176
.circleci/config2.yml Normal file
View File

@@ -0,0 +1,176 @@
version: 2.1
commands:
setup-toolchain:
parameters:
toolchain:
type: string
steps:
- run:
name: Set toolchain url and key
command: |
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-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",
"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": "https://llvm-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 '.["<< parameters.toolchain >>"]')
# only cache if not a github link
if [[ $toolchain_url != "https://github.com"* ]]; then
echo "<< parameters.toolchain >>-$toolchain_url" > toolchain_key
fi
echo "export toolchain_url=$toolchain_url" >> $BASH_ENV
- restore_cache:
name: Restore Toolchain Cache
key: deps-{{ checksum "toolchain_key" }}
paths:
- ~/cache/<< parameters.toolchain >>
- run:
name: Install Toolchain
command: |
# download if folder does not exist (not cached)
if [ ! -d ~/cache/<< parameters.toolchain >> ]; then
mkdir -p ~/cache/<< parameters.toolchain >>
wget --progress=dot:giga $toolchain_url -O toolchain.tar.gz
if [[ << parameters.toolchain >> == rx-gcc ]]; then
mv toolchain.tar.gz toolchain.run
chmod +x toolchain.run
./toolchain.run -p ~/cache/<< parameters.toolchain >>/gnurx -y
else
tar -C ~/cache/<< parameters.toolchain >> -xaf toolchain.tar.gz
fi
fi
# Add toolchain to PATH
echo "export PATH=$PATH:`echo ~/cache/<< parameters.toolchain >>/*/bin`" >> $BASH_ENV
- save_cache:
name: Save Toolchain Cache
key: deps-{{ checksum "toolchain_key" }}
paths:
- ~/cache/<< parameters.toolchain >>
build:
parameters:
build-system:
type: string
toolchain:
type: string
family:
type: string
steps:
- checkout
- when:
condition:
not:
equal: [esp-idf, << parameters.toolchain >>]
steps:
- setup-toolchain:
toolchain: << parameters.toolchain >>
- run:
name: Get Dependencies
command: |
python tools/get_deps.py << parameters.family >>
# Install ninja if cmake build system
if [ << parameters.build-system >> == "cmake" ]; then
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
fi
# 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
- run:
name: Build
command: |
if [ << parameters.toolchain >> == esp-idf ]; then
docker run --rm -v $PWD:/project -w /project espressif/idf:v5.1.1 python tools/build.py << parameters.family >>
else
# 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 -s << parameters.build-system >> $TOOLCHAIN_OPTION << parameters.family >>
fi
jobs:
# Build using docker
build:
parameters:
resource_class:
type: string
default: medium+
build-system:
type: string
toolchain:
type: string
family:
type: string
docker:
- image: cimg/base:current
resource_class: << parameters.resource_class >>
steps:
- build:
build-system: << parameters.build-system >>
toolchain: << parameters.toolchain >>
family: << parameters.family >>
# Build using VM
build-vm:
parameters:
resource_class:
type: string
default: large
build-system:
type: string
toolchain:
type: string
family:
type: string
machine:
image: ubuntu-2404:current
resource_class: << parameters.resource_class >>
steps:
- build:
build-system: << parameters.build-system >>
toolchain: << parameters.toolchain >>
family: << parameters.family >>
workflows:
build:
jobs:
# - build:
# matrix:
# parameters:
# toolchain: [ 'arm-gcc' ]
# build-system: [ 'cmake' ]
# family: [ 'nrf' ]
# resource_class: ['large']
# - build-vm:
# matrix:
# parameters:
# toolchain: ['esp-idf']
# build-system: ['cmake']
# family: ['-bespressif_kaluga_1']
# resource_class: ['large']

View File

@@ -4,8 +4,8 @@ inputs:
toolchain:
description: 'Toolchain name'
required: true
toolchain_url:
description: 'Toolchain URL or version'
toolchain_version:
description: 'Toolchain version'
required: false
outputs:
@@ -27,7 +27,28 @@ runs:
uses: ./.github/actions/setup_toolchain/espressif
with:
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
if: >-
@@ -37,7 +58,7 @@ runs:
uses: ./.github/actions/setup_toolchain/download
with:
toolchain: ${{ inputs.toolchain }}
toolchain_url: ${{ inputs.toolchain_url }}
toolchain_url: ${{ steps.set-toolchain-url.outputs.toolchain_url }}
- name: Set toolchain option
id: set-toolchain-option

View File

@@ -4,7 +4,7 @@ inputs:
toolchain:
description: 'Toolchain name'
required: true
toolchain_url:
toolchain_version:
description: 'Toolchain URL or version'
required: true
@@ -22,14 +22,14 @@ runs:
id: cache-toolchain-espressif
with:
path: ${{ env.DOCKER_ESP_IDF }}
key: ${{ inputs.toolchain }}-${{ inputs.toolchain_url }}
key: ${{ inputs.toolchain }}-${{ inputs.toolchain_version }}
- name: Pull and Save Docker Image
if: steps.cache-toolchain-espressif.outputs.cache-hit != 'true'
run: |
docker pull espressif/idf:${{ inputs.toolchain_url }}
docker pull espressif/idf:${{ inputs.toolchain_version }}
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
shell: bash

View File

@@ -51,14 +51,13 @@ jobs:
# Build CMake
# ---------------------------------------
cmake:
# if: false
needs: set-matrix
uses: ./.github/workflows/build_util.yml
strategy:
fail-fast: false
matrix:
toolchain:
# - 'arm-clang' is built by circle-ci
# - 'arm-clang' is built by circle-ci in PR
- 'aarch64-gcc'
- 'arm-gcc'
- 'msp430-gcc'
@@ -66,38 +65,38 @@ jobs:
with:
build-system: 'cmake'
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) }}
one-per-family: ${{ github.event_name != 'pull_request' }}
one-per-family: ${{ github.event_name == 'push' }}
# ---------------------------------------
# Build Make
# Build Make (built by circle-ci in PR, only build on push here)
# ---------------------------------------
make:
# if: false
if: github.event_name == 'push'
needs: set-matrix
uses: ./.github/workflows/build_util.yml
strategy:
fail-fast: false
matrix:
toolchain:
# 'arm-clang' is built by circle-ci
- 'aarch64-gcc'
# 'arm-clang'
- 'arm-gcc'
- 'aarch64-gcc'
- 'msp430-gcc'
- 'riscv-gcc'
- 'rx-gcc'
- 'esp-idf' # buid-system is ignored
with:
build-system: 'make'
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) }}
one-per-family: ${{ github.event_name != 'pull_request' }}
one-per-family: true
# ---------------------------------------
# Build Make on Windows/MacOS
# ---------------------------------------
make-os:
if: github.event_name == 'pull_request'
uses: ./.github/workflows/build_util.yml
strategy:
fail-fast: false
@@ -110,29 +109,10 @@ jobs:
build-args: '["stm32h7"]'
one-per-family: true
# ---------------------------------------
# Build Espressif
# ---------------------------------------
espressif:
# if: false
uses: ./.github/workflows/build_util.yml
strategy:
fail-fast: false
matrix:
board:
- 'espressif_kaluga_1'
- 'espressif_s3_devkitm'
with:
build-system: 'cmake'
toolchain: 'esp-idf'
toolchain_url: 'v5.1.1'
build-args: '["-b${{ matrix.board }}"]'
# ---------------------------------------
# Build IAR on HFP self-hosted
# ---------------------------------------
arm-iar:
# if: false
if: github.repository_owner == 'hathach'
needs: set-matrix
runs-on: [self-hosted, Linux, X64, hifiphile]

View File

@@ -9,9 +9,6 @@ on:
toolchain:
required: true
type: string
toolchain_url:
required: false
type: string
build-args:
required: true
type: string
@@ -40,7 +37,7 @@ jobs:
uses: ./.github/actions/setup_toolchain
with:
toolchain: ${{ inputs.toolchain }}
toolchain_url: ${{ inputs.toolchain_url }}
toolchain_version: 'v5.1.1'
- name: Get Dependencies
uses: ./.github/actions/get_deps
@@ -58,11 +55,10 @@ jobs:
shell: bash
- name: Build
if: inputs.toolchain != 'esp-idf'
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 }}
- name: Build using ESP-IDF docker
if: inputs.toolchain == 'esp-idf'
run: |
docker run --rm -v $PWD:/project -w /project espressif/idf:${{ inputs.toolchain_url }} python3 tools/build.py ${{ matrix.arg }}
if [ "${{ inputs.toolchain }}" == "esp-idf" ]; then
docker run --rm -v $PWD:/project -w /project espressif/idf:v5.1.1 python tools/build.py ${{ matrix.arg }}
else
python tools/build.py -s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ steps.set-one-per-family.outputs.build_option }} ${{ matrix.arg }}
fi
shell: bash

View File

@@ -1,15 +1,16 @@
import json
# toolchain, url
toolchain_list = {
"aarch64-gcc": "https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz",
"arm-clang": "https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/releases/download/release-17.0.1/LLVMEmbeddedToolchainForArm-17.0.1-Linux-x86_64.tar.xz",
"arm-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_list = [
"aarch64-gcc",
"arm-clang",
"arm-iar",
"arm-gcc",
"esp-idf",
"msp430-gcc",
"riscv-gcc",
"rx-gcc"
]
# family: [supported toolchain]
family_list = {
@@ -22,6 +23,7 @@ family_list = {
"lpc11 lpc13 lpc15": ["arm-gcc", "arm-clang"],
"lpc17 lpc18 lpc40 lpc43": ["arm-gcc", "arm-clang"],
"lpc51 lpc54 lpc55": ["arm-gcc", "arm-clang"],
"max32650 max32666 max32690 max78002": ["arm-gcc"],
"mcx": ["arm-gcc"],
"mm32": ["arm-gcc"],
"msp430": ["msp430-gcc"],
@@ -30,21 +32,25 @@ family_list = {
"ra": ["arm-gcc"],
"rp2040": ["arm-gcc"],
"rx": ["rx-gcc"],
"samd11 samd21 saml2x": ["arm-gcc", "arm-clang"],
"samd11 saml2x": ["arm-gcc", "arm-clang"],
"samd21": ["arm-gcc", "arm-clang"],
"samd5x_e5x samg": ["arm-gcc", "arm-clang"],
"stm32f0 stm32f1 stm32f2 stm32f3": ["arm-gcc", "arm-clang", "arm-iar"],
"stm32f4": ["arm-gcc", "arm-clang", "arm-iar"],
"stm32f7": ["arm-gcc", "arm-clang", "arm-iar"],
"stm32g0 stm32g4 stm32h5": ["arm-gcc", "arm-clang", "arm-iar"],
"stm32h7": ["arm-gcc", "arm-clang", "arm-iar"],
"stm32l0 stm32l4 stm32u5 stm32wb": ["arm-gcc", "arm-clang", "arm-iar"],
"stm32l0 stm32l4": ["arm-gcc", "arm-clang", "arm-iar"],
"stm32u5 stm32wb": ["arm-gcc", "arm-clang", "arm-iar"],
"xmc4000": ["arm-gcc"],
"-bespressif_kaluga_1": ["esp-idf"],
"-bespressif_s3_devkitm": ["esp-idf"],
}
def set_matrix_json():
matrix = {}
for toolchain in toolchain_list.keys():
for toolchain in toolchain_list:
filtered_families = [family for family, supported_toolchain in family_list.items() if
toolchain in supported_toolchain]
@@ -55,7 +61,7 @@ def set_matrix_json():
hfp_boards = [f"-b{board['name']}" for board in hfp_data['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))

View File

@@ -44,11 +44,16 @@ jobs:
echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_ENV
echo "BOARDS_LIST=$BOARDS_LIST" >> $GITHUB_OUTPUT
- name: Setup Toolchain
- name: Setup arm-gcc toolchain
uses: ./.github/actions/setup_toolchain
with:
toolchain: 'arm-gcc'
- name: Setup risv-gcc toolchain
uses: ./.github/actions/setup_toolchain
with:
toolchain: 'riscv-gcc'
- name: Get Dependencies
uses: ./.github/actions/get_deps
with:
@@ -65,56 +70,6 @@ jobs:
cmake-build/cmake-build-*/*/*/*.elf
cmake-build/cmake-build-*/*/*/*.bin
# ---------------------------------------
# Build Espressif (skipped since CP210x cause USB bus issue)
# cp210x ttyUSB0: usb_serial_generic_write_bulk_callback - nonzero urb status: -71
# ---------------------------------------
build-esp:
if: false
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' ${{ env.HIL_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_rpi_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)
# self-hosted running on an RPI. For attached hardware checkout test/hil/rpi.json
@@ -123,7 +78,6 @@ jobs:
if: github.repository_owner == 'hathach'
needs:
- build
#- build-esp
runs-on: [self-hosted, ARM64, rpi, hardware-in-the-loop]
env:
BOARDS_LIST: "${{ needs.build-esp.outputs.BOARDS_LIST }} ${{ needs.build.outputs.BOARDS_LIST }}"

136
.idea/cmake.xml generated
View File

@@ -4,141 +4,145 @@
<configurations>
<configuration PROFILE_NAME="pico" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=raspberry_pi_pico -DLOG=1" />
<configuration PROFILE_NAME="pico pio-host" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=raspberry_pi_pico -DLOG=1 -DCFLAGS_CLI=&quot;-DCFG_TUH_RPI_PIO_USB=1&quot;" />
<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="feather_rp2040_max3421" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=feather_rp2040_max3421 -DLOG=2" />
<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 esp32s2" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=adafruit_feather_esp32s2 -DMAX3421_HOST=1 -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="feather_rp2040_max3421" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=feather_rp2040_max3421 -DLOG=1" />
<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>
<envs>
<env name="ESPBAUD" value="1500000" />
</envs>
</ADDITIONAL_GENERATION_ENVIRONMENT>
</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>
<envs>
<env name="ESPBAUD" value="1500000" />
</envs>
</ADDITIONAL_GENERATION_ENVIRONMENT>
</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>
<envs>
<env name="ESPBAUD" value="1500000" />
</envs>
</ADDITIONAL_GENERATION_ENVIRONMENT>
</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>
<envs>
<env name="ESPBAUD" value="1500000" />
</envs>
</ADDITIONAL_GENERATION_ENVIRONMENT>
</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>
<envs>
<env name="ESPBAUD" value="1500000" />
</envs>
</ADDITIONAL_GENERATION_ENVIRONMENT>
</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>
<envs>
<env name="ESPBAUD" value="1500000" />
</envs>
</ADDITIONAL_GENERATION_ENVIRONMENT>
</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>
<envs>
<env name="ESPBAUD" value="1500000" />
</envs>
</ADDITIONAL_GENERATION_ENVIRONMENT>
</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>
<envs>
<env name="ESPBAUD" value="1500000" />
</envs>
</ADDITIONAL_GENERATION_ENVIRONMENT>
</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="metro_m0_express" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=metro_m0_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=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=1 -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" />
<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=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="pca10095" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=pca10095 -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=3 -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="rt1010 evk" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=mimxrt1010_evk -DLOG=3 -DLOGGER=RTT" />
<configuration PROFILE_NAME="rt1060 evk" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=mimxrt1060_evk -DLOG=3 -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="lpcxpresso1769" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso1769 -DLOG=3 -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="ea4088 quickstart" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ea4088_quickstart -DLOG=3 -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="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=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=1 -DLOGGER=RTT -DTRACE_ETM=1" />
<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=1 -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=1 -DLOGGER=RTT -DTRACE_ETM=1" />
<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=1 -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=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="lpc54628" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso54628 -DLOG=3 -DLOGGER=RTT" />
<configuration PROFILE_NAME="lpc55s69" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso55s69 -DLOG=3 -DLOGGER=RTT" />
<configuration PROFILE_NAME="mcxn947brk" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=mcxn947brk -DLOG=3 -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_kl25z" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=frdm_kl25z -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=1 -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=1 -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_k64f" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=frdm_k64f -DLOG=2 -DLOGGER=RTT" />
<configuration PROFILE_NAME="stm32f072disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f072disco" />
<configuration PROFILE_NAME="stm32f103_mini_2" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f103_mini_2" />
<configuration PROFILE_NAME="stm32f207nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f207nucleo -DLOG=2 -DLOGGER=RTT" />
<configuration PROFILE_NAME="stm32f303disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f303disco -DLOG=2 -DLOGGER=RTT" />
<configuration PROFILE_NAME="stm32f411disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f411disco -DLOG=2 -DLOGGER=RTT" />
<configuration PROFILE_NAME="stm32f769disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f769disco -DLOG=3 -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 -DLOG=0 -DLOGGER=RTT" />
<configuration PROFILE_NAME="stm32f103_mini_2" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f103_mini_2 -DLOG=1 -DLOGGGER=RTT" />
<configuration PROFILE_NAME="stm32f103ze_iar" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f103ze_iar -DLOG=1 -DLOGGGER=RTT" />
<configuration PROFILE_NAME="stm32f207nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f207nucleo -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="stm32f303disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f303disco -DLOG=0 -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="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="stm32h563nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32h563nucleo -DLOG=3 -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="stm32h743nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32h743nucleo -DLOG=3" />
<configuration PROFILE_NAME="stm32l0538disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32l0538disco" />
<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" 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=1 -DLOGGER=RTT -DTRACE_ETM=1" />
<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 -DLOG=0 -DLOGGER=RTT" />
<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="stm32u5a5nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32u5a5nucleo -DLOG=3 -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=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="stm32wb55nucleo" ENABLED="false" GENERATION_OPTIONS="-DBOARD=stm32wb55nucleo" />
<configuration PROFILE_NAME="ra2a1_ek" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ra2a1_ek -DLOG=3 -DLOGGER=RTT" />
<configuration PROFILE_NAME="ra4m1_ek" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ra4m1_ek -DLOG=3 -DLOGGER=RTT" />
<configuration PROFILE_NAME="ra6m1_ek" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ra6m1_ek -DLOG=3 -DLOGGER=RTT" />
<configuration PROFILE_NAME="ra6m5_ek" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ra6m5_ek -DLOG=3 -DLOGGER=RTT -DTRACE_ETM=1" />
<configuration PROFILE_NAME="ra6m5_ek PORT0" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ra6m5_ek -DLOG=3 -DLOGGER=RTT -DTRACE_ETM=1 -DPORT=0" />
<configuration PROFILE_NAME="ra2a1_ek" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ra2a1_ek -DLOG=1 -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_ek" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ra6m1_ek -DLOG=1 -DLOGGER=RTT" />
<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_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="portenta_c33" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=portenta_c33 -DLOG=3" />
<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_cm4" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=raspberrypi_cm4 -DLOG=2" />
<configuration PROFILE_NAME="raspberrypi_zero2" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=raspberrypi_zero2 -DLOG=2" />
<configuration PROFILE_NAME="portenta_c33" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=portenta_c33 -DLOG=1" />
<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=1" />
<configuration PROFILE_NAME="raspberrypi_zero2" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=raspberrypi_zero2 -DLOG=1" />
<configuration PROFILE_NAME="lpcxpresso11u37" ENABLED="false" GENERATION_OPTIONS="-DBOARD=lpcxpresso11u37" />
<configuration PROFILE_NAME="lpcxpresso11u68" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso11u68 -DLOG=2 -DLOGGER=RTT" />
<configuration PROFILE_NAME="lpcxpresso1347" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso1347 -DLOG=2 -DLOGGER=RTT" />
<configuration PROFILE_NAME="lpcxpresso1549" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso1549 -DLOG=2 -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="msp_exp432e401y" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=msp_exp432e401y -DLOG=2" />
<configuration PROFILE_NAME="lpcxpresso11u68" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso11u68 -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="lpcxpresso1347" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso1347 -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="lpcxpresso1549" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso1549 -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="lpcxpresso51u68" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso51u68 -DLOG=1 -DLOGGER=RTT" />
<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="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="msp430f5529" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=msp_exp430f5529lp" />
<configuration PROFILE_NAME="msp_exp432e401y" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=msp_exp432e401y -DLOG=1" />
<configuration PROFILE_NAME="ek_tm4c123gxl" ENABLED="false" CONFIG_NAME="MinSizeRel" GENERATION_OPTIONS="-DBOARD=ek_tm4c123gxl -DLOG=1" />
<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="mm32f327x_mb39" ENABLED="false" GENERATION_OPTIONS="-DBOARD=mm32f327x_mb39" />
<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="sipeed_longan_nano" ENABLED="false" GENERATION_OPTIONS="-DBOARD=sipeed_longan_nano" />
<configuration PROFILE_NAME="nanoch32v203" ENABLED="false" GENERATION_OPTIONS="-DBOARD=nanoch32v203" />
<configuration PROFILE_NAME="ch32v203c_r0_1v0" ENABLED="false" CONFIG_NAME="MinSizeRel" GENERATION_OPTIONS="-DBOARD=ch32v203c_r0_1v0" />
<configuration PROFILE_NAME="ch32v203c_r0_1v0 USBFS" ENABLED="false" CONFIG_NAME="MinSizeRel" GENERATION_OPTIONS="-DBOARD=ch32v203c_r0_1v0 -DPORT=1" />
<configuration PROFILE_NAME="nanoch32v203" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=nanoch32v203" />
<configuration PROFILE_NAME="ch32v203c_r0_1v0" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ch32v203c_r0_1v0 -DLOG=0" />
<configuration PROFILE_NAME="ch32v203c_r0_1v0 USBFS" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ch32v203c_r0_1v0 -DPORT=1" />
<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=2" />
<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="da14695_dk_usb" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=da14695_dk_usb" />
<configuration PROFILE_NAME="max32650fthr" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=max32650fthr -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="max32666fthr" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=max32666fthr -DLOG=1 -DLOGGER=RTT" />
<configuration PROFILE_NAME="max32690evkit" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=max32690evkit -DLOG=1 -DLOGGER=RTT" />
</configurations>
</component>
</project>

View File

@@ -1,4 +1,4 @@
|Build Status| |Documentation Status| |Fuzzing Status| |License|
|Build Status| |CircleCI Status| |Documentation Status| |Fuzzing Status| |License|
Sponsors
========
@@ -109,7 +109,9 @@ Following CPUs are supported, check out `Supported Devices`_ for comprehensive l
+==============+============================================================+
| Allwinner | F1C100s/F1C200s |
+--------------+------------------------------------------------------------+
| Analog | MAX3421E (usb host shield) |
| Analog | max32: 650, 666, 690. max78002 |
| | |
| | max3421e (host) |
+--------------+------------------------------------------------------------+
| Brigetek | FT90x |
+--------------+------------------------------------------------------------+
@@ -197,6 +199,8 @@ Docs
.. |Build Status| image:: https://github.com/hathach/tinyusb/actions/workflows/cmake_arm.yml/badge.svg
:target: https://github.com/hathach/tinyusb/actions
.. |CircleCI Status| image:: https://dl.circleci.com/status-badge/img/circleci/4AYHvUhFxdnY4rA7LEsdqW/QmrpoL2AjGqetvFQNqtWyq/tree/master.svg?style=svg
:target: https://dl.circleci.com/status-badge/redirect/circleci/4AYHvUhFxdnY4rA7LEsdqW/QmrpoL2AjGqetvFQNqtWyq/tree/master
.. |Documentation Status| image:: https://readthedocs.org/projects/tinyusb/badge/?version=latest
:target: https://docs.tinyusb.org/en/latest/?badge=latest
.. |Fuzzing Status| image:: https://oss-fuzz-build-logs.storage.googleapis.com/badges/tinyusb.svg

View File

@@ -5,147 +5,142 @@ Supported Devices
Supported MCUs
==============
+--------------+-----------------------+--------+------+-----------+-------------------+--------------+
| Manufacturer | Family | Device | Host | Highspeed | Driver | Note |
+==============+=======================+========+======+===========+===================+==============+
| Allwinner | F1C100s/F1C200s | ✔ | | ✔ | sunxi | musb variant |
+--------------+-----------------------+--------+------+-----------+-------------------+--------------+
| Analog | MAX3421E | | ✔ | ✖ | max3421 | via SPI |
+--------------+-----------------------+--------+------+-----------+-------------------+--------------+
| Brigetek | FT90x | ✔ | | ✔ | ft9xx | |
+--------------+-----------------------+--------+------+-----------+-------------------+--------------+
| Broadcom | BCM2711, BCM2837 | ✔ | | ✔ | dwc2 | |
+--------------+-----------------------+--------+------+-----------+-------------------+--------------+
| Dialog | DA1469x | ✔ | ✖ | ✖ | da146xx | |
+--------------+-----------------------+--------+------+-----------+-------------------+--------------+
| Espressif | ESP32 S2, S3 | ✔ | | ✖ | dwc2 or esp32sx | |
+--------------+-----------------------+--------+------+-----------+-------------------+--------------+
| GigaDevice | GD32VF103 | ✔ | | ✖ | dwc2 | |
+--------------+-----------------------+--------+------+-----------+-------------------+--------------+
| Infineon | XMC4500 | ✔ | | ✖ | dwc2 | |
+--------------+-----+-----------------+--------+------+-----------+-------------------+--------------+
| MicroChip | SAM | D11, D21 | ✔ | | ✖ | samd | |
| | +-----------------+--------+------+-----------+-------------------+--------------+
| | | D51, E5x | ✔ | | ✖ | samd | |
| | +-----------------+--------+------+-----------+-------------------+--------------+
| | | G55 | ✔ | | ✖ | samg | |
| | +-----------------+--------+------+-----------+-------------------+--------------+
| | | L21, L22 | ✔ | | ✖ | samd | |
| | +-----------------+--------+------+-----------+-------------------+--------------+
| | | E70,S70,V70,V71 | ✔ | | ✔ | samx7x | |
| +-----+-----------------+--------+------+-----------+-------------------+--------------+
| | PIC | 24 | ✔ | | | pic | ci_fs variant|
| | +-----------------+--------+------+-----------+-------------------+--------------+
| | | 32 mm, mk, mx | ✔ | | | pic | ci_fs variant|
| | +-----------------+--------+------+-----------+-------------------+--------------+
| | | dsPIC33 | ✔ | | | pic | ci_fs variant|
| | +-----------------+--------+------+-----------+-------------------+--------------+
| | | 32mz | ✔ | | | pic32mz | musb variant |
+--------------+-----+-----------------+--------+------+-----------+-------------------+--------------+
| Mind Montion | mm32 | ✔ | | ✖ | mm32f327x_otg | ci_fs variant|
+--------------+-----+-----------------+--------+------+-----------+-------------------+--------------+
| NordicSemi | nRF52833, nRF52840 | ✔ | ✖ | ✖ | nrf5x | |
| +-----------------------+--------+------+-----------+-------------------+--------------+
| | nRF5340 | ✔ | ✖ | ✖ | nrf5x | |
+--------------+-----------------------+--------+------+-----------+-------------------+--------------+
| Nuvoton | NUC120 | ✔ | ✖ | ✖ | nuc120 | |
| +-----------------------+--------+------+-----------+-------------------+--------------+
| | NUC121/NUC125 | ✔ | ✖ | ✖ | nuc121 | |
| +-----------------------+--------+------+-----------+-------------------+--------------+
| | NUC126 | ✔ | ✖ | ✖ | nuc121 | |
| +-----------------------+--------+------+-----------+-------------------+--------------+
| | NUC505 | ✔ | | ✔ | nuc505 | |
+--------------+---------+-------------+--------+------+-----------+-------------------+--------------+
| NXP | iMXRT | RT10xx | ✔ | ✔ | ✔ | ci_hs | |
| | +-------------+--------+------+-----------+-------------------+--------------+
| | | RT11xx | ✔ | ✔ | ✔ | ci_hs | |
| +---------+-------------+--------+------+-----------+-------------------+--------------+
| | Kinetis | KL | ✔ | ⚠ | ✖ | ci_fs, khci | |
| | +-------------+--------+------+-----------+-------------------+--------------+
| | | K32L2 | ✔ | | ✖ | khci | ci_fs variant|
| +---------+-------------+--------+------+-----------+-------------------+--------------+
| | LPC | 11u, 13, 15 | ✔ | ✖ | ✖ | lpc_ip3511 | |
| | +-------------+--------+------+-----------+-------------------+--------------+
| | | 17, 40 | ✔ | ⚠ | ✖ | lpc17_40 | |
| | +-------------+--------+------+-----------+-------------------+--------------+
| | | 18, 43 | ✔ | ✔ | ✔ | ci_hs | |
| | +-------------+--------+------+-----------+-------------------+--------------+
| | | 51u | ✔ | ✖ | ✖ | lpc_ip3511 | |
| | +-------------+--------+------+-----------+-------------------+--------------+
| | | 54 | ✔ | | ✔ | lpc_ip3511 | |
| | +-------------+--------+------+-----------+-------------------+--------------+
| | | 55 | ✔ | | ✔ | lpc_ip3511 | |
| +---------+-------------+--------+------+-----------+-------------------+--------------+
| | MCX | N9 | ✔ | | ✔ | ci_fs, ci_hs | |
+--------------+---------+-------------+--------+------+-----------+-------------------+--------------+
| Raspberry Pi | RP2040 | | ✔ | ✖ | rp2040, pio_usb | |
+--------------+-----+-----------------+--------+------+-----------+-------------------+--------------+
| Renesas | RX | 63N, 65N, 72N | ✔ | ✔ | ✖ | rusb2 | |
| +-----+-----------------+--------+------+-----------+-------------------+--------------+
| | RA | 4M1, 4M3, 6M1 | ✔ | ✔ | ✖ | rusb2 | |
| | +-----------------+--------+------+-----------+-------------------+--------------+
| | | 6M5 | ✔ | ✔ | ✔ | rusb2 | |
+--------------+-----+-----------------+--------+------+-----------+-------------------+--------------+
| Silabs | EFM32GG12 | ✔ | | ✖ | dwc2 | |
+--------------+-----------------------+--------+------+-----------+-------------------+--------------+
| Sony | CXD56 | | ✖ | ✔ | cxd56 | |
+--------------+-----------------------+--------+------+-----------+-------------------+--------------+
| ST STM32 | F0 | ✔ | ✖ | ✖ | stm32_fsdev | |
| +----+------------------+--------+------+-----------+-------------------+--------------+
| | F1 | 102, 103 | ✔ | ✖ | ✖ | stm32_fsdev | |
| | +------------------+--------+------+-----------+-------------------+--------------+
| | | 105, 107 | ✔ | | ✖ | dwc2 | |
| +----+------------------+--------+------+-----------+-------------------+--------------+
| | F2 | ✔ | | ✔ | dwc2 | |
| +-----------------------+--------+------+-----------+-------------------+--------------+
| | F3 | ✔ | ✖ | ✖ | stm32_fsdev | |
| +-----------------------+--------+------+-----------+-------------------+--------------+
| | F4 | ✔ | | ✔ | dwc2 | |
| +-----------------------+--------+------+-----------+-------------------+--------------+
| | F7 | ✔ | | ✔ | dwc2 | |
| +-----------------------+--------+------+-----------+-------------------+--------------+
| | G0 | ✔ | | ✖ | stm32_fsdev | |
| +-----------------------+--------+------+-----------+-------------------+--------------+
| | G4 | ✔ | ✖ | ✖ | stm32_fsdev | |
| +-----------------------+--------+------+-----------+-------------------+--------------+
| | H5 | ✔ | | ✖ | stm32_fsdev | |
| +-----------------------+--------+------+-----------+-------------------+--------------+
| | H7 | ✔ | | ✔ | dwc2 | |
| +-----------------------+--------+------+-----------+-------------------+--------------+
| | L0 | ✔ | ✖ | ✖ | stm32_fsdev | |
| +-----------------------+--------+------+-----------+-------------------+--------------+
| | L1 | ✔ | ✖ | ✖ | stm32_fsdev | |
| +----+------------------+--------+------+-----------+-------------------+--------------+
| | L4 | 4x2, 4x3 | ✔ | ✖ | ✖ | stm32_fsdev | |
| | +------------------+--------+------+-----------+-------------------+--------------+
| | | 4x5, 4x6 | ✔ | | ✖ | dwc2 | |
| +----+------------------+--------+------+-----------+-------------------+--------------+
| | L4+ | ✔ | | ✖ | dwc2 | |
| +-----------------------+--------+------+-----------+-------------------+--------------+
| | L5 | ✔ | ✖ | ✖ | stm32_fsdev | |
| +----+------------------+--------+------+-----------+-------------------+--------------+
| | U5 | 535, 545 | ✔ | | ✖ | stm32_fsdev | |
| | +------------------+--------+------+-----------+-------------------+--------------+
| | | 575, 585 | ✔ | | ✖ | dwc2 | |
| | +------------------+--------+------+-----------+-------------------+--------------+
| | | 59x,5Ax,5Fx,5Gx | ✔ | | ✔ | dwc2 | |
| +----+------------------+--------+------+-----------+-------------------+--------------+
| | WBx5 | ✔ | ✖ | ✖ | stm32_fsdev | |
+--------------+-----------------------+--------+------+-----------+-------------------+--------------+
| TI | MSP430 | ✔ | ✖ | ✖ | msp430x5xx | |
| +-----------------------+--------+------+-----------+-------------------+--------------+
| | MSP432E4 | ✔ | | ✖ | musb | |
| +-----------------------+--------+------+-----------+-------------------+--------------+
| | TM4C123 | ✔ | | ✖ | musb | |
+--------------+-----------------------+--------+------+-----------+-------------------+--------------+
| ValentyUSB | eptri | ✔ | ✖ | ✖ | eptri | |
+--------------+-----------------------+--------+------+-----------+-------------------+--------------+
| WCH | CH32F20x | ✔ | | ✔ | ch32f205 | |
| +-----------------------+--------+------+-----------+-------------------+--------------+
| | CH32V20x | ✔ | | ✖ | ch32v20x | |
| +-----------------------+--------+------+-----------+-------------------+--------------+
| | CH32V307 | ✔ | | ✔ | ch32v307 | |
+--------------+-----------------------+--------+------+-----------+-------------------+--------------+
+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+
| Manufacturer | Family | Device | Host | Highspeed | Driver | Note |
+==============+=============================+========+======+===========+===================+===================+
| Allwinner | F1C100s/F1C200s | ✔ | | ✔ | sunxi | musb variant |
+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+
| Analog | MAX3421E | | ✔ | ✖ | max3421 | via SPI |
| +-----------------------------+--------+------+-----------+-------------------+-------------------+
| | MAX32 650, 666, 690, | ✔ | | ✔ | musb | 1-dir ep |
| | MAX78002 | | | | | |
+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+
| Brigetek | FT90x | ✔ | | ✔ | ft9xx | 1-dir ep |
+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+
| Broadcom | BCM2711, BCM2837 | ✔ | | ✔ | dwc2 | |
+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+
| Dialog | DA1469x | ✔ | ✖ | ✖ | da146xx | |
+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+
| Espressif | ESP32 S2, S3 | ✔ | | ✖ | dwc2 or esp32sx | |
+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+
| GigaDevice | GD32VF103 | ✔ | | ✖ | dwc2 | |
+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+
| Infineon | XMC4500 | ✔ | | ✖ | dwc2 | |
+--------------+-----+-----------------------+--------+------+-----------+-------------------+-------------------+
| MicroChip | SAM | D11, D21, L21, L22 | ✔ | | ✖ | samd | |
| | +-----------------------+--------+------+-----------+-------------------+-------------------+
| | | D51, E5x | ✔ | | ✖ | samd | |
| | +-----------------------+--------+------+-----------+-------------------+-------------------+
| | | G55 | ✔ | | ✖ | samg | 1-dir ep |
| | +-----------------------+--------+------+-----------+-------------------+-------------------+
| | | E70,S70,V70,V71 | ✔ | | ✔ | samx7x | 1-dir ep |
| +-----+-----------------------+--------+------+-----------+-------------------+-------------------+
| | PIC | 24 | ✔ | | | pic | ci_fs variant |
| | +-----------------------+--------+------+-----------+-------------------+-------------------+
| | | 32 mm, mk, mx | ✔ | | | pic | ci_fs variant |
| | +-----------------------+--------+------+-----------+-------------------+-------------------+
| | | dsPIC33 | ✔ | | | pic | ci_fs variant |
| | +-----------------------+--------+------+-----------+-------------------+-------------------+
| | | 32mz | ✔ | | | pic32mz | musb variant |
+--------------+-----+-----------------------+--------+------+-----------+-------------------+-------------------+
| Mind Montion | mm32 | ✔ | | ✖ | mm32f327x_otg | ci_fs variant |
+--------------+-----+-----------------------+--------+------+-----------+-------------------+-------------------+
| NordicSemi | nRF 52833, 52840, 5340 | ✔ | ✖ | ✖ | nrf5x | only ep8 is ISO |
+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+
| Nuvoton | NUC120 | ✔ | ✖ | ✖ | nuc120 | |
| +-----------------------------+--------+------+-----------+-------------------+-------------------+
| | NUC121/NUC125 | ✔ | ✖ | ✖ | nuc121 | |
| +-----------------------------+--------+------+-----------+-------------------+-------------------+
| | NUC126 | ✔ | ✖ | ✖ | nuc121 | |
| +-----------------------------+--------+------+-----------+-------------------+-------------------+
| | NUC505 | ✔ | | ✔ | nuc505 | |
+--------------+---------+-------------------+--------+------+-----------+-------------------+-------------------+
| NXP | iMXRT | RT 10xx, 11xx | ✔ | ✔ | ✔ | ci_hs | |
| +---------+-------------------+--------+------+-----------+-------------------+-------------------+
| | Kinetis | KL | ✔ | ⚠ | ✖ | ci_fs, khci | |
| | +-------------------+--------+------+-----------+-------------------+-------------------+
| | | K32L2 | ✔ | | ✖ | khci | ci_fs variant |
| +---------+-------------------+--------+------+-----------+-------------------+-------------------+
| | LPC | 11u, 13, 15 | ✔ | ✖ | ✖ | lpc_ip3511 | |
| | +-------------------+--------+------+-----------+-------------------+-------------------+
| | | 17, 40 | ✔ | ⚠ | ✖ | lpc17_40 | |
| | +-------------------+--------+------+-----------+-------------------+-------------------+
| | | 18, 43 | ✔ | ✔ | ✔ | ci_hs | |
| | +-------------------+--------+------+-----------+-------------------+-------------------+
| | | 51u | ✔ | ✖ | ✖ | lpc_ip3511 | |
| | +-------------------+--------+------+-----------+-------------------+-------------------+
| | | 54, 55 | ✔ | | ✔ | lpc_ip3511 | |
| +---------+-------------------+--------+------+-----------+-------------------+-------------------+
| | MCX | N9 | ✔ | | ✔ | ci_fs, ci_hs | |
+--------------+---------+-------------------+--------+------+-----------+-------------------+-------------------+
| Raspberry Pi | RP2040, RP2350 | ✔ | ✔ | ✖ | rp2040, pio_usb | |
+--------------+-----+-----------------------+--------+------+-----------+-------------------+-------------------+
| Renesas | RX | 63N, 65N, 72N | ✔ | ✔ | ✖ | rusb2 | |
| +-----+-----------------------+--------+------+-----------+-------------------+-------------------+
| | RA | 4M1, 4M3, 6M1 | ✔ | ✔ | ✖ | rusb2 | |
| | +-----------------------+--------+------+-----------+-------------------+-------------------+
| | | 6M5 | ✔ | ✔ | ✔ | rusb2 | |
+--------------+-----+-----------------------+--------+------+-----------+-------------------+-------------------+
| Silabs | EFM32GG12 | ✔ | | ✖ | dwc2 | |
+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+
| Sony | CXD56 | ✔ | ✖ | ✔ | cxd56 | |
+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+
| ST STM32 | F0 | ✔ | ✖ | ✖ | stm32_fsdev | |
| +----+------------------------+--------+------+-----------+-------------------+-------------------+
| | F1 | 102, 103 | ✔ | ✖ | ✖ | stm32_fsdev | |
| | +------------------------+--------+------+-----------+-------------------+-------------------+
| | | 105, 107 | ✔ | | ✖ | dwc2 | |
| +----+------------------------+--------+------+-----------+-------------------+-------------------+
| | F2 | ✔ | | ✔ | dwc2 | |
| +-----------------------------+--------+------+-----------+-------------------+-------------------+
| | F3 | ✔ | ✖ | ✖ | stm32_fsdev | |
| +-----------------------------+--------+------+-----------+-------------------+-------------------+
| | F4 | ✔ | | ✔ | dwc2 | |
| +-----------------------------+--------+------+-----------+-------------------+-------------------+
| | F7 | ✔ | | ✔ | dwc2 | |
| +-----------------------------+--------+------+-----------+-------------------+-------------------+
| | G0 | ✔ | | ✖ | stm32_fsdev | |
| +-----------------------------+--------+------+-----------+-------------------+-------------------+
| | G4 | ✔ | ✖ | ✖ | stm32_fsdev | |
| +-----------------------------+--------+------+-----------+-------------------+-------------------+
| | H5 | ✔ | | ✖ | stm32_fsdev | |
| +-----------------------------+--------+------+-----------+-------------------+-------------------+
| | H7 | ✔ | | ✔ | dwc2 | |
| +-----------------------------+--------+------+-----------+-------------------+-------------------+
| | L0 | ✔ | ✖ | ✖ | stm32_fsdev | |
| +-----------------------------+--------+------+-----------+-------------------+-------------------+
| | L1 | ✔ | ✖ | ✖ | stm32_fsdev | |
| +----+------------------------+--------+------+-----------+-------------------+-------------------+
| | L4 | 4x2, 4x3 | ✔ | ✖ | ✖ | stm32_fsdev | |
| | +------------------------+--------+------+-----------+-------------------+-------------------+
| | | 4x5, 4x6 | ✔ | | ✖ | dwc2 | |
| +----+------------------------+--------+------+-----------+-------------------+-------------------+
| | L4+ | ✔ | | ✖ | dwc2 | |
| +-----------------------------+--------+------+-----------+-------------------+-------------------+
| | L5 | ✔ | ✖ | ✖ | stm32_fsdev | |
| +----+------------------------+--------+------+-----------+-------------------+-------------------+
| | U5 | 535, 545 | ✔ | | ✖ | stm32_fsdev | |
| | +------------------------+--------+------+-----------+-------------------+-------------------+
| | | 575, 585 | ✔ | | ✖ | dwc2 | |
| | +------------------------+--------+------+-----------+-------------------+-------------------+
| | | 59x,5Ax,5Fx,5Gx | ✔ | | ✔ | dwc2 | |
| +----+------------------------+--------+------+-----------+-------------------+-------------------+
| | WBx5 | ✔ | ✖ | ✖ | stm32_fsdev | |
+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+
| TI | MSP430 | ✔ | ✖ | ✖ | msp430x5xx | |
| +-----------------------------+--------+------+-----------+-------------------+-------------------+
| | MSP432E4 | ✔ | | ✖ | musb | |
| +-----------------------------+--------+------+-----------+-------------------+-------------------+
| | TM4C123 | ✔ | | ✖ | musb | |
+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+
| ValentyUSB | eptri | ✔ | ✖ | ✖ | eptri | |
+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+
| WCH | CH32F20x | ✔ | | ✔ | ch32f205 | |
| +-----------------------------+--------+------+-----------+-------------------+-------------------+
| | CH32V20x | ✔ | | ✖ | ch32v20x | |
| +-----------------------------+--------+------+-----------+-------------------+-------------------+
| | CH32V307 | ✔ | | ✔ | ch32v307 | |
+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+
Table Legend

View File

@@ -166,6 +166,11 @@ flash-bmp: $(BUILD)/$(PROJECT).elf
debug-bmp: $(BUILD)/$(PROJECT).elf
$(GDB) -ex 'target extended-remote $(BMP)' -ex 'monitor swdp_scan' -ex 'attach 1' $<
# --------------- TI Uniflash -----------------
DSLITE ?= dslite.sh
flash-uniflash: $(BUILD)/$(PROJECT).hex
${DSLITE} ${UNIFLASH_OPTION} -f $<
#-------------- Artifacts --------------
# Create binary directory

View File

@@ -98,19 +98,19 @@ enum
#define EPNUM_CDC_1_OUT 0x05
#define EPNUM_CDC_1_IN 0x85
#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_0_NOTIF 0x81
#elif CFG_TUSB_MCU == OPT_MCU_CXD56
// 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_0_NOTIF 0x83
#define EPNUM_CDC_0_OUT 0x02
#define EPNUM_CDC_0_IN 0x83
#define EPNUM_CDC_0_IN 0x81
#define EPNUM_CDC_1_NOTIF 0x84
#define EPNUM_CDC_1_NOTIF 0x86
#define EPNUM_CDC_1_OUT 0x05
#define EPNUM_CDC_1_IN 0x86
#define EPNUM_CDC_1_IN 0x84
#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
#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY)
// MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h
// e.g EP1 OUT & EP1 IN cannot exist together
#define EPNUM_CDC_0_NOTIF 0x81
#define EPNUM_CDC_0_OUT 0x02

View File

@@ -93,19 +93,7 @@ enum {
#define EPNUM_MSC_OUT 0x05
#define EPNUM_MSC_IN 0x85
#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
#define EPNUM_MSC_OUT 0x04
#define EPNUM_MSC_IN 0x85
#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
@@ -115,8 +103,8 @@ enum {
#define EPNUM_MSC_OUT 0x05
#define EPNUM_MSC_IN 0x84
#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
#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY)
// MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h
// e.g EP1 OUT & EP1 IN cannot exist together
#define EPNUM_CDC_NOTIF 0x81
#define EPNUM_CDC_OUT 0x02

View File

@@ -42,8 +42,7 @@
//--------------------------------------------------------------------+
// Device Descriptors
//--------------------------------------------------------------------+
tusb_desc_device_t const desc_device =
{
tusb_desc_device_t const desc_device = {
.bLength = sizeof(tusb_desc_device_t),
.bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = USB_BCD,
@@ -69,8 +68,7 @@ tusb_desc_device_t const desc_device =
// Invoked when received GET DEVICE 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;
}
@@ -78,8 +76,7 @@ uint8_t const * tud_descriptor_device_cb(void)
// Configuration Descriptor
//--------------------------------------------------------------------+
enum
{
enum {
ITF_NUM_CDC = 0,
ITF_NUM_CDC_DATA,
ITF_NUM_MSC,
@@ -96,8 +93,18 @@ enum
#define EPNUM_MSC_OUT 0x05
#define EPNUM_MSC_IN 0x85
#elif CFG_TUSB_MCU == OPT_MCU_SAMG
// SAMG doesn't support a same endpoint number with different direction IN and OUT
#elif CFG_TUSB_MCU == OPT_MCU_CXD56
// 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
#define EPNUM_MSC_OUT 0x05
#define EPNUM_MSC_IN 0x84
#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY)
// MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h
// e.g EP1 OUT & EP1 IN cannot exist together
#define EPNUM_CDC_NOTIF 0x81
#define EPNUM_CDC_OUT 0x02

View File

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

View File

@@ -97,18 +97,8 @@ uint8_t const * tud_descriptor_device_cb(void)
#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_AUDIO_IN 0x01
#define EPNUM_AUDIO_OUT 0x02
#define EPNUM_CDC_NOTIF 0x83
#define EPNUM_CDC_OUT 0x04
#define EPNUM_CDC_IN 0x85
#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
#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY)
// MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h
// e.g EP1 OUT & EP1 IN cannot exist together
#define EPNUM_AUDIO_IN 0x01
#define EPNUM_AUDIO_OUT 0x02

View File

@@ -132,21 +132,8 @@ enum
#define EPNUM_1_MSC_OUT 0x02
#define EPNUM_1_MSC_IN 0x82
#elif CFG_TUSB_MCU == OPT_MCU_SAMG
// SAMG doesn't support a same endpoint number with different direction IN and OUT
// e.g EP1 OUT & EP1 IN cannot exist together
#define EPNUM_0_CDC_NOTIF 0x81
#define EPNUM_0_CDC_OUT 0x02
#define EPNUM_0_CDC_IN 0x83
#define EPNUM_0_MIDI_OUT 0x04
#define EPNUM_0_MIDI_IN 0x85
#define EPNUM_1_MSC_OUT 0x01
#define EPNUM_1_MSC_IN 0x82
#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
#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY)
// MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h
// e.g EP1 OUT & EP1 IN cannot exist together
#define EPNUM_0_CDC_NOTIF 0x81
#define EPNUM_0_CDC_OUT 0x02

View File

@@ -84,15 +84,24 @@ enum
#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_MIDI_OUT 0x02
#define EPNUM_MIDI_IN 0x02
#elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X
// On Bridgetek FT9xx endpoint numbers must be unique...
#define EPNUM_MIDI_OUT 0x02
#define EPNUM_MIDI_IN 0x03
#define EPNUM_MIDI_OUT 0x02
#define EPNUM_MIDI_IN 0x82
#elif CFG_TUSB_MCU == OPT_MCU_CXD56
// 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_MIDI_OUT 0x02
#define EPNUM_MIDI_IN 0x81
#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY)
// MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h
// e.g EP1 OUT & EP1 IN cannot exist together
#define EPNUM_MIDI_OUT 0x01
#define EPNUM_MIDI_IN 0x82
#else
#define EPNUM_MIDI_OUT 0x01
#define EPNUM_MIDI_IN 0x01
#define EPNUM_MIDI_OUT 0x01
#define EPNUM_MIDI_IN 0x81
#endif
uint8_t const desc_fs_configuration[] =

View File

@@ -85,17 +85,17 @@ enum
#define EPNUM_MSC_OUT 0x02
#define EPNUM_MSC_IN 0x82
#elif CFG_TUSB_MCU == OPT_MCU_SAMG
// SAMG doesn't support a same endpoint number with different direction IN and OUT
// e.g EP1 OUT & EP1 IN cannot exist together
#define EPNUM_MSC_OUT 0x01
#define EPNUM_MSC_IN 0x82
#elif CFG_TUSB_MCU == OPT_MCU_CXD56
// 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_MSC_OUT 0x02
#define EPNUM_MSC_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
#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY)
// MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h
// e.g EP1 OUT & EP1 IN cannot exist together
#define EPNUM_MSC_OUT 0x01
#define EPNUM_MSC_IN 0x82
#define EPNUM_MSC_OUT 0x01
#define EPNUM_MSC_IN 0x82
#else
#define EPNUM_MSC_OUT 0x01

View File

@@ -91,6 +91,8 @@ extern "C" {
#define USE_ECM 1
#elif TU_CHECK_MCU(OPT_MCU_STM32F0, OPT_MCU_STM32F1)
#define USE_ECM 1
#elif TU_CHECK_MCU(OPT_MCU_MAX32690, OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX78002)
#define USE_ECM 1
#else
#define USE_ECM 0
#define INCLUDE_IPERF

View File

@@ -113,8 +113,15 @@ uint8_t const * tud_descriptor_device_cb(void)
#define EPNUM_NET_OUT 0x02
#define EPNUM_NET_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
#elif CFG_TUSB_MCU == OPT_MCU_CXD56
// 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_NET_NOTIF 0x83
#define EPNUM_NET_OUT 0x02
#define EPNUM_NET_IN 0x81
#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY)
// MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h
// e.g EP1 OUT & EP1 IN cannot exist together
#define EPNUM_NET_NOTIF 0x81
#define EPNUM_NET_OUT 0x02

View File

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

View File

@@ -84,21 +84,21 @@ uint8_t const * tud_descriptor_device_cb(void)
#define EPNUM_AUDIO_OUT 0x03
#define EPNUM_AUDIO_INT 0x01
#elif CFG_TUSB_MCU == OPT_MCU_CXD56
// 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_AUDIO_IN 0x01
// #define EPNUM_AUDIO_OUT 0x02
// #define EPNUM_AUDIO_INT 0x03
#elif CFG_TUSB_MCU == OPT_MCU_NRF5X
// ISO endpoints for NRF5x are fixed to 0x08 (0x88)
#define EPNUM_AUDIO_IN 0x08
#define EPNUM_AUDIO_OUT 0x08
#define EPNUM_AUDIO_INT 0x01
#elif CFG_TUSB_MCU == OPT_MCU_SAMG || CFG_TUSB_MCU == OPT_MCU_SAMX7X
// SAMG & SAME70 don't support a same endpoint number with different direction IN and OUT
// e.g EP1 OUT & EP1 IN cannot exist together
#define EPNUM_AUDIO_IN 0x01
#define EPNUM_AUDIO_OUT 0x02
#define EPNUM_AUDIO_INT 0x03
#elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X
// FT9XX doesn't support a same endpoint number with different direction IN and OUT
#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY)
// MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h
// e.g EP1 OUT & EP1 IN cannot exist together
#define EPNUM_AUDIO_IN 0x01
#define EPNUM_AUDIO_OUT 0x02

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

View 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

View File

@@ -0,0 +1,8 @@
mcu:LPC11UXX
mcu:LPC13XX
mcu:NUC121
mcu:SAMD11
mcu:SAME5X
mcu:SAMG
board:stm32l052dap52
family:broadcom_64bit

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

View File

@@ -1,7 +1,7 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2021, Ha Thach (tinyusb.org)
* 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
@@ -21,20 +21,32 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#ifndef _TUSB_MUSB_MSP432E_H_
#define _TUSB_MUSB_MSP432E_H_
#ifndef _COMMON_TYPES_H_
#define _COMMON_TYPES_H_
#ifdef __cplusplus
extern "C" {
enum
{
ITF_NUM_AUDIO_CONTROL = 0,
ITF_NUM_AUDIO_STREAMING,
#if CFG_AUDIO_DEBUG
ITF_NUM_DEBUG,
#endif
ITF_NUM_TOTAL
};
#include "msp.h"
#ifdef __cplusplus
}
#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

View 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

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

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

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

View File

@@ -0,0 +1,288 @@
/*
* 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 defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY)
// MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h
// 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;
}

View 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

View File

@@ -106,7 +106,7 @@
#define CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE 256
// use bulk endpoint for streaming interface
#define CFG_TUD_VIDEO_STREAMING_BULK 1
#define CFG_TUD_VIDEO_STREAMING_BULK 0
//#define CFG_EXAMPLE_VIDEO_READONLY
//#define CFG_EXAMPLE_VIDEO_DISABLE_MJPEG

View File

@@ -118,6 +118,8 @@ enum {
#elif TU_CHECK_MCU(OPT_MCU_NRF5X)
// nRF5x ISO can only be endpoint 8
#define EPNUM_VIDEO_IN (CFG_TUD_VIDEO_STREAMING_BULK ? 0x81 : 0x88)
#elif TU_CHECK_MCU(OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX32690, OPT_MCU_MAX78002)
#define EPNUM_VIDEO_IN 0x81
#else
#define EPNUM_VIDEO_IN 0x81
#endif

View File

@@ -87,29 +87,40 @@ enum
#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_CDC_IN 2
#define EPNUM_CDC_OUT 2
#define EPNUM_VENDOR_IN 5
#define EPNUM_VENDOR_OUT 5
#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
#define EPNUM_CDC_NOTIF 0x81
#define EPNUM_CDC_OUT 0x02
#define EPNUM_CDC_IN 0x82
#define EPNUM_VENDOR_OUT 0x05
#define EPNUM_VENDOR_IN 0x85
#elif CFG_TUSB_MCU == OPT_MCU_CXD56
// 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
#define EPNUM_VENDOR_OUT 0x05
#define EPNUM_VENDOR_IN 0x84
#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY)
// MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h
// e.g EP1 OUT & EP1 IN cannot exist together
#define EPNUM_CDC_IN 2
#define EPNUM_CDC_OUT 3
#define EPNUM_VENDOR_IN 4
#define EPNUM_VENDOR_OUT 5
#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_IN 2
#define EPNUM_CDC_OUT 3
#define EPNUM_VENDOR_IN 4
#define EPNUM_VENDOR_OUT 5
#define EPNUM_CDC_NOTIF 0x81
#define EPNUM_CDC_OUT 0x02
#define EPNUM_CDC_IN 0x83
#define EPNUM_VENDOR_OUT 0x04
#define EPNUM_VENDOR_IN 0x85
#else
#define EPNUM_CDC_IN 2
#define EPNUM_CDC_OUT 2
#define EPNUM_VENDOR_IN 3
#define EPNUM_VENDOR_OUT 3
#define EPNUM_CDC_NOTIF 0x81
#define EPNUM_CDC_OUT 0x02
#define EPNUM_CDC_IN 0x82
#define EPNUM_VENDOR_OUT 0x03
#define EPNUM_VENDOR_IN 0x83
#endif
uint8_t const desc_configuration[] =
@@ -118,7 +129,7 @@ uint8_t const desc_configuration[] =
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, 0x81, 8, EPNUM_CDC_OUT, 0x80 | EPNUM_CDC_IN, TUD_OPT_HIGH_SPEED ? 512 : 64),
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, 0x80 | EPNUM_CDC_IN, TUD_OPT_HIGH_SPEED ? 512 : 64),
// Interface number, string index, EP Out & IN address, EP size
TUD_VENDOR_DESCRIPTOR(ITF_NUM_VENDOR, 5, EPNUM_VENDOR_OUT, 0x80 | EPNUM_VENDOR_IN, TUD_OPT_HIGH_SPEED ? 512 : 64)

View File

@@ -24,7 +24,7 @@
*/
/* Host example will get device descriptors of attached devices and print it out via device cdc as follows:
* Device 1: ID 046d:c52f
* Device 1: ID 046d:c52f SN 11223344
Device Descriptor:
bLength 18
bDescriptorType 1
@@ -147,7 +147,21 @@ void print_device_info(uint8_t daddr) {
return;
}
cdc_printf("Device %u: ID %04x:%04x\r\n", daddr, desc_device.idVendor, desc_device.idProduct);
// Get String descriptor using Sync API
uint16_t serial[64];
uint16_t buf[128];
cdc_printf("Device %u: ID %04x:%04x SN ", daddr, desc_device.idVendor, desc_device.idProduct);
xfer_result = tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, serial, sizeof(serial));
if (XFER_RESULT_SUCCESS != xfer_result) {
serial[0] = 'n';
serial[1] = '/';
serial[2] = 'a';
serial[3] = 0;
}
print_utf16(serial, TU_ARRAY_SIZE(serial));
tud_cdc_write_str("\r\n");
cdc_printf("Device Descriptor:\r\n");
cdc_printf(" bLength %u\r\n" , desc_device.bLength);
cdc_printf(" bDescriptorType %u\r\n" , desc_device.bDescriptorType);
@@ -160,9 +174,6 @@ void print_device_info(uint8_t daddr) {
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 ) {
@@ -178,10 +189,7 @@ void print_device_info(uint8_t daddr) {
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((char*)serial); // serial is already to UTF-8
tud_cdc_write_str("\r\n");
cdc_printf(" bNumConfigurations %u\r\n" , desc_device.bNumConfigurations);

View File

@@ -170,6 +170,18 @@
#elif TU_CHECK_MCU(OPT_MCU_BCM2711, OPT_MCU_BCM2835, OPT_MCU_BCM2837)
// no header needed
#elif CFG_TUSB_MCU == OPT_MCU_MAX32690
#include "max32690.h"
#elif CFG_TUSB_MCU == OPT_MCU_MAX32650
#include "max32650.h"
#elif CFG_TUSB_MCU == OPT_MCU_MAX32666
#include "max32665.h"
#elif CFG_TUSB_MCU == OPT_MCU_MAX78002
#include "max78002.h"
#else
#error "Missing MCU header"
#endif

View File

@@ -1,8 +1,8 @@
set(MCU_VARIANT D6)
# 64KB zero-wait, 224KB total flash
#set(LD_FLASH_SIZE 64K)
set(LD_FLASH_SIZE 224K)
set(LD_FLASH_SIZE 64K)
#set(LD_FLASH_SIZE 224K)
set(LD_RAM_SIZE 20K)
function(update_board TARGET)

View File

@@ -399,6 +399,11 @@ function(family_flash_jlink TARGET)
set(JLINK_IF swd)
endif ()
if (NOT DEFINED JLINK_OPTION)
set(JLINK_OPTION "")
endif ()
separate_arguments(OPTION_LIST UNIX_COMMAND ${JLINK_OPTION})
file(GENERATE
OUTPUT $<TARGET_FILE_DIR:${TARGET}>/${TARGET}.jlink
CONTENT "halt
@@ -410,7 +415,8 @@ exit"
add_custom_target(${TARGET}-jlink
DEPENDS ${TARGET}
COMMAND ${JLINKEXE} -device ${JLINK_DEVICE} -if ${JLINK_IF} -JTAGConf -1,-1 -speed auto -CommandFile $<TARGET_FILE_DIR:${TARGET}>/${TARGET}.jlink
COMMAND ${JLINKEXE} -device ${JLINK_DEVICE} ${OPTION_LIST} -if ${JLINK_IF} -JTAGConf -1,-1 -speed auto -CommandFile $<TARGET_FILE_DIR:${TARGET}>/${TARGET}.jlink
VERBATIM
)
endfunction()
@@ -457,7 +463,7 @@ function(family_flash_openocd TARGET)
# note skip verify since it has issue with rp2040
add_custom_target(${TARGET}-openocd
DEPENDS ${TARGET}
COMMAND ${OPENOCD} ${OPTION_LIST} -c init -c halt -c "program $<TARGET_FILE:${TARGET}> reset" ${OPTION_LIST2} -c exit
COMMAND ${OPENOCD} -c "tcl_port disabled" -c "gdb_port disabled" ${OPTION_LIST} -c init -c halt -c "program $<TARGET_FILE:${TARGET}>" -c reset ${OPTION_LIST2} -c exit
VERBATIM
)
endfunction()
@@ -474,6 +480,25 @@ function(family_flash_openocd_wch TARGET)
endfunction()
# Add flash openocd adi (Analog Devices) target
# included with msdk or compiled from release branch of https://github.com/analogdevicesinc/openocd
function(family_flash_openocd_adi TARGET)
if (DEFINED $ENV{MAXIM_PATH})
# use openocd from msdk
set(OPENOCD ENV{MAXIM_PATH}/Tools/OpenOCD/openocd)
set(OPENOCD_OPTION2 "-s ENV{MAXIM_PATH}/Tools/OpenOCD/scripts")
else()
# compiled from source
if (NOT DEFINED OPENOCD_ADI_PATH)
set(OPENOCD_ADI_PATH $ENV{HOME}/app/openocd_adi)
endif ()
set(OPENOCD ${OPENOCD_ADI_PATH}/src/openocd)
set(OPENOCD_OPTION2 "-s ${OPENOCD_ADI_PATH}/tcl")
endif ()
family_flash_openocd(${TARGET})
endfunction()
# Add flash with https://github.com/ch32-rs/wlink
function(family_flash_wlink_rs TARGET)
if (NOT DEFINED WLINK_RS)
@@ -567,6 +592,21 @@ function(family_flash_msp430flasher TARGET)
)
endfunction()
function(family_flash_uniflash TARGET)
if (NOT DEFINED DSLITE)
set(DSLITE dslite.sh)
endif ()
separate_arguments(OPTION_LIST UNIX_COMMAND ${UNIFLASH_OPTION})
add_custom_target(${TARGET}-uniflash
DEPENDS ${TARGET}
COMMAND ${DSLITE} ${UNIFLASH_OPTION} -f $<TARGET_FILE_DIR:${TARGET}>/${TARGET}.hex
VERBATIM
)
endfunction()
#----------------------------------
# Family specific
#----------------------------------

View File

@@ -81,44 +81,73 @@ void USB1_IRQHandler(void) {
}
/****************************************************************
name: BOARD_BootClockFROHF96M
name: BOARD_BootClockPLL100M
outputs:
- {id: SYSTICK_clock.outFreq, value: 96 MHz}
- {id: System_clock.outFreq, value: 96 MHz}
- {id: System_clock.outFreq, value: 100 MHz}
settings:
- {id: SYSCON.MAINCLKSELA.sel, value: SYSCON.fro_hf}
- {id: PLL0_Mode, value: Normal}
- {id: ANALOG_CONTROL_FRO192M_CTRL_ENDI_FRO_96M_CFG, value: Enable}
- {id: ENABLE_CLKIN_ENA, value: Enabled}
- {id: ENABLE_SYSTEM_CLK_OUT, value: Enabled}
- {id: SYSCON.MAINCLKSELB.sel, value: SYSCON.PLL0_BYPASS}
- {id: SYSCON.PLL0CLKSEL.sel, value: SYSCON.CLK_IN_EN}
- {id: SYSCON.PLL0M_MULT.scale, value: '100', locked: true}
- {id: SYSCON.PLL0N_DIV.scale, value: '4', locked: true}
- {id: SYSCON.PLL0_PDEC.scale, value: '4', locked: true}
sources:
- {id: SYSCON.fro_hf.outFreq, value: 96 MHz}
- {id: ANACTRL.fro_hf.outFreq, value: 96 MHz}
- {id: SYSCON.XTAL32M.outFreq, value: 16 MHz, enabled: true}
******************************************************************/
void BootClockFROHF96M(void) {
/*!< Set up the clock sources */
/*!< Set up FRO */
POWER_DisablePD(kPDRUNCFG_PD_FRO192M); /*!< Ensure FRO is on */
CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */
CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change voltage without
accidentally being below the voltage for current speed */
void BOARD_BootClockPLL100M(void)
{
/*!< Set up the clock sources */
/*!< Configure FRO192M */
POWER_DisablePD(kPDRUNCFG_PD_FRO192M); /*!< Ensure FRO is on */
CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */
CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change the clock setting */
CLOCK_SetupFROClocking(96000000U); /*!< Set up high frequency FRO output to selected frequency */
CLOCK_SetupFROClocking(96000000U); /* Enable FRO HF(96MHz) output */
POWER_SetVoltageForFreq(96000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */
CLOCK_SetFLASHAccessCyclesForFreq(96000000U); /*!< Set FLASH wait states for core */
/*!< Configure XTAL32M */
POWER_DisablePD(kPDRUNCFG_PD_XTAL32M); /* Ensure XTAL32M is powered */
POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M); /* Ensure XTAL32M is powered */
CLOCK_SetupExtClocking(16000000U); /* Enable clk_in clock */
SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; /* Enable clk_in from XTAL32M clock */
ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK; /* Enable clk_in to system */
/*!< Set up dividers */
CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */
POWER_SetVoltageForFreq(100000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */
CLOCK_SetFLASHAccessCyclesForFreq(100000000U); /*!< Set FLASH wait states for core */
/*!< Set up clock selectors - Attach clocks to the peripheries */
CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO_HF */
/*!< Set up PLL */
CLOCK_AttachClk(kEXT_CLK_to_PLL0); /*!< Switch PLL0CLKSEL to EXT_CLK */
POWER_DisablePD(kPDRUNCFG_PD_PLL0); /* Ensure PLL is on */
POWER_DisablePD(kPDRUNCFG_PD_PLL0_SSCG);
const pll_setup_t pll0Setup = {
.pllctrl = SYSCON_PLL0CTRL_CLKEN_MASK | SYSCON_PLL0CTRL_SELI(53U) | SYSCON_PLL0CTRL_SELP(26U),
.pllndec = SYSCON_PLL0NDEC_NDIV(4U),
.pllpdec = SYSCON_PLL0PDEC_PDIV(2U),
.pllsscg = {0x0U,(SYSCON_PLL0SSCG1_MDIV_EXT(100U) | SYSCON_PLL0SSCG1_SEL_EXT_MASK)},
.pllRate = 100000000U,
.flags = PLL_SETUPFLAG_WAITLOCK
};
CLOCK_SetPLL0Freq(&pll0Setup); /*!< Configure PLL0 to the desired values */
/*!< Set SystemCoreClock variable. */
SystemCoreClock = 96000000U;
/*!< Set up dividers */
CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */
/*!< Set up clock selectors - Attach clocks to the peripheries */
CLOCK_AttachClk(kPLL0_to_MAIN_CLK); /*!< Switch MAIN_CLK to PLL0 */
/*< Set SystemCoreClock variable. */
SystemCoreClock = 100000000U;
}
void board_init(void) {
// Enable IOCON clock
CLOCK_EnableClock(kCLOCK_Iocon);
// Init 96 MHz clock
BootClockFROHF96M();
// Init 100 MHz clock
BOARD_BootClockPLL100M();
#if CFG_TUSB_OS == OPT_OS_NONE
// 1ms tick timer

View File

@@ -0,0 +1,149 @@
/*
* FreeRTOS Kernel V10.0.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. If you wish to use our Amazon
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
*
* See http://www.freertos.org/a00110.html.
*----------------------------------------------------------*/
// skip if included from IAR assembler
#ifndef __IASMARM__
#include "mxc_device.h"
#endif
/* Cortex M23/M33 port configuration. */
#define configENABLE_MPU 0
#define configENABLE_FPU 1
#define configENABLE_TRUSTZONE 0
#define configMINIMAL_SECURE_STACK_SIZE (1024)
#define configUSE_PREEMPTION 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
#define configCPU_CLOCK_HZ SystemCoreClock
#define configTICK_RATE_HZ ( 1000 )
#define configMAX_PRIORITIES ( 5 )
#define configMINIMAL_STACK_SIZE ( 128 )
#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 )
#define configMAX_TASK_NAME_LEN 16
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configQUEUE_REGISTRY_SIZE 4
#define configUSE_QUEUE_SETS 0
#define configUSE_TIME_SLICING 0
#define configUSE_NEWLIB_REENTRANT 0
#define configENABLE_BACKWARD_COMPATIBILITY 1
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
#define configSUPPORT_STATIC_ALLOCATION 1
#define configSUPPORT_DYNAMIC_ALLOCATION 0
/* Hook function related definitions. */
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configCHECK_HANDLER_INSTALLATION 0
/* Run time and task stats gathering related definitions. */
#define configGENERATE_RUN_TIME_STATS 0
#define configRECORD_STACK_HIGH_ADDRESS 1
#define configUSE_TRACE_FACILITY 1 // legacy trace
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES 2
/* Software timer related definitions. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2)
#define configTIMER_QUEUE_LENGTH 32
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
/* Optional functions - most linkers will remove unused functions anyway. */
#define INCLUDE_vTaskPrioritySet 0
#define INCLUDE_uxTaskPriorityGet 0
#define INCLUDE_vTaskDelete 0
#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY
#define INCLUDE_xResumeFromISR 0
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTaskGetSchedulerState 0
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_uxTaskGetStackHighWaterMark 0
#define INCLUDE_xTaskGetIdleTaskHandle 0
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
#define INCLUDE_pcTaskGetTaskName 0
#define INCLUDE_eTaskGetState 0
#define INCLUDE_xEventGroupSetBitFromISR 0
#define INCLUDE_xTimerPendFunctionCall 0
/* FreeRTOS hooks to NVIC vectors */
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler
#define vPortSVCHandler SVC_Handler
//--------------------------------------------------------------------+
// Interrupt nesting behavior configuration.
//--------------------------------------------------------------------+
// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header
#define configPRIO_BITS __NVIC_PRIO_BITS
/* The lowest interrupt priority that can be used in a call to a "set priority" function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<<configPRIO_BITS) - 1)
/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2
/* Interrupt priorities used by the kernel port layer itself. These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#endif

46
hw/bsp/max32650/README.md Normal file
View File

@@ -0,0 +1,46 @@
# Analog Devices MAX32650/1/2
This BSP is for working with the Analog Devices
[MAX32650](https://www.analog.com/en/products/max32650.html),
[MAX32651](https://www.analog.com/en/products/max32651.html) and
[MAX32652](https://www.analog.com/en/products/max32652.html)
microcontrollers. The following boards are supported:
* [MAX32650EVKIT](https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max32650-evkit.html)
* [MAX32650FTHR](https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max32650fthr.html)
* [MAX32651EVKIT](https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max32651-evkit.html) (Secure Bootloader)
This part family leverages the Maxim Microcontrollers SDK (MSDK) for the device
interfaces and hardware abstraction layers. This source code package is fetched
as part of the get-deps script.
The microcontrollers utilize the standard GNU ARM toolchain. If this toolchain
is not already available on your build machine, it can be installed by using the
bundled MSDK installation. Details on downloading and installing can be found
in the [User's Guide](https://analogdevicesinc.github.io/msdk//USERGUIDE/).
## Flashing
### MAX32650 and MAX32652
The default flashing behavior in this BSP for the MAX32650 and MAX32652 is to
utilize JLink. This can be done by running the `flash` or `flash-jlink` rule
for Makefiles, or the `<target>-jlink` target for CMake.
Both the Evaluation Kit and Feather boards are shipped with a CMSIS-DAP
compatible debug probe. However, at the time of writing, the necessary flashing
algorithms for OpenOCD have not yet been incorporated into the OpenOCD master
branch. To utilize the provided debug probes, please install the bundled MSDK
package which includes the appropriate OpenOCD modifications. To leverage this
OpenOCD instance, run the `flash-msdk` Makefile rule, or `<target>-msdk` CMake
target.
### MAX32651
The MAX32651 features an integrated secure bootloader which requires the
application image be signed prior to flashing. Both the Makefile and CMake
scripts account for this signing automatically when building for the
MAX32651EVKIT.
To flash the signed image, the MSDK's OpenOCD variant must be used. To flash
the MAX32651EVKIT please install the bundled MSDK, and utilize the `flash-msdk`
and `<target>-msdk` rule and target.

View File

@@ -0,0 +1,10 @@
# Use the standard, non-secure linker file
set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/max32650.ld)
function(update_board_extras TARGET)
#No extra arguments
endfunction()
function(prepare_image TARGET_IN)
#No signing required
endfunction()

View File

@@ -0,0 +1,56 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2024, Brent Kowal (Analog Devices, Inc)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#ifndef BOARD_H_
#define BOARD_H_
#include "gpio.h"
#include "mxc_sys.h"
#ifdef __cplusplus
extern "C" {
#endif
// LED
#define LED_PORT MXC_GPIO2
#define LED_PIN MXC_GPIO_PIN_25
#define LED_VDDIO MXC_GPIO_VSSEL_VDDIOH
#define LED_STATE_ON 0
// Button
#define BUTTON_PORT MXC_GPIO2
#define BUTTON_PIN MXC_GPIO_PIN_28
#define BUTTON_PULL MXC_GPIO_PAD_WEAK_PULL_UP
#define BUTTON_STATE_ACTIVE 0
// UART Enable for EvKit's Integrated FTDI Adapter. Pin Mux handled by the HAL
#define UART_NUM 0
#ifdef __cplusplus
}
#endif
#endif /* BOARD_H_ */

View File

@@ -0,0 +1,2 @@
# Use the standard, non-secure linker file
LD_FILE = $(BOARD_PATH)/max32650.ld

View File

@@ -0,0 +1,119 @@
MEMORY {
ROM (rx) : ORIGIN = 0x00000000, LENGTH = 0x00010000 /* 64kB ROM */
FLASH (rx) : ORIGIN = 0x10000000, LENGTH = 0x00300000 /* 3MB flash */
SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00100000 /* 1MB SRAM */
}
SECTIONS {
.text :
{
_text = .;
KEEP(*(.isr_vector))
*(.text*) /* program code */
*(.rodata*) /* read-only data: "const" */
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
/* C++ Exception handling */
KEEP(*(.eh_frame*))
_etext = .;
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
/* it's used for C++ exception handling */
/* we need to keep this to avoid overlapping */
.ARM.exidx :
{
__exidx_start = .;
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
__exidx_end = .;
} > FLASH
.data :
{
_data = ALIGN(., 4);
*(vtable)
*(.data*) /*read-write initialized data: initialized global variable*/
*(.spix_config*) /* SPIX configuration functions need to be run from SRAM */
*(.flashprog*) /* Flash program */
/* These array sections are used by __libc_init_array to call static C++ constructors */
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
_edata = ALIGN(., 4);
} > SRAM AT>FLASH
__load_data = LOADADDR(.data);
.bss :
{
. = ALIGN(4);
_bss = .;
*(.bss*) /*read-write zero initialized data: uninitialized global variable*/
*(COMMON)
_ebss = ALIGN(., 4);
} > SRAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(SRAM) + LENGTH(SRAM);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (COPY):
{
*(.stack*)
} > SRAM
.heap (COPY):
{
. = ALIGN(4);
PROVIDE ( end = . );
PROVIDE ( _end = . );
*(.heap*)
__HeapLimit = ABSOLUTE(__StackLimit);
} > SRAM
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= _ebss, "region RAM overflowed with stack")
}

View File

@@ -0,0 +1,10 @@
# Use the standard, non-secure linker file
set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/max32650.ld)
function(update_board_extras TARGET)
#No extra arguments
endfunction()
function(prepare_image TARGET_IN)
#No signing required
endfunction()

View File

@@ -1,7 +1,7 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2020, Ha Thach (tinyusb.org)
* Copyright (c) 2024, Brent Kowal (Analog Devices, Inc)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -27,26 +27,31 @@
#ifndef BOARD_H_
#define BOARD_H_
#include "gpio.h"
#include "mxc_sys.h"
#ifdef __cplusplus
extern "C" {
extern "C" {
#endif
#define _PINNUM(port, pin) ((port)*32 + (pin))
// LED
#define LED_PIN _PINNUM(0, 23)
#define LED_STATE_ON 0
#define LED_PORT MXC_GPIO1
#define LED_PIN MXC_GPIO_PIN_14
#define LED_VDDIO MXC_GPIO_VSSEL_VDDIO
#define LED_STATE_ON 0
// Button
#define BUTTON_PIN _PINNUM(0, 18)
#define BUTTON_STATE_ACTIVE 0
#define BUTTON_PORT MXC_GPIO1
#define BUTTON_PIN MXC_GPIO_PIN_19
#define BUTTON_PULL MXC_GPIO_PAD_WEAK_PULL_UP
#define BUTTON_STATE_ACTIVE 0
// UART Enable for SWD UART Pins. Pin Mux handled by the HAL
#define UART_NUM 0
// UART
#define UART_RX_PIN 2
#define UART_TX_PIN 3
#ifdef __cplusplus
}
}
#endif
#endif /* BOARD_H_ */

View File

@@ -0,0 +1,2 @@
# Use the standard, non-secure linker file
LD_FILE = $(BOARD_PATH)/max32650.ld

View File

@@ -0,0 +1,119 @@
MEMORY {
ROM (rx) : ORIGIN = 0x00000000, LENGTH = 0x00010000 /* 64kB ROM */
FLASH (rx) : ORIGIN = 0x10000000, LENGTH = 0x00300000 /* 3MB flash */
SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00100000 /* 1MB SRAM */
}
SECTIONS {
.text :
{
_text = .;
KEEP(*(.isr_vector))
*(.text*) /* program code */
*(.rodata*) /* read-only data: "const" */
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
/* C++ Exception handling */
KEEP(*(.eh_frame*))
_etext = .;
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
/* it's used for C++ exception handling */
/* we need to keep this to avoid overlapping */
.ARM.exidx :
{
__exidx_start = .;
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
__exidx_end = .;
} > FLASH
.data :
{
_data = ALIGN(., 4);
*(vtable)
*(.data*) /*read-write initialized data: initialized global variable*/
*(.spix_config*) /* SPIX configuration functions need to be run from SRAM */
*(.flashprog*) /* Flash program */
/* These array sections are used by __libc_init_array to call static C++ constructors */
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
_edata = ALIGN(., 4);
} > SRAM AT>FLASH
__load_data = LOADADDR(.data);
.bss :
{
. = ALIGN(4);
_bss = .;
*(.bss*) /*read-write zero initialized data: uninitialized global variable*/
*(COMMON)
_ebss = ALIGN(., 4);
} > SRAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(SRAM) + LENGTH(SRAM);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (COPY):
{
*(.stack*)
} > SRAM
.heap (COPY):
{
. = ALIGN(4);
PROVIDE ( end = . );
PROVIDE ( _end = . );
*(.heap*)
__HeapLimit = ABSOLUTE(__StackLimit);
} > SRAM
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= _ebss, "region RAM overflowed with stack")
}

View File

@@ -0,0 +1,30 @@
# Use the secure linker file
set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/max32651.ld)
function(update_board_extras TARGET)
# for the signed target, need to add the __SLA_FWK__ define
target_compile_definitions(${TARGET} PUBLIC
__SLA_FWK__
)
endfunction()
function(prepare_image TARGET_IN)
#For the signed target, set up a POST_BUILD command to sign the elf file once
#created
if((WIN32) OR (MINGW) OR (MSYS))
set(SIGN_EXE "sign_app.exe")
else()
set(SIGN_EXE "sign_app")
endif()
set(MCU_PATH "${TOP}/hw/mcu/analog/max32/")
# Custom POST_BUILD command
add_custom_command(
TARGET ${TARGET_IN} POST_BUILD
COMMAND ${CMAKE_OBJCOPY} $<TARGET_FILE:${TARGET_IN}> -R .sig -O binary $<TARGET_FILE_DIR:${TARGET_IN}>/${TARGET_IN}.bin
COMMAND ${MCU_PATH}/Tools/SBT/bin/${SIGN_EXE} -c MAX32651 key_file=${MCU_PATH}/Tools/SBT/devices/MAX32651/keys/maximtestcrk.key
ca=$<TARGET_FILE_DIR:${TARGET_IN}>/${TARGET_IN}.bin sca=$<TARGET_FILE_DIR:${TARGET_IN}>/${TARGET_IN}.sbin
COMMAND ${CMAKE_OBJCOPY} $<TARGET_FILE:${TARGET_IN}> --update-section .sig=$<TARGET_FILE_DIR:${TARGET_IN}>/${TARGET_IN}.sig
VERBATIM
)
endfunction()

View File

@@ -0,0 +1,56 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2024, Brent Kowal (Analog Devices, Inc)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#ifndef BOARD_H_
#define BOARD_H_
#include "gpio.h"
#include "mxc_sys.h"
#ifdef __cplusplus
extern "C" {
#endif
// LED
#define LED_PORT MXC_GPIO2
#define LED_PIN MXC_GPIO_PIN_25
#define LED_VDDIO MXC_GPIO_VSSEL_VDDIOH
#define LED_STATE_ON 0
// Button
#define BUTTON_PORT MXC_GPIO2
#define BUTTON_PIN MXC_GPIO_PIN_28
#define BUTTON_PULL MXC_GPIO_PAD_WEAK_PULL_UP
#define BUTTON_STATE_ACTIVE 0
// UART Enable for EvKit's Integrated FTDI Adapter. Pin Mux handled by the HAL
#define UART_NUM 0
#ifdef __cplusplus
}
#endif
#endif /* BOARD_H_ */

View File

@@ -0,0 +1,5 @@
# Use the secure linker file
LD_FILE = $(BOARD_PATH)/max32651.ld
# Let the family script know the build needs to be signed
SIGNED_BUILD := 1

View File

@@ -0,0 +1,132 @@
MEMORY {
HEADER (rx): ORIGIN = 0x10000000, LENGTH = 0x200
FLASH (rx) : ORIGIN = 0x10000200, LENGTH = 0x002FFE00 /* 3MB flash */
SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00100000 /* 1MB SRAM */
}
/* Added Oct 9, 2018 to go to correct reset vector. */
ENTRY(Reset_Handler)
PROVIDE( _start_SWAP = (((Reset_Handler) >> 24) | (((Reset_Handler) & 0x00FF0000) >> 8) | (((Reset_Handler) & 0x0000FF00) << 8) | ((Reset_Handler) << 24)));
PROVIDE_HIDDEN( _SLA_Size = _endimage - __end_header );
PROVIDE( _SLA_Size_SWAP = (((_SLA_Size) >> 24) | (((_SLA_Size) & 0x00FF0000) >> 8) | (((_SLA_Size) & 0x0000FF00) << 8) | ((_SLA_Size) << 24)));
/* Sections Definitions */
SECTIONS {
.sb_sla_header : ALIGN(4)
{
FILL(0xFF)
KEEP(*(.sb_sla_header)) /* Header for ROM code */
__end_header = . ;
. = ALIGN(512);
} > HEADER
.text :
{
_text = .;
KEEP(*(.isr_vector))
*(.text*) /* program code */
*(.rodata*) /* read-only data: "const" */
KEEP(*(.init))
KEEP(*(.fini))
/* C++ Exception handling */
KEEP(*(.eh_frame*))
_etext = .;
} > FLASH
/* it's used for C++ exception handling */
/* we need to keep this to avoid overlapping */
.ARM.exidx :
{
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} > FLASH
.data :
{
_data = ALIGN(., 4);
*(.data*) /*read-write initialized data: initialized global variable*/
*(.spix_config*) /* SPIX configuration functions need to be run from SRAM */
*(.flashprog*) /* Flash program */
/* These array sections are used by __libc_init_array to call static C++ constructors */
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
_edata = ALIGN(., 4);
} > SRAM AT>FLASH
__load_data = LOADADDR(.data);
_enddata = LOADADDR(.data)+SIZEOF(.data);
.sb_sla_trailer : AT(_enddata)
{
KEEP(*(.sb_sla_trailer))
/* Align image with 16 byte boundary to conform to flash encryption block size. */
FILL(0xDEADC0DE);
/* NOTE: The FILL and ALIGN will not work unless something is written to the section. So, we use LONG. */
LONG(0xDEADC0DE);
. = ALIGN(16);
} > FLASH
_endimage = LOADADDR(.sb_sla_trailer)+SIZEOF(.sb_sla_trailer);
.sig :
{
KEEP(*(.sig))
LONG(0xDEADBEEF);
} > FLASH
.bss :
{
. = ALIGN(4);
_bss = .;
*(.bss*) /*read-write zero initialized data: uninitialized global variable*/
*(COMMON)
_ebss = ALIGN(., 4);
} > SRAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(SRAM) + LENGTH(SRAM);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (COPY):
{
*(.stack*)
} > SRAM
.heap (COPY):
{
. = ALIGN(4);
PROVIDE ( end = . );
PROVIDE ( _end = . );
*(.heap*)
__HeapLimit = ABSOLUTE(__StackLimit);
} > SRAM
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= _ebss, "region RAM overflowed with stack")
}

172
hw/bsp/max32650/family.c Normal file
View File

@@ -0,0 +1,172 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2024 Brent Kowal (Analog Devices, Inc)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-prototypes" // _mxc_crit_get_state()
#endif
#include "gpio.h"
#include "mxc_sys.h"
#include "mxc_device.h"
#include "uart.h"
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#include "board.h"
#include "bsp/board_api.h"
//--------------------------------------------------------------------+
// Forward USB interrupt events to TinyUSB IRQ Handler
//--------------------------------------------------------------------+
void USB_IRQHandler(void) {
tud_int_handler(0);
}
//--------------------------------------------------------------------+
// MACRO TYPEDEF CONSTANT ENUM
//--------------------------------------------------------------------+
mxc_uart_regs_t *ConsoleUart = MXC_UART_GET_UART(UART_NUM);
void board_init(void) {
#if CFG_TUSB_OS == OPT_OS_NONE
// 1ms tick timer
SysTick_Config(SystemCoreClock / 1000);
#elif CFG_TUSB_OS == OPT_OS_FREERTOS
// If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher )
NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
#endif
mxc_gpio_cfg_t gpioConfig;
// LED
gpioConfig.drvstr = MXC_GPIO_DRVSTR_0;
gpioConfig.func = MXC_GPIO_FUNC_OUT;
gpioConfig.mask = LED_PIN;
gpioConfig.pad = MXC_GPIO_PAD_NONE;
gpioConfig.port = LED_PORT;
gpioConfig.vssel = LED_VDDIO;
MXC_GPIO_Config(&gpioConfig);
board_led_write(false);
// Button
gpioConfig.drvstr = MXC_GPIO_DRVSTR_0;
gpioConfig.func = MXC_GPIO_FUNC_IN;
gpioConfig.mask = BUTTON_PIN;
gpioConfig.pad = BUTTON_PULL;
gpioConfig.port = BUTTON_PORT;
gpioConfig.vssel = MXC_GPIO_VSSEL_VDDIO;
MXC_GPIO_Config(&gpioConfig);
// UART
MXC_UART_Init(ConsoleUart, CFG_BOARD_UART_BAUDRATE);
//USB
// Startup the HIRC96M clock if it's not on already
if (!(MXC_GCR->clk_ctrl & MXC_F_GCR_CLK_CTRL_HIRC96_EN)) {
MXC_GCR->clk_ctrl |= MXC_F_GCR_CLK_CTRL_HIRC96_EN;
MXC_SYS_Clock_Timeout(MXC_F_GCR_CLK_CTRL_HIRC96_RDY);
}
MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_USB);
}
//--------------------------------------------------------------------+
// Board porting API
//--------------------------------------------------------------------+
void board_led_write(bool state) {
#if LED_STATE_ON
state = !state;
#endif
if (state) {
MXC_GPIO_OutClr(LED_PORT, LED_PIN);
} else {
MXC_GPIO_OutSet(LED_PORT, LED_PIN);
}
}
uint32_t board_button_read(void) {
uint32_t state = MXC_GPIO_InGet(BUTTON_PORT, BUTTON_PIN) ? 1 : 0;
return BUTTON_STATE_ACTIVE == state;
}
size_t board_get_unique_id(uint8_t id[], size_t max_len) {
uint8_t hw_id[13];//USN Buffer
MXC_SYS_GetUSN(hw_id, 13);
size_t act_len = TU_MIN(max_len, 13);
memcpy(id, hw_id, act_len);
return act_len;
}
int board_uart_read(uint8_t *buf, int len) {
int uart_val;
int act_len = 0;
while (act_len < len) {
if ((uart_val = MXC_UART_ReadCharacterRaw(ConsoleUart)) == E_UNDERFLOW) {
break;
} else {
*buf++ = (uint8_t) uart_val;
act_len++;
}
}
return act_len;
}
int board_uart_write(void const *buf, int len) {
int act_len = 0;
const uint8_t *ch_ptr = (const uint8_t *) buf;
while (act_len < len) {
MXC_UART_WriteCharacter(ConsoleUart, *ch_ptr++);
act_len++;
}
return len;
}
#if CFG_TUSB_OS == OPT_OS_NONE
volatile uint32_t system_ticks = 0;
void SysTick_Handler(void) {
system_ticks++;
}
uint32_t board_millis(void) {
return system_ticks;
}
#endif
void HardFault_Handler(void) {
__asm("BKPT #0\n");
}
// Required by __libc_init_array in startup code if we are compiling using
// -nostdlib/-nostartfiles.
void _init(void) {
}

View File

@@ -0,0 +1,169 @@
include_guard()
set(MAX32_PERIPH ${TOP}/hw/mcu/analog/max32/Libraries/PeriphDrivers)
set(MAX32_CMSIS ${TOP}/hw/mcu/analog/max32/Libraries/CMSIS)
set(CMSIS_5 ${TOP}/lib/CMSIS_5)
# include board specific information and functions
include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake)
# Get the linker file
set(LD_FILE_Clang ${LD_FILE_GNU})
# toolchain set up
set(CMAKE_SYSTEM_PROCESSOR cortex-m4 CACHE INTERNAL "System Processor")
set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake)
set(JLINK_DEVICE max32650)
set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -f target/max32650.cfg")
set(FAMILY_MCUS MAX32650 CACHE INTERNAL "")
function(update_board TARGET)
target_compile_definitions(${TARGET} PUBLIC
TARGET=MAX32650
TARGET_REV=0x4131
MXC_ASSERT_ENABLE
MAX32650
IAR_PRAGMAS=0
CFG_TUSB_MCU=OPT_MCU_MAX32650
BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED
)
# Run any board specific updates
update_board_extras(${TARGET})
endfunction()
#------------------------------------
# BOARD_TARGET
#------------------------------------
# only need to be built ONCE for all examples
function(add_board_target BOARD_TARGET)
if (TARGET ${BOARD_TARGET})
return()
endif ()
# Startup & Linker script
set(STARTUP_FILE_GNU ${MAX32_CMSIS}/Device/Maxim/MAX32650/Source/GCC/startup_max32650.S)
set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU})
set(PERIPH_SRC ${MAX32_PERIPH}/Source)
add_library(${BOARD_TARGET} STATIC
${MAX32_CMSIS}/Device/Maxim/MAX32650/Source/heap.c
${MAX32_CMSIS}/Device/Maxim/MAX32650/Source/header_MAX32650.c
${MAX32_CMSIS}/Device/Maxim/MAX32650/Source/system_max32650.c
${PERIPH_SRC}/SYS/mxc_assert.c
${PERIPH_SRC}/SYS/mxc_delay.c
${PERIPH_SRC}/SYS/mxc_lock.c
${PERIPH_SRC}/SYS/nvic_table.c
${PERIPH_SRC}/SYS/pins_me10.c
${PERIPH_SRC}/SYS/sys_me10.c
${PERIPH_SRC}/TPU/tpu_me10.c
${PERIPH_SRC}/TPU/tpu_reva.c
${PERIPH_SRC}/FLC/flc_common.c
${PERIPH_SRC}/FLC/flc_me10.c
${PERIPH_SRC}/FLC/flc_reva.c
${PERIPH_SRC}/GPIO/gpio_common.c
${PERIPH_SRC}/GPIO/gpio_me10.c
${PERIPH_SRC}/GPIO/gpio_reva.c
${PERIPH_SRC}/ICC/icc_me10.c
${PERIPH_SRC}/ICC/icc_reva.c
${PERIPH_SRC}/ICC/icc_common.c
${PERIPH_SRC}/UART/uart_common.c
${PERIPH_SRC}/UART/uart_me10.c
${PERIPH_SRC}/UART/uart_reva.c
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
)
target_include_directories(${BOARD_TARGET} PUBLIC
${CMAKE_CURRENT_FUNCTION_LIST_DIR}
${MAX32_CMSIS}/Include
${MAX32_CMSIS}/Device/Maxim/MAX32650/Include
${MAX32_PERIPH}/Include/MAX32650
${PERIPH_SRC}/SYS
${PERIPH_SRC}/GPIO
${PERIPH_SRC}/TPU
${PERIPH_SRC}/ICC
${PERIPH_SRC}/FLC
${PERIPH_SRC}/UART
)
target_compile_options(${BOARD_TARGET} PRIVATE
-Wno-error=strict-prototypes
)
update_board(${BOARD_TARGET})
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
target_link_options(${BOARD_TARGET} PUBLIC
"LINKER:--script=${LD_FILE_GNU}"
-nostartfiles
--specs=nosys.specs --specs=nano.specs
-u sb_header #Needed when linking libraries to not lose the Signing header
)
elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang")
target_link_options(${BOARD_TARGET} PUBLIC
"LINKER:--script=${LD_FILE_Clang}"
)
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_MAX32650 ${RTOS})
target_sources(${TARGET}-tinyusb PUBLIC
${TOP}/src/portable/mentor/musb/dcd_musb.c
)
target_compile_options(${TARGET} PRIVATE
-Wno-error=strict-prototypes
)
target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD})
target_compile_options(${TARGET}-tinyusb PRIVATE
-Wno-error=strict-prototypes
)
# Link dependencies
target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb)
# Flashing
family_flash_jlink(${TARGET})
# Add the optional MSDK OpenOCD flashing
family_flash_msdk(${TARGET})
family_flash_openocd_adi(${TARGET})
endfunction()
function(family_flash_msdk TARGET)
# Prepare the image (signed) if the board requires it
prepare_image(${TARGET})
set(MAXIM_PATH "$ENV{MAXIM_PATH}")
add_custom_target(${TARGET}-msdk
DEPENDS ${TARGET}
COMMAND ${MAXIM_PATH}/Tools/OpenOCD/openocd -s ${MAXIM_PATH}/Tools/OpenOCD/scripts
-f interface/cmsis-dap.cfg -f target/max32650.cfg
-c "program $<TARGET_FILE:${TARGET}> verify; init; reset; exit"
VERBATIM
)
endfunction()

140
hw/bsp/max32650/family.mk Normal file
View File

@@ -0,0 +1,140 @@
DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/analog/max32
# Important locations in the hw support for MCU
MAX32_CMSIS = hw/mcu/analog/max32/Libraries/CMSIS
MAX32_PERIPH = hw/mcu/analog/max32/Libraries/PeriphDrivers
# Add any board specific make rules
include $(TOP)/$(BOARD_PATH)/board.mk
CPU_CORE ?= cortex-m4
PORT ?= 0
# GCC
SRC_S_GCC += $(MAX32_CMSIS)/Device/Maxim/MAX32650/Source/GCC/startup_max32650.S
# --------------
# Compiler Flags
# --------------
# Flags for the MAX32650/1/2 SDK
CFLAGS += -DTARGET=MAX32650 \
-DTARGET_REV=0x4131 \
-DMXC_ASSERT_ENABLE \
-DMAX32650 \
-DIAR_PRAGMAS=0
# Flags for TUSB features
CFLAGS += \
-DCFG_TUSB_MCU=OPT_MCU_MAX32650 \
-DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED
# mcu driver cause following warnings
CFLAGS += -Wno-error=strict-prototypes \
-Wno-error=unused-parameter \
-Wno-error=cast-align \
-Wno-error=cast-qual \
-Wno-error=sign-compare
LDFLAGS_GCC += -nostartfiles --specs=nosys.specs --specs=nano.specs
# Configure the flash rule. By default, use JLink.
SIGNED_BUILD ?= 0
DEFAULT_FLASH = flash-jlink
# If the applications needs to be signed (for the MAX32651), sign it first and
# then need to use MSDK's OpenOCD to flash it
# Also need to include the __SLA_FWK__ define to enable the signed header into
# memory
ifeq ($(SIGNED_BUILD), 1)
# Extra definitions to build for the secure part
CFLAGS += -D__SLA_FWK__
DEFAULT_FLASH := sign-build flash-msdk
endif
# For flash-jlink target
JLINK_DEVICE = max32650
# Configure the flash rule
flash: $(DEFAULT_FLASH)
# -----------------
# Sources & Include
# -----------------
PERIPH_SRC = $(TOP)/$(MAX32_PERIPH)/Source
SRC_C += \
src/portable/mentor/musb/dcd_musb.c \
$(MAX32_CMSIS)/Device/Maxim/MAX32650/Source/heap.c \
$(MAX32_CMSIS)/Device/Maxim/MAX32650/Source/system_max32650.c \
$(MAX32_CMSIS)/Device/Maxim/MAX32650/Source/header_MAX32650.c \
$(PERIPH_SRC)/SYS/mxc_assert.c \
$(PERIPH_SRC)/SYS/mxc_delay.c \
$(PERIPH_SRC)/SYS/mxc_lock.c \
$(PERIPH_SRC)/SYS/nvic_table.c \
$(PERIPH_SRC)/SYS/pins_me10.c \
$(PERIPH_SRC)/SYS/sys_me10.c \
$(PERIPH_SRC)/FLC/flc_common.c \
$(PERIPH_SRC)/FLC/flc_me10.c \
$(PERIPH_SRC)/FLC/flc_reva.c \
$(PERIPH_SRC)/GPIO/gpio_common.c \
$(PERIPH_SRC)/GPIO/gpio_me10.c \
$(PERIPH_SRC)/GPIO/gpio_reva.c \
$(PERIPH_SRC)/ICC/icc_me10.c \
$(PERIPH_SRC)/ICC/icc_reva.c \
$(PERIPH_SRC)/ICC/icc_common.c \
$(PERIPH_SRC)/TPU/tpu_me10.c \
$(PERIPH_SRC)/TPU/tpu_reva.c \
$(PERIPH_SRC)/UART/uart_common.c \
$(PERIPH_SRC)/UART/uart_me10.c \
$(PERIPH_SRC)/UART/uart_reva.c \
INC += \
$(TOP)/$(BOARD_PATH) \
$(TOP)/$(MAX32_CMSIS)/Include \
$(TOP)/$(MAX32_CMSIS)/Device/Maxim/MAX32650/Include \
$(TOP)/$(MAX32_PERIPH)/Include/MAX32650 \
$(PERIPH_SRC)/SYS \
$(PERIPH_SRC)/GPIO \
$(PERIPH_SRC)/ICC \
$(PERIPH_SRC)/FLC \
$(PERIPH_SRC)/TPU \
$(PERIPH_SRC)/UART
# The MAX32651EVKIT is pin for pin identical to the MAX32650EVKIT, however the
# MAX32651 has a secure bootloader which requires the image to be signed before
# loading into flash. All MAX32651EVKIT's have the same key for evaluation
# purposes, so create a special flash rule to sign the binary and flash using
# the MSDK.
MCU_PATH = $(TOP)/hw/mcu/analog/max32/
# Assume no extension for sign utility
SIGN_EXE = sign_app
ifeq ($(OS), Windows_NT)
# Must use .exe extension on Windows, since the binaries
# for Linux may live in the same place.
SIGN_EXE := sign_app.exe
else
UNAME = $(shell uname -s)
ifneq ($(findstring MSYS_NT,$(UNAME)),)
# Must also use .exe extension for MSYS2
SIGN_EXE := sign_app.exe
endif
endif
# Rule to sign the build. This will in-place modify the existing .elf file
# an populate the .sig section with the signature value
sign-build: $(BUILD)/$(PROJECT).elf
$(OBJCOPY) $(BUILD)/$(PROJECT).elf -R .sig -O binary $(BUILD)/$(PROJECT).bin
$(MCU_PATH)/Tools/SBT/bin/$(SIGN_EXE) -c MAX32651 \
key_file="$(MCU_PATH)/Tools/SBT/devices/MAX32651/keys/maximtestcrk.key" \
ca=$(BUILD)/$(PROJECT).bin sca=$(BUILD)/$(PROJECT).sbin
$(OBJCOPY) $(BUILD)/$(PROJECT).elf --update-section .sig=$(BUILD)/$(PROJECT).sig
# Optional flash option when running within an installed MSDK to use OpenOCD
# Mainline OpenOCD does not yet have the MAX32's flash algorithm integrated.
# If the MSDK is installed, flash-msdk can be run to utilize the the modified
# openocd with the algorithms
MAXIM_PATH := $(subst \,/,$(MAXIM_PATH))
flash-msdk: $(BUILD)/$(PROJECT).elf
$(MAXIM_PATH)/Tools/OpenOCD/openocd -s $(MAXIM_PATH)/Tools/OpenOCD/scripts \
-f interface/cmsis-dap.cfg -f target/max32650.cfg \
-c "program $(BUILD)/$(PROJECT).elf verify; init; reset; exit"

View File

@@ -0,0 +1,149 @@
/*
* FreeRTOS Kernel V10.0.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. If you wish to use our Amazon
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
*
* See http://www.freertos.org/a00110.html.
*----------------------------------------------------------*/
// skip if included from IAR assembler
#ifndef __IASMARM__
#include "mxc_device.h"
#endif
/* Cortex M23/M33 port configuration. */
#define configENABLE_MPU 0
#define configENABLE_FPU 1
#define configENABLE_TRUSTZONE 0
#define configMINIMAL_SECURE_STACK_SIZE (1024)
#define configUSE_PREEMPTION 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
#define configCPU_CLOCK_HZ SystemCoreClock
#define configTICK_RATE_HZ ( 1000 )
#define configMAX_PRIORITIES ( 5 )
#define configMINIMAL_STACK_SIZE ( 128 )
#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 )
#define configMAX_TASK_NAME_LEN 16
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configQUEUE_REGISTRY_SIZE 4
#define configUSE_QUEUE_SETS 0
#define configUSE_TIME_SLICING 0
#define configUSE_NEWLIB_REENTRANT 0
#define configENABLE_BACKWARD_COMPATIBILITY 1
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
#define configSUPPORT_STATIC_ALLOCATION 1
#define configSUPPORT_DYNAMIC_ALLOCATION 0
/* Hook function related definitions. */
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configCHECK_HANDLER_INSTALLATION 0
/* Run time and task stats gathering related definitions. */
#define configGENERATE_RUN_TIME_STATS 0
#define configRECORD_STACK_HIGH_ADDRESS 1
#define configUSE_TRACE_FACILITY 1 // legacy trace
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES 2
/* Software timer related definitions. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2)
#define configTIMER_QUEUE_LENGTH 32
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
/* Optional functions - most linkers will remove unused functions anyway. */
#define INCLUDE_vTaskPrioritySet 0
#define INCLUDE_uxTaskPriorityGet 0
#define INCLUDE_vTaskDelete 0
#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY
#define INCLUDE_xResumeFromISR 0
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTaskGetSchedulerState 0
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_uxTaskGetStackHighWaterMark 0
#define INCLUDE_xTaskGetIdleTaskHandle 0
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
#define INCLUDE_pcTaskGetTaskName 0
#define INCLUDE_eTaskGetState 0
#define INCLUDE_xEventGroupSetBitFromISR 0
#define INCLUDE_xTimerPendFunctionCall 0
/* FreeRTOS hooks to NVIC vectors */
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler
#define vPortSVCHandler SVC_Handler
//--------------------------------------------------------------------+
// Interrupt nesting behavior configuration.
//--------------------------------------------------------------------+
// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header
#define configPRIO_BITS __NVIC_PRIO_BITS
/* The lowest interrupt priority that can be used in a call to a "set priority" function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<<configPRIO_BITS) - 1)
/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2
/* Interrupt priorities used by the kernel port layer itself. These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#endif

32
hw/bsp/max32666/README.md Normal file
View File

@@ -0,0 +1,32 @@
# Analog Devices MAX32665/6
This BSP is for working with the Analog Devices
[MAX32665](https://www.analog.com/en/products/max32665.html) and
[MAX32666](https://www.analog.com/en/products/max32666.html) microcontrollers.
The following boards are supported:
* [MAX32666EVKIT](https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max32666evkit.html)
* [MAX32666FTHR](https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max32666fthr.html)
This part family leverages the Maxim Microcontrollers SDK (MSDK) for the device
interfaces and hardware abstraction layers. This source code package is fetched
as part of the get-deps script.
The microcontrollers utilize the standard GNU ARM toolchain. If this toolchain
is not already available on your build machine, it can be installed by using the
bundled MSDK installation. Details on downloading and installing can be found
in the [User's Guide](https://analogdevicesinc.github.io/msdk//USERGUIDE/).
## Flashing
The default flashing behavior in this BSP is to utilize JLink. This can be done
by running the `flash` or `flash-jlink` rule for Makefiles, or the
`<target>-jlink` target for CMake.
Both the Evaluation Kit and Feather boards are shipped with a CMSIS-DAP
compatible debug probe. However, at the time of writing, the necessary flashing
algorithms for OpenOCD have not yet been incorporated into the OpenOCD master
branch. To utilize the provided debug probes, please install the bundled MSDK
package which includes the appropriate OpenOCD modifications. To leverage this
OpenOCD instance, run the `flash-msdk` Makefile rule, or `<target>-msdk` CMake
target.

View File

@@ -0,0 +1 @@
# Nothing to be done at the board level

View File

@@ -0,0 +1,57 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2024, Brent Kowal (Analog Devices, Inc)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#ifndef BOARD_H_
#define BOARD_H_
#include "gpio.h"
#include "mxc_sys.h"
#ifdef __cplusplus
extern "C" {
#endif
// LED
#define LED_PORT MXC_GPIO1
#define LED_PIN MXC_GPIO_PIN_14
#define LED_VDDIO MXC_GPIO_VSSEL_VDDIOH
#define LED_STATE_ON 0
// Button
#define BUTTON_PORT MXC_GPIO1
#define BUTTON_PIN MXC_GPIO_PIN_6
#define BUTTON_PULL MXC_GPIO_PAD_PULL_UP
#define BUTTON_STATE_ACTIVE 0
// UART Enable for EvKit's Integrated FTDI Adapter. Pin Mux handled by the HAL
#define UART_NUM 1
#define UART_MAP MAP_A
#ifdef __cplusplus
}
#endif
#endif /* BOARD_H_ */

View File

@@ -0,0 +1 @@
# No specific build requirements for the board.

View File

@@ -0,0 +1 @@
# Nothing to be done at the board level

View File

@@ -0,0 +1,57 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2024, Brent Kowal (Analog Devices, Inc)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#ifndef BOARD_H_
#define BOARD_H_
#include "gpio.h"
#include "mxc_sys.h"
#ifdef __cplusplus
extern "C" {
#endif
// LED
#define LED_PORT MXC_GPIO0
#define LED_PIN MXC_GPIO_PIN_29
#define LED_VDDIO MXC_GPIO_VSSEL_VDDIOH
#define LED_STATE_ON 0
// Button
#define BUTTON_PORT MXC_GPIO1
#define BUTTON_PIN MXC_GPIO_PIN_10
#define BUTTON_PULL MXC_GPIO_PAD_PULL_UP
#define BUTTON_STATE_ACTIVE 0
// UART Enable for UART on SWD. Pin Mux handled by the HAL
#define UART_NUM 1
#define UART_MAP MAP_B
#ifdef __cplusplus
}
#endif
#endif /* BOARD_H_ */

View File

@@ -0,0 +1 @@
# No specific build requirements for the board.

172
hw/bsp/max32666/family.c Normal file
View File

@@ -0,0 +1,172 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2024 Brent Kowal (Analog Devices, Inc)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-prototypes" // _mxc_crit_get_state()
#endif
#include "gpio.h"
#include "mxc_sys.h"
#include "mcr_regs.h"
#include "mxc_device.h"
#include "uart.h"
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#include "board.h"
#include "bsp/board_api.h"
//--------------------------------------------------------------------+
// Forward USB interrupt events to TinyUSB IRQ Handler
//--------------------------------------------------------------------+
void USB_IRQHandler(void) {
tud_int_handler(0);
}
//--------------------------------------------------------------------+
// MACRO TYPEDEF CONSTANT ENUM
//--------------------------------------------------------------------+
mxc_uart_regs_t *ConsoleUart = MXC_UART_GET_UART(UART_NUM);
void board_init(void) {
#if CFG_TUSB_OS == OPT_OS_NONE
// 1ms tick timer
SysTick_Config(SystemCoreClock / 1000);
#elif CFG_TUSB_OS == OPT_OS_FREERTOS
// If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher )
NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
#endif
mxc_gpio_cfg_t gpioConfig;
// LED
gpioConfig.drvstr = MXC_GPIO_DRVSTR_0;
gpioConfig.func = MXC_GPIO_FUNC_OUT;
gpioConfig.mask = LED_PIN;
gpioConfig.pad = MXC_GPIO_PAD_NONE;
gpioConfig.port = LED_PORT;
gpioConfig.vssel = LED_VDDIO;
MXC_GPIO_Config(&gpioConfig);
board_led_write(false);
// Button
gpioConfig.drvstr = MXC_GPIO_DRVSTR_0;
gpioConfig.func = MXC_GPIO_FUNC_IN;
gpioConfig.mask = BUTTON_PIN;
gpioConfig.pad = BUTTON_PULL;
gpioConfig.port = BUTTON_PORT;
gpioConfig.vssel = MXC_GPIO_VSSEL_VDDIO;
MXC_GPIO_Config(&gpioConfig);
// UART
MXC_UART_Init(ConsoleUart, CFG_BOARD_UART_BAUDRATE, UART_MAP);
//USB
// Startup the HIRC96M clock if it's not on already
if (!(MXC_GCR->clkcn & MXC_F_GCR_CLKCN_HIRC96M_EN)) {
MXC_GCR->clkcn |= MXC_F_GCR_CLKCN_HIRC96M_EN;
}
MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_USB);
}
//--------------------------------------------------------------------+
// Board porting API
//--------------------------------------------------------------------+
void board_led_write(bool state) {
#if LED_STATE_ON
state = !state;
#endif
if (state) {
MXC_GPIO_OutClr(LED_PORT, LED_PIN);
} else {
MXC_GPIO_OutSet(LED_PORT, LED_PIN);
}
}
uint32_t board_button_read(void) {
uint32_t state = MXC_GPIO_InGet(BUTTON_PORT, BUTTON_PIN) ? 1 : 0;
return BUTTON_STATE_ACTIVE == state;
}
size_t board_get_unique_id(uint8_t id[], size_t max_len) {
uint8_t hw_id[MXC_SYS_USN_CHECKSUM_LEN];//USN Buffer
/* All other 2nd parameter is optional checksum buffer */
MXC_SYS_GetUSN(hw_id, NULL);
size_t act_len = TU_MIN(max_len, MXC_SYS_USN_LEN);
memcpy(id, hw_id, act_len);
return act_len;
}
int board_uart_read(uint8_t *buf, int len) {
int uart_val;
int act_len = 0;
while (act_len < len) {
if ((uart_val = MXC_UART_ReadCharacterRaw(ConsoleUart)) == E_UNDERFLOW) {
break;
} else {
*buf++ = (uint8_t) uart_val;
act_len++;
}
}
return act_len;
}
int board_uart_write(void const *buf, int len) {
int act_len = 0;
const uint8_t *ch_ptr = (const uint8_t *) buf;
while (act_len < len) {
MXC_UART_WriteCharacter(ConsoleUart, *ch_ptr++);
act_len++;
}
return len;
}
#if CFG_TUSB_OS == OPT_OS_NONE
volatile uint32_t system_ticks = 0;
void SysTick_Handler(void) {
system_ticks++;
}
uint32_t board_millis(void) {
return system_ticks;
}
#endif
void HardFault_Handler(void) {
__asm("BKPT #0\n");
}
// Required by __libc_init_array in startup code if we are compiling using
// -nostdlib/-nostartfiles.
void _init(void) {
}

View File

@@ -0,0 +1,147 @@
include_guard()
set(MAX32_PERIPH ${TOP}/hw/mcu/analog/max32/Libraries/PeriphDrivers)
set(MAX32_CMSIS ${TOP}/hw/mcu/analog/max32/Libraries/CMSIS)
set(CMSIS_5 ${TOP}/lib/CMSIS_5)
# include board specific
include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake)
# Get the linker file from current location (family)
set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/max32666.ld)
set(LD_FILE_Clang ${LD_FILE_GNU})
# toolchain set up
set(CMAKE_SYSTEM_PROCESSOR cortex-m4 CACHE INTERNAL "System Processor")
set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake)
set(JLINK_DEVICE max32666)
set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -f target/max32665.cfg")
set(FAMILY_MCUS MAX32666 CACHE INTERNAL "")
function(update_board TARGET)
target_compile_definitions(${TARGET} PUBLIC
TARGET=MAX32665
TARGET_REV=0x4131
MXC_ASSERT_ENABLE
MAX32665
IAR_PRAGMAS=0
CFG_TUSB_MCU=OPT_MCU_MAX32666
BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED
)
endfunction()
#------------------------------------
# BOARD_TARGET
#------------------------------------
# only need to be built ONCE for all examples
function(add_board_target BOARD_TARGET)
if (TARGET ${BOARD_TARGET})
return()
endif ()
# Startup & Linker script
set(STARTUP_FILE_GNU ${MAX32_CMSIS}/Device/Maxim/MAX32665/Source/GCC/startup_max32665.S)
set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU})
set(PERIPH_SRC ${MAX32_PERIPH}/Source)
add_library(${BOARD_TARGET} STATIC
${MAX32_CMSIS}/Device/Maxim/MAX32665/Source/heap.c
${MAX32_CMSIS}/Device/Maxim/MAX32665/Source/system_max32665.c
${PERIPH_SRC}/SYS/mxc_assert.c
${PERIPH_SRC}/SYS/mxc_delay.c
${PERIPH_SRC}/SYS/mxc_lock.c
${PERIPH_SRC}/SYS/nvic_table.c
${PERIPH_SRC}/SYS/pins_me14.c
${PERIPH_SRC}/SYS/sys_me14.c
${PERIPH_SRC}/TPU/tpu_me14.c
${PERIPH_SRC}/TPU/tpu_reva.c
${PERIPH_SRC}/FLC/flc_common.c
${PERIPH_SRC}/FLC/flc_me14.c
${PERIPH_SRC}/FLC/flc_reva.c
${PERIPH_SRC}/GPIO/gpio_common.c
${PERIPH_SRC}/GPIO/gpio_me14.c
${PERIPH_SRC}/GPIO/gpio_reva.c
${PERIPH_SRC}/ICC/icc_me14.c
${PERIPH_SRC}/ICC/icc_reva.c
${PERIPH_SRC}/UART/uart_common.c
${PERIPH_SRC}/UART/uart_me14.c
${PERIPH_SRC}/UART/uart_reva.c
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
)
target_include_directories(${BOARD_TARGET} PUBLIC
${CMAKE_CURRENT_FUNCTION_LIST_DIR}
${MAX32_CMSIS}/Include
${MAX32_CMSIS}/Device/Maxim/MAX32665/Include
${MAX32_PERIPH}/Include/MAX32665
${PERIPH_SRC}/SYS
${PERIPH_SRC}/GPIO
${PERIPH_SRC}/TPU
${PERIPH_SRC}/ICC
${PERIPH_SRC}/FLC
${PERIPH_SRC}/UART
)
target_compile_options(${BOARD_TARGET} PRIVATE
-Wno-error=strict-prototypes
)
update_board(${BOARD_TARGET})
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
target_link_options(${BOARD_TARGET} PUBLIC
"LINKER:--script=${LD_FILE_GNU}"
-nostartfiles
--specs=nosys.specs --specs=nano.specs
)
elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang")
target_link_options(${BOARD_TARGET} PUBLIC
"LINKER:--script=${LD_FILE_Clang}"
)
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_MAX32666 ${RTOS})
target_sources(${TARGET}-tinyusb PUBLIC
${TOP}/src/portable/mentor/musb/dcd_musb.c
)
target_compile_options(${TARGET} PRIVATE
-Wno-error=strict-prototypes
)
target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD})
target_compile_options(${TARGET}-tinyusb PRIVATE
-Wno-error=strict-prototypes
)
# Link dependencies
target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb)
# Flashing
family_flash_jlink(${TARGET})
family_flash_openocd_adi(${TARGET})
endfunction()

93
hw/bsp/max32666/family.mk Normal file
View File

@@ -0,0 +1,93 @@
DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/analog/max32
# Important locations in the hw support for MCU
MAX32_CMSIS = hw/mcu/analog/max32/Libraries/CMSIS
MAX32_PERIPH = hw/mcu/analog/max32/Libraries/PeriphDrivers
# Add any board specific make rules
include $(TOP)/$(BOARD_PATH)/board.mk
CPU_CORE ?= cortex-m4
PORT ?= 0
# GCC
SRC_S_GCC += $(MAX32_CMSIS)/Device/Maxim/MAX32665/Source/GCC/startup_max32665.S
LD_FILE = $(FAMILY_PATH)/max32666.ld
# --------------
# Compiler Flags
# --------------
# Flags for the MAX32665/6 SDK
CFLAGS += -DTARGET=MAX32665 \
-DTARGET_REV=0x4131 \
-DMXC_ASSERT_ENABLE \
-DMAX32665 \
-DIAR_PRAGMAS=0
# Flags for TUSB features
CFLAGS += \
-DCFG_TUSB_MCU=OPT_MCU_MAX32666 \
-DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED
# mcu driver cause following warnings
CFLAGS += -Wno-error=strict-prototypes \
-Wno-error=unused-parameter \
-Wno-error=cast-align \
-Wno-error=cast-qual
LDFLAGS_GCC += -nostartfiles --specs=nosys.specs --specs=nano.specs
# For flash-jlink target
JLINK_DEVICE = max32666
# flash target using Jlink by default
flash: flash-jlink
# Optional flash option when running within an installed MSDK to use OpenOCD
# Mainline OpenOCD does not yet have the MAX32's flash algorithm integrated.
# If the MSDK is installed, flash-msdk can be run to utilize the the modified
# openocd with the algorithms
MAXIM_PATH := $(subst \,/,$(MAXIM_PATH))
flash-msdk: $(BUILD)/$(PROJECT).elf
$(MAXIM_PATH)/Tools/OpenOCD/openocd -s $(MAXIM_PATH)/Tools/OpenOCD/scripts \
-f interface/cmsis-dap.cfg -f target/max32665.cfg \
-c "program $(BUILD)/$(PROJECT).elf verify; init; reset; exit"
# -----------------
# Sources & Include
# -----------------
PERIPH_SRC = $(TOP)/$(MAX32_PERIPH)/Source
SRC_C += \
src/portable/mentor/musb/dcd_musb.c \
$(MAX32_CMSIS)/Device/Maxim/MAX32665/Source/heap.c \
$(MAX32_CMSIS)/Device/Maxim/MAX32665/Source/system_max32665.c \
$(PERIPH_SRC)/SYS/mxc_assert.c \
$(PERIPH_SRC)/SYS/mxc_delay.c \
$(PERIPH_SRC)/SYS/mxc_lock.c \
$(PERIPH_SRC)/SYS/nvic_table.c \
$(PERIPH_SRC)/SYS/pins_me14.c \
$(PERIPH_SRC)/SYS/sys_me14.c \
$(PERIPH_SRC)/FLC/flc_common.c \
$(PERIPH_SRC)/FLC/flc_me14.c \
$(PERIPH_SRC)/FLC/flc_reva.c \
$(PERIPH_SRC)/GPIO/gpio_common.c \
$(PERIPH_SRC)/GPIO/gpio_me14.c \
$(PERIPH_SRC)/GPIO/gpio_reva.c \
$(PERIPH_SRC)/ICC/icc_me14.c \
$(PERIPH_SRC)/ICC/icc_reva.c \
$(PERIPH_SRC)/TPU/tpu_me14.c \
$(PERIPH_SRC)/TPU/tpu_reva.c \
$(PERIPH_SRC)/UART/uart_common.c \
$(PERIPH_SRC)/UART/uart_me14.c \
$(PERIPH_SRC)/UART/uart_reva.c \
INC += \
$(TOP)/$(BOARD_PATH) \
$(TOP)/$(MAX32_CMSIS)/Include \
$(TOP)/$(MAX32_CMSIS)/Device/Maxim/MAX32665/Include \
$(TOP)/$(MAX32_PERIPH)/Include/MAX32665 \
$(PERIPH_SRC)/SYS \
$(PERIPH_SRC)/GPIO \
$(PERIPH_SRC)/ICC \
$(PERIPH_SRC)/FLC \
$(PERIPH_SRC)/TPU \
$(PERIPH_SRC)/UART

135
hw/bsp/max32666/max32666.ld Normal file
View File

@@ -0,0 +1,135 @@
/* SPID and SPIX Sections here are maximum possible sizes */
/* If used, they should be adjusted for the external Flash/RAM size */
MEMORY {
SPIX (rx) : ORIGIN = 0x08000000, LENGTH = 0x08000000
FLASH (rx) : ORIGIN = 0x10000000, LENGTH = 0x00100000
SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x0008C000
SPID (rw) : ORIGIN = 0x80000000, LENGTH = 512M
}
/* Sections Definitions */
SECTIONS {
.text :
{
_text = .;
KEEP(*(.isr_vector))
*(.text*) /* program code */
*(.rodata*) /* read-only data: "const" */
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
/* C++ Exception handling */
KEEP(*(.eh_frame*))
_etext = .;
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
/* This section will keep the SPIX data until loaded into the external device */
/* Upon initialization of SPIX (user code needs to do this) */
.xip_section :
{
KEEP(*(.xip_section*))
} > SPIX AT>FLASH
__load_start_xip = LOADADDR(.xip_section);
__load_length_xip = SIZEOF(.xip_section);
/* it's used for C++ exception handling */
/* we need to keep this to avoid overlapping */
.ARM.exidx :
{
__exidx_start = .;
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
__exidx_end = .;
} > FLASH
.data :
{
_data = ALIGN(., 4);
*(vtable)
*(.data*) /*read-write initialized data: initialized global variable*/
*(.spix_config*) /* SPIX configuration functions need to be run from SRAM */
*(.flashprog*) /* Flash program */
/* These array sections are used by __libc_init_array to call static C++ constructors */
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
_edata = ALIGN(., 4);
} > SRAM AT>FLASH
__load_data = LOADADDR(.data);
.bss :
{
. = ALIGN(4);
_bss = .;
*(.bss*) /*read-write zero initialized data: uninitialized global variable*/
*(COMMON)
_ebss = ALIGN(., 4);
} > SRAM
/* Setup the stack for Core 1, it will only be used if the user code
* includes a definition of Stack_Size_Core1, which defines the space
* reserved above the main core's stack for core 1's stack */
__StackTop_Core1 = ORIGIN(SRAM) + LENGTH(SRAM);
__StackLimit_Core1 = DEFINED(Stack_Size_Core1) ? __StackTop_Core1 - Stack_Size_Core1 : __StackTop_Core1;
/* Set stack top to end of RAM, and stack limit move down by Stack_Size.
* If core 1 is used, set the stack to the bottom of Core 1's stack region */
__StackTop = DEFINED(Stack_Size_Core1) ? __StackLimit_Core1 : ORIGIN(SRAM) + LENGTH(SRAM);
__StackLimit = __StackTop - Stack_Size;
.heap (COPY):
{
. = ALIGN(4);
PROVIDE ( end = . );
PROVIDE ( _end = . );
*(.heap*)
__HeapLimit = ABSOLUTE(__StackLimit);
} > SRAM
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack(s) exceeds RAM limit */
ASSERT(__StackLimit >= _ebss, "region RAM overflowed with stack")
}

View File

@@ -0,0 +1,149 @@
/*
* FreeRTOS Kernel V10.0.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. If you wish to use our Amazon
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
*
* See http://www.freertos.org/a00110.html.
*----------------------------------------------------------*/
// skip if included from IAR assembler
#ifndef __IASMARM__
#include "mxc_device.h"
#endif
/* Cortex M23/M33 port configuration. */
#define configENABLE_MPU 0
#define configENABLE_FPU 1
#define configENABLE_TRUSTZONE 0
#define configMINIMAL_SECURE_STACK_SIZE (1024)
#define configUSE_PREEMPTION 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
#define configCPU_CLOCK_HZ SystemCoreClock
#define configTICK_RATE_HZ ( 1000 )
#define configMAX_PRIORITIES ( 5 )
#define configMINIMAL_STACK_SIZE ( 128 )
#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 )
#define configMAX_TASK_NAME_LEN 16
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configQUEUE_REGISTRY_SIZE 4
#define configUSE_QUEUE_SETS 0
#define configUSE_TIME_SLICING 0
#define configUSE_NEWLIB_REENTRANT 0
#define configENABLE_BACKWARD_COMPATIBILITY 1
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
#define configSUPPORT_STATIC_ALLOCATION 1
#define configSUPPORT_DYNAMIC_ALLOCATION 0
/* Hook function related definitions. */
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configCHECK_HANDLER_INSTALLATION 0
/* Run time and task stats gathering related definitions. */
#define configGENERATE_RUN_TIME_STATS 0
#define configRECORD_STACK_HIGH_ADDRESS 1
#define configUSE_TRACE_FACILITY 1 // legacy trace
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES 2
/* Software timer related definitions. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2)
#define configTIMER_QUEUE_LENGTH 32
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
/* Optional functions - most linkers will remove unused functions anyway. */
#define INCLUDE_vTaskPrioritySet 0
#define INCLUDE_uxTaskPriorityGet 0
#define INCLUDE_vTaskDelete 0
#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY
#define INCLUDE_xResumeFromISR 0
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTaskGetSchedulerState 0
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_uxTaskGetStackHighWaterMark 0
#define INCLUDE_xTaskGetIdleTaskHandle 0
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
#define INCLUDE_pcTaskGetTaskName 0
#define INCLUDE_eTaskGetState 0
#define INCLUDE_xEventGroupSetBitFromISR 0
#define INCLUDE_xTimerPendFunctionCall 0
/* FreeRTOS hooks to NVIC vectors */
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler
#define vPortSVCHandler SVC_Handler
//--------------------------------------------------------------------+
// Interrupt nesting behavior configuration.
//--------------------------------------------------------------------+
// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header
#define configPRIO_BITS __NVIC_PRIO_BITS
/* The lowest interrupt priority that can be used in a call to a "set priority" function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<<configPRIO_BITS) - 1)
/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2
/* Interrupt priorities used by the kernel port layer itself. These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#endif

31
hw/bsp/max32690/README.md Normal file
View File

@@ -0,0 +1,31 @@
# Analog Devices MAX32690
This BSP is for working with the Analog Devices
[MAX32690](https://www.analog.com/en/products/max32690.html) microcontroller.
The following boards are supported:
* [MAX32690EVKIT](https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max32690evkit.html)
* [AD-APARD32690-SL](https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/ad-apard32690-sl.html)
This part family leverages the Maxim Microcontrollers SDK (MSDK) for the device
interfaces and hardware abstraction layers. This source code package is fetched
as part of the get-deps script.
The microcontroller utilizes the standard GNU ARM toolchain. If this toolchain
is not already available on your build machine, it can be installed by using the
bundled MSDK installation. Details on downloading and installing can be found
in the [User's Guide](https://analogdevicesinc.github.io/msdk//USERGUIDE/).
## Flashing
The default flashing behavior in this BSP is to utilize JLink. This can be done
by running the `flash` or `flash-jlink` rule for Makefiles, or the
`<target>-jlink` target for CMake.
Both the Evaluation Kit and APARD boards are shipped with a CMSIS-DAP
compatible debug probe. However, at the time of writing, the necessary flashing
algorithms for OpenOCD have not yet been incorporated into the OpenOCD master
branch. To utilize the provided debug probes, please install the bundled MSDK
package which includes the appropriate OpenOCD modifications. To leverage this
OpenOCD instance, run the `flash-msdk` Makefile rule, or `<target>-msdk` CMake
target.

View File

@@ -0,0 +1 @@
# Nothing to be done at the board level

View File

@@ -1,7 +1,7 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2020, Ha Thach (tinyusb.org)
* Copyright (c) 2024, Brent Kowal (Analog Devices, Inc)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -27,26 +27,30 @@
#ifndef BOARD_H_
#define BOARD_H_
#include "gpio.h"
#include "mxc_sys.h"
#ifdef __cplusplus
extern "C" {
extern "C" {
#endif
#define _PINNUM(port, pin) ((port)*32 + (pin))
// LED
#define LED_PIN _PINNUM(1, 13)
#define LED_STATE_ON 0
#define LED_PORT MXC_GPIO2
#define LED_PIN MXC_GPIO_PIN_1
#define LED_VDDIO MXC_GPIO_VSSEL_VDDIOH
#define LED_STATE_ON 1
// Button
#define BUTTON_PIN _PINNUM(0, 15)
#define BUTTON_STATE_ACTIVE 0
#define BUTTON_PORT MXC_GPIO1
#define BUTTON_PIN MXC_GPIO_PIN_27
#define BUTTON_PULL MXC_GPIO_PAD_NONE
#define BUTTON_STATE_ACTIVE 1
// UART
#define UART_RX_PIN 25
#define UART_TX_PIN 24
// UART Enable for UART on ARM SWD Connector
#define UART_NUM 0
#ifdef __cplusplus
}
}
#endif
#endif /* BOARD_H_ */

View File

@@ -0,0 +1 @@
# No specific build requirements for the board.

View File

@@ -0,0 +1 @@
# Nothing to be done at the board level

View File

@@ -1,7 +1,7 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2021, Ha Thach (tinyusb.org)
* Copyright (c) 2024, Brent Kowal (Analog Devices, Inc)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,22 +24,33 @@
* This file is part of the TinyUSB stack.
*/
#ifndef _TUSB_MUSB_TM4C_H_
#define _TUSB_MUSB_TM4C_H_
#ifndef BOARD_H_
#define BOARD_H_
#include "gpio.h"
#include "mxc_sys.h"
#ifdef __cplusplus
extern "C" {
extern "C" {
#endif
#if CFG_TUSB_MCU == OPT_MCU_TM4C123
#include "TM4C123.h"
//#elif CFG_TUSB_MCU == OPT_MCU_TM4C129
#else
#error "Unsupported MCUs"
#endif
// LED
#define LED_PORT MXC_GPIO0
#define LED_PIN MXC_GPIO_PIN_14
#define LED_VDDIO MXC_GPIO_VSSEL_VDDIOH
#define LED_STATE_ON 0
// Button
#define BUTTON_PORT MXC_GPIO4
#define BUTTON_PIN MXC_GPIO_PIN_0
#define BUTTON_PULL MXC_GPIO_PAD_PULL_UP
#define BUTTON_STATE_ACTIVE 0
// UART Enable for EvKit's Integrated FTDI Adapter. Pin Mux handled by the HAL
#define UART_NUM 2
#ifdef __cplusplus
}
}
#endif
#endif
#endif /* BOARD_H_ */

View File

@@ -0,0 +1 @@
# No specific build requirements for the board.

171
hw/bsp/max32690/family.c Normal file
View File

@@ -0,0 +1,171 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2024 Brent Kowal (Analog Devices, Inc)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-prototypes" // _mxc_crit_get_state()
#endif
#include "gpio.h"
#include "mxc_sys.h"
#include "mcr_regs.h"
#include "mxc_device.h"
#include "uart.h"
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#include "board.h"
#include "bsp/board_api.h"
//--------------------------------------------------------------------+
// Forward USB interrupt events to TinyUSB IRQ Handler
//--------------------------------------------------------------------+
void USB_IRQHandler(void) {
tud_int_handler(0);
}
//--------------------------------------------------------------------+
// MACRO TYPEDEF CONSTANT ENUM
//--------------------------------------------------------------------+
mxc_uart_regs_t *ConsoleUart = MXC_UART_GET_UART(UART_NUM);
void board_init(void) {
#if CFG_TUSB_OS == OPT_OS_NONE
// 1ms tick timer
SysTick_Config(SystemCoreClock / 1000);
#elif CFG_TUSB_OS == OPT_OS_FREERTOS
// If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher )
NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
#endif
mxc_gpio_cfg_t gpioConfig;
// LED
gpioConfig.drvstr = MXC_GPIO_DRVSTR_0;
gpioConfig.func = MXC_GPIO_FUNC_OUT;
gpioConfig.mask = LED_PIN;
gpioConfig.pad = MXC_GPIO_PAD_NONE;
gpioConfig.port = LED_PORT;
gpioConfig.vssel = LED_VDDIO;
MXC_GPIO_Config(&gpioConfig);
board_led_write(false);
// Button
gpioConfig.drvstr = MXC_GPIO_DRVSTR_0;
gpioConfig.func = MXC_GPIO_FUNC_IN;
gpioConfig.mask = BUTTON_PIN;
gpioConfig.pad = BUTTON_PULL;
gpioConfig.port = BUTTON_PORT;
gpioConfig.vssel = MXC_GPIO_VSSEL_VDDIO;
MXC_GPIO_Config(&gpioConfig);
// UART
MXC_UART_Init(ConsoleUart, CFG_BOARD_UART_BAUDRATE, MXC_UART_IBRO_CLK);
//USB
MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_IPO);
MXC_MCR->ldoctrl |= MXC_F_MCR_LDOCTRL_0P9EN;
MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_USB);
MXC_SYS_Reset_Periph(MXC_SYS_RESET0_USB);
}
//--------------------------------------------------------------------+
// Board porting API
//--------------------------------------------------------------------+
void board_led_write(bool state) {
#if LED_STATE_ON
state = !state;
#endif
if (state) {
MXC_GPIO_OutClr(LED_PORT, LED_PIN);
} else {
MXC_GPIO_OutSet(LED_PORT, LED_PIN);
}
}
uint32_t board_button_read(void) {
uint32_t state = MXC_GPIO_InGet(BUTTON_PORT, BUTTON_PIN) ? 1 : 0;
return BUTTON_STATE_ACTIVE == state;
}
size_t board_get_unique_id(uint8_t id[], size_t max_len) {
uint8_t hw_id[MXC_SYS_USN_CHECKSUM_LEN];//USN Buffer
/* All other 2nd parameter is optional checksum buffer */
MXC_SYS_GetUSN(hw_id, NULL);
size_t act_len = TU_MIN(max_len, MXC_SYS_USN_LEN);
memcpy(id, hw_id, act_len);
return act_len;
}
int board_uart_read(uint8_t *buf, int len) {
int uart_val;
int act_len = 0;
while (act_len < len) {
if ((uart_val = MXC_UART_ReadCharacterRaw(ConsoleUart)) == E_UNDERFLOW) {
break;
} else {
*buf++ = (uint8_t) uart_val;
act_len++;
}
}
return act_len;
}
int board_uart_write(void const *buf, int len) {
int act_len = 0;
const uint8_t *ch_ptr = (const uint8_t *) buf;
while (act_len < len) {
MXC_UART_WriteCharacter(ConsoleUart, *ch_ptr++);
act_len++;
}
return len;
}
#if CFG_TUSB_OS == OPT_OS_NONE
volatile uint32_t system_ticks = 0;
void SysTick_Handler(void) {
system_ticks++;
}
uint32_t board_millis(void) {
return system_ticks;
}
#endif
void HardFault_Handler(void) {
__asm("BKPT #0\n");
}
// Required by __libc_init_array in startup code if we are compiling using
// -nostdlib/-nostartfiles.
void _init(void) {
}

View File

@@ -0,0 +1,152 @@
include_guard()
set(MAX32_PERIPH ${TOP}/hw/mcu/analog/max32/Libraries/PeriphDrivers)
set(MAX32_CMSIS ${TOP}/hw/mcu/analog/max32/Libraries/CMSIS)
set(CMSIS_5 ${TOP}/lib/CMSIS_5)
# include board specific
include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake)
# Get the linker file from current location (family)
set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/max32690.ld)
set(LD_FILE_Clang ${LD_FILE_GNU})
# toolchain set up
set(CMAKE_SYSTEM_PROCESSOR cortex-m4 CACHE INTERNAL "System Processor")
set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake)
set(JLINK_DEVICE max32690)
set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -f target/max32690.cfg")
set(FAMILY_MCUS MAX32690 CACHE INTERNAL "")
function(update_board TARGET)
target_compile_definitions(${TARGET} PUBLIC
TARGET=MAX32690
TARGET_REV=0x4131
MXC_ASSERT_ENABLE
MAX32690
FLASH_ORIGIN=0x10000000
FLASH_SIZE=0x340000
SRAM_ORIGIN=0x20000000
SRAM_SIZE=0x100000
IAR_PRAGMAS=0
CFG_TUSB_MCU=OPT_MCU_MAX32690
BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED
)
endfunction()
#------------------------------------
# BOARD_TARGET
#------------------------------------
# only need to be built ONCE for all examples
function(add_board_target BOARD_TARGET)
if (TARGET ${BOARD_TARGET})
return()
endif ()
# Startup & Linker script
set(STARTUP_FILE_GNU ${MAX32_CMSIS}/Device/Maxim/MAX32690/Source/GCC/startup_max32690.S)
set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU})
set(PERIPH_SRC ${MAX32_PERIPH}/Source)
add_library(${BOARD_TARGET} STATIC
${MAX32_CMSIS}/Device/Maxim/MAX32690/Source/heap.c
${MAX32_CMSIS}/Device/Maxim/MAX32690/Source/system_max32690.c
${PERIPH_SRC}/SYS/mxc_assert.c
${PERIPH_SRC}/SYS/mxc_delay.c
${PERIPH_SRC}/SYS/mxc_lock.c
${PERIPH_SRC}/SYS/nvic_table.c
${PERIPH_SRC}/SYS/pins_me18.c
${PERIPH_SRC}/SYS/sys_me18.c
${PERIPH_SRC}/CTB/ctb_me18.c
${PERIPH_SRC}/CTB/ctb_reva.c
${PERIPH_SRC}/CTB/ctb_common.c
${PERIPH_SRC}/FLC/flc_common.c
${PERIPH_SRC}/FLC/flc_me18.c
${PERIPH_SRC}/FLC/flc_reva.c
${PERIPH_SRC}/GPIO/gpio_common.c
${PERIPH_SRC}/GPIO/gpio_me18.c
${PERIPH_SRC}/GPIO/gpio_reva.c
${PERIPH_SRC}/ICC/icc_me18.c
${PERIPH_SRC}/ICC/icc_reva.c
${PERIPH_SRC}/UART/uart_common.c
${PERIPH_SRC}/UART/uart_me18.c
${PERIPH_SRC}/UART/uart_revb.c
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
)
target_include_directories(${BOARD_TARGET} PUBLIC
${CMAKE_CURRENT_FUNCTION_LIST_DIR}
${MAX32_CMSIS}/Include
${MAX32_CMSIS}/Device/Maxim/MAX32690/Include
${MAX32_PERIPH}/Include/MAX32690
${PERIPH_SRC}/SYS
${PERIPH_SRC}/GPIO
${PERIPH_SRC}/CTB
${PERIPH_SRC}/ICC
${PERIPH_SRC}/FLC
${PERIPH_SRC}/UART
)
target_compile_options(${BOARD_TARGET} PRIVATE
-Wno-error=strict-prototypes
)
update_board(${BOARD_TARGET})
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
target_link_options(${BOARD_TARGET} PUBLIC
"LINKER:--script=${LD_FILE_GNU}"
-nostartfiles
--specs=nosys.specs --specs=nano.specs
)
elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang")
target_link_options(${BOARD_TARGET} PUBLIC
"LINKER:--script=${LD_FILE_Clang}"
)
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_MAX32690 ${RTOS})
target_sources(${TARGET}-tinyusb PUBLIC
${TOP}/src/portable/mentor/musb/dcd_musb.c
)
target_compile_options(${TARGET} PRIVATE
-Wno-error=strict-prototypes
)
target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD})
target_compile_options(${TARGET}-tinyusb PRIVATE
-Wno-error=strict-prototypes
)
# Link dependencies
target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb)
# Flashing
family_flash_jlink(${TARGET})
family_flash_openocd_adi(${TARGET})
endfunction()

101
hw/bsp/max32690/family.mk Normal file
View File

@@ -0,0 +1,101 @@
DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/analog/max32
# Important locations in the hw support for MCU
MAX32_CMSIS = hw/mcu/analog/max32/Libraries/CMSIS
MAX32_PERIPH = hw/mcu/analog/max32/Libraries/PeriphDrivers
# Add any board specific make rules
include $(TOP)/$(BOARD_PATH)/board.mk
CPU_CORE ?= cortex-m4
PORT ?= 0
# GCC
SRC_S_GCC += $(MAX32_CMSIS)/Device/Maxim/MAX32690/Source/GCC/startup_max32690.S
LD_FILE = $(FAMILY_PATH)/max32690.ld
# --------------
# Compiler Flags
# --------------
# Flags for the MAX32690 SDK
CFLAGS += -DTARGET=MAX32690 \
-DTARGET_REV=0x4131 \
-DMXC_ASSERT_ENABLE \
-DMAX32690 \
-DFLASH_ORIGIN=0x10000000 \
-DFLASH_SIZE=0x340000 \
-DSRAM_ORIGIN=0x20000000 \
-DSRAM_SIZE=0x100000 \
-DIAR_PRAGMAS=0
# Flags for TUSB features
CFLAGS += \
-DCFG_TUSB_MCU=OPT_MCU_MAX32690 \
-DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED
# mcu driver cause following warnings
CFLAGS += -Wno-error=unused-parameter \
-Wno-error=strict-prototypes \
-Wno-error=old-style-declaration \
-Wno-error=sign-compare \
-Wno-error=cast-qual \
-Wno-lto-type-mismatch
LDFLAGS_GCC += -nostartfiles --specs=nosys.specs --specs=nano.specs
# For flash-jlink target
JLINK_DEVICE = max32690
# flash target using Jlink by default
flash: flash-jlink
# Optional flash option when running within an installed MSDK to use OpenOCD
# Mainline OpenOCD does not yet have the MAX32's flash algorithm integrated.
# If the MSDK is installed, flash-msdk can be run to utilize the the modified
# openocd with the algorithms
MAXIM_PATH := $(subst \,/,$(MAXIM_PATH))
flash-msdk: $(BUILD)/$(PROJECT).elf
$(MAXIM_PATH)/Tools/OpenOCD/openocd -s $(MAXIM_PATH)/Tools/OpenOCD/scripts \
-f interface/cmsis-dap.cfg -f target/max32690.cfg \
-c "program $(BUILD)/$(PROJECT).elf verify; init; reset; exit"
# -----------------
# Sources & Include
# -----------------
PERIPH_SRC = $(TOP)/$(MAX32_PERIPH)/Source
SRC_C += \
src/portable/mentor/musb/dcd_musb.c \
$(MAX32_CMSIS)/Device/Maxim/MAX32690/Source/heap.c \
$(MAX32_CMSIS)/Device/Maxim/MAX32690/Source/system_max32690.c \
$(PERIPH_SRC)/SYS/mxc_assert.c \
$(PERIPH_SRC)/SYS/mxc_delay.c \
$(PERIPH_SRC)/SYS/mxc_lock.c \
$(PERIPH_SRC)/SYS/nvic_table.c \
$(PERIPH_SRC)/SYS/pins_me18.c \
$(PERIPH_SRC)/SYS/sys_me18.c \
$(PERIPH_SRC)/CTB/ctb_me18.c \
$(PERIPH_SRC)/CTB/ctb_reva.c \
$(PERIPH_SRC)/CTB/ctb_common.c \
$(PERIPH_SRC)/FLC/flc_common.c \
$(PERIPH_SRC)/FLC/flc_me18.c \
$(PERIPH_SRC)/FLC/flc_reva.c \
$(PERIPH_SRC)/GPIO/gpio_common.c \
$(PERIPH_SRC)/GPIO/gpio_me18.c \
$(PERIPH_SRC)/GPIO/gpio_reva.c \
$(PERIPH_SRC)/ICC/icc_me18.c \
$(PERIPH_SRC)/ICC/icc_reva.c \
$(PERIPH_SRC)/UART/uart_common.c \
$(PERIPH_SRC)/UART/uart_me18.c \
$(PERIPH_SRC)/UART/uart_revb.c \
INC += \
$(TOP)/$(BOARD_PATH) \
$(TOP)/$(MAX32_CMSIS)/Include \
$(TOP)/$(MAX32_CMSIS)/Device/Maxim/MAX32690/Include \
$(TOP)/$(MAX32_PERIPH)/Include/MAX32690 \
$(PERIPH_SRC)/SYS \
$(PERIPH_SRC)/GPIO \
$(PERIPH_SRC)/CTB \
$(PERIPH_SRC)/ICC \
$(PERIPH_SRC)/FLC \
$(PERIPH_SRC)/UART

164
hw/bsp/max32690/max32690.ld Normal file
View File

@@ -0,0 +1,164 @@
MEMORY {
ROM (rx) : ORIGIN = 0x00000000, LENGTH = 0x00020000 /* 128kB ROM */
FLASH (rx) : ORIGIN = 0x10000000, LENGTH = 0x00340000
SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00100000
/*
* Note that CS0/CS1 address mappings may be reversed using MXC_HPC->mbr0 and ->mbr1
* The following mappings are selected for simplicity
*/
HPB_CS0 (rwx) : ORIGIN = 0x60000000, LENGTH = 0x10000000 /* External Hyperbus/Xccelabus chip select 0 */
HPB_CS1 (rwx) : ORIGIN = 0x70000000, LENGTH = 0x10000000 /* External Hyperbus/Xccelabus chip select 1 */
}
SECTIONS {
.rom :
{
KEEP(*(.rom_vector))
*(.rom_handlers*)
} > ROM
.text :
{
_text = .;
KEEP(*(.isr_vector))
EXCLUDE_FILE (*riscv.o) *(.text*) /* program code, exclude RISCV code */
*(.rodata*) /* read-only data: "const" */
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
/* C++ Exception handling */
KEEP(*(.eh_frame*))
_etext = .;
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
/* These sections allow code to be compiled/linked for HPB addresses, but reside in
* flash until copied by code to the external HPB flash device
*/
.hpb_cs0_section :
{
__hpb_cs0_start = ABSOLUTE(.);
KEEP(*(.hpb_cs0_section*))
} > HPB_CS0 AT>FLASH
__load_start_hpb_cs0 = LOADADDR(.hpb_cs0_section);
__load_length_hpb_cs0 = SIZEOF(.hpb_cs0_section);
.hpb_cs1_section :
{
__hpb_cs1_start = ABSOLUTE(.);
KEEP(*(.hpb_cs1_section*))
} > HPB_CS1 AT>FLASH
__load_start_hpb_cs1 = LOADADDR(.hpb_cs1_section);
__load_length_hpb_cs1 = SIZEOF(.hpb_cs1_section);
/* Binary import */
.bin_storage :
{
FILL(0xFF)
_bin_start_ = .;
KEEP(*(.bin_storage_img))
_bin_end_ = .;
. = ALIGN(4);
} > FLASH
/* it's used for C++ exception handling */
/* we need to keep this to avoid overlapping */
.ARM.exidx :
{
__exidx_start = .;
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
__exidx_end = .;
} > FLASH
.data :
{
_data = ALIGN(., 4);
*(vtable)
*(.data*) /*read-write initialized data: initialized global variable*/
/* These array sections are used by __libc_init_array to call static C++ constructors */
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
/* Run the flash programming functions from SRAM */
*(.flashprog)
_edata = ALIGN(., 4);
} > SRAM AT>FLASH
__load_data = LOADADDR(.data);
.bss :
{
. = ALIGN(4);
_bss = .;
*(.bss*) /*read-write zero initialized data: uninitialized global variable*/
*(COMMON)
_ebss = ALIGN(., 4);
} > SRAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(SRAM) + LENGTH(SRAM);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (COPY):
{
*(.stack*)
} > SRAM
.heap (COPY):
{
. = ALIGN(4);
PROVIDE ( end = . );
PROVIDE ( _end = . );
*(.heap*)
__HeapLimit = ABSOLUTE(__StackLimit);
} > SRAM
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= _ebss, "region RAM overflowed with stack")
}

View File

@@ -0,0 +1,149 @@
/*
* FreeRTOS Kernel V10.0.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. If you wish to use our Amazon
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
*
* See http://www.freertos.org/a00110.html.
*----------------------------------------------------------*/
// skip if included from IAR assembler
#ifndef __IASMARM__
#include "mxc_device.h"
#endif
/* Cortex M23/M33 port configuration. */
#define configENABLE_MPU 0
#define configENABLE_FPU 1
#define configENABLE_TRUSTZONE 0
#define configMINIMAL_SECURE_STACK_SIZE (1024)
#define configUSE_PREEMPTION 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
#define configCPU_CLOCK_HZ SystemCoreClock
#define configTICK_RATE_HZ ( 1000 )
#define configMAX_PRIORITIES ( 5 )
#define configMINIMAL_STACK_SIZE ( 128 )
#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 )
#define configMAX_TASK_NAME_LEN 16
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configQUEUE_REGISTRY_SIZE 4
#define configUSE_QUEUE_SETS 0
#define configUSE_TIME_SLICING 0
#define configUSE_NEWLIB_REENTRANT 0
#define configENABLE_BACKWARD_COMPATIBILITY 1
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
#define configSUPPORT_STATIC_ALLOCATION 1
#define configSUPPORT_DYNAMIC_ALLOCATION 0
/* Hook function related definitions. */
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configCHECK_HANDLER_INSTALLATION 0
/* Run time and task stats gathering related definitions. */
#define configGENERATE_RUN_TIME_STATS 0
#define configRECORD_STACK_HIGH_ADDRESS 1
#define configUSE_TRACE_FACILITY 1 // legacy trace
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES 2
/* Software timer related definitions. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2)
#define configTIMER_QUEUE_LENGTH 32
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
/* Optional functions - most linkers will remove unused functions anyway. */
#define INCLUDE_vTaskPrioritySet 0
#define INCLUDE_uxTaskPriorityGet 0
#define INCLUDE_vTaskDelete 0
#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY
#define INCLUDE_xResumeFromISR 0
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTaskGetSchedulerState 0
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_uxTaskGetStackHighWaterMark 0
#define INCLUDE_xTaskGetIdleTaskHandle 0
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
#define INCLUDE_pcTaskGetTaskName 0
#define INCLUDE_eTaskGetState 0
#define INCLUDE_xEventGroupSetBitFromISR 0
#define INCLUDE_xTimerPendFunctionCall 0
/* FreeRTOS hooks to NVIC vectors */
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler
#define vPortSVCHandler SVC_Handler
//--------------------------------------------------------------------+
// Interrupt nesting behavior configuration.
//--------------------------------------------------------------------+
// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header
#define configPRIO_BITS __NVIC_PRIO_BITS
/* The lowest interrupt priority that can be used in a call to a "set priority" function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<<configPRIO_BITS) - 1)
/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2
/* Interrupt priorities used by the kernel port layer itself. These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#endif

28
hw/bsp/max78002/README.md Normal file
View File

@@ -0,0 +1,28 @@
# Analog Devices MAX78002
This BSP is for working with the Analog Devices
[MAX78002](https://www.analog.com/en/products/max78002.html) AI microcontroller.
The following boards are supported:
* [MAX78002EVKIT](https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/max78002evkit.html)
This part family leverages the Maxim Microcontrollers SDK (MSDK) for the device
interfaces and hardware abstraction layers. This source code package is fetched
as part of the get-deps script.
The microcontroller utilizes the standard GNU ARM toolchain. If this toolchain
is not already available on your build machine, it can be installed by using the
bundled MSDK installation. Details on downloading and installing can be found
in the [User's Guide](https://analogdevicesinc.github.io/msdk//USERGUIDE/).
## Flashing
The default flashing behavior in this BSP is to utilize JLink. This can be done
by running the `flash` or `flash-jlink` rule for Makefiles, or the
`<target>-jlink` target for CMake.
The Evaluation Kit is shipped with a CMSIS-DAP compatible debug probe. However,
at the time of writing, the necessary flashing algorithms for OpenOCD have not
yet been incorporated into the OpenOCD master branch. To utilize the provided
debug probes, please install the bundled MSDK package which includes the
appropriate OpenOCD modifications. To leverage this OpenOCD instance, run the
`flash-msdk` Makefile rule, or `<target>-msdk` CMake target.

View File

@@ -0,0 +1 @@
# Nothing to be done at the board level

View File

@@ -0,0 +1,58 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2024, Brent Kowal (Analog Devices, Inc)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#ifndef BOARD_H_
#define BOARD_H_
#include "gpio.h"
#include "mxc_sys.h"
#ifdef __cplusplus
extern "C" {
#endif
// LED
#define LED_PORT MXC_GPIO2
#define LED_PIN MXC_GPIO_PIN_4
#define LED_VDDIO MXC_GPIO_VSSEL_VDDIOH
#define LED_STATE_ON 1
// Button
#define BUTTON_PORT MXC_GPIO2
#define BUTTON_PIN MXC_GPIO_PIN_6
#define BUTTON_PULL MXC_GPIO_PAD_PULL_UP
#define BUTTON_STATE_ACTIVE 0
// UART Enable for EvKit's Integrated FTDI Adapter. Pin Mux handled by the HAL
#define UART_NUM 0
#define UART_PORT MXC_GPIO0
#define UART_VDDIO_BITS 0xF
#ifdef __cplusplus
}
#endif
#endif /* BOARD_H_ */

View File

@@ -0,0 +1 @@
# No specific build requirements for the board.

169
hw/bsp/max78002/family.c Normal file
View File

@@ -0,0 +1,169 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2024 Brent Kowal (Analog Devices, Inc)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-prototypes" // _mxc_crit_get_state()
#endif
#include "gpio.h"
#include "mxc_sys.h"
#include "mcr_regs.h"
#include "mxc_device.h"
#include "uart.h"
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#include "board.h"
#include "bsp/board_api.h"
//--------------------------------------------------------------------+
// Forward USB interrupt events to TinyUSB IRQ Handler
//--------------------------------------------------------------------+
void USB_IRQHandler(void) {
tud_int_handler(0);
}
//--------------------------------------------------------------------+
// MACRO TYPEDEF CONSTANT ENUM
//--------------------------------------------------------------------+
mxc_uart_regs_t *ConsoleUart = MXC_UART_GET_UART(UART_NUM);
void board_init(void) {
#if CFG_TUSB_OS == OPT_OS_NONE
// 1ms tick timer
SysTick_Config(SystemCoreClock / 1000);
#elif CFG_TUSB_OS == OPT_OS_FREERTOS
// If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher )
NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
#endif
mxc_gpio_cfg_t gpioConfig;
// LED
gpioConfig.drvstr = MXC_GPIO_DRVSTR_0;
gpioConfig.func = MXC_GPIO_FUNC_OUT;
gpioConfig.mask = LED_PIN;
gpioConfig.pad = MXC_GPIO_PAD_NONE;
gpioConfig.port = LED_PORT;
gpioConfig.vssel = LED_VDDIO;
MXC_GPIO_Config(&gpioConfig);
board_led_write(false);
// Button
gpioConfig.drvstr = MXC_GPIO_DRVSTR_0;
gpioConfig.func = MXC_GPIO_FUNC_IN;
gpioConfig.mask = BUTTON_PIN;
gpioConfig.pad = BUTTON_PULL;
gpioConfig.port = BUTTON_PORT;
gpioConfig.vssel = MXC_GPIO_VSSEL_VDDIO;
MXC_GPIO_Config(&gpioConfig);
// UART
MXC_UART_Init(ConsoleUart, CFG_BOARD_UART_BAUDRATE, MXC_UART_IBRO_CLK);
UART_PORT->vssel |= UART_VDDIO_BITS; //Set necessary bits to 3.3V
//USB
MXC_MCR->ldoctrl |= MXC_F_MCR_LDOCTRL_0P9EN;
MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_USB);
}
//--------------------------------------------------------------------+
// Board porting API
//--------------------------------------------------------------------+
void board_led_write(bool state) {
#if LED_STATE_ON
state = !state;
#endif
if (state) {
MXC_GPIO_OutClr(LED_PORT, LED_PIN);
} else {
MXC_GPIO_OutSet(LED_PORT, LED_PIN);
}
}
uint32_t board_button_read(void) {
uint32_t state = MXC_GPIO_InGet(BUTTON_PORT, BUTTON_PIN) ? 1 : 0;
return BUTTON_STATE_ACTIVE == state;
}
size_t board_get_unique_id(uint8_t id[], size_t max_len) {
uint8_t hw_id[MXC_SYS_USN_CHECKSUM_LEN];//USN Buffer
/* All other 2nd parameter is optional checksum buffer */
MXC_SYS_GetUSN(hw_id, NULL);
size_t act_len = TU_MIN(max_len, MXC_SYS_USN_LEN);
memcpy(id, hw_id, act_len);
return act_len;
}
int board_uart_read(uint8_t *buf, int len) {
int uart_val;
int act_len = 0;
while (act_len < len) {
if ((uart_val = MXC_UART_ReadCharacterRaw(ConsoleUart)) == E_UNDERFLOW) {
break;
} else {
*buf++ = (uint8_t) uart_val;
act_len++;
}
}
return act_len;
}
int board_uart_write(void const *buf, int len) {
int act_len = 0;
const uint8_t *ch_ptr = (const uint8_t *) buf;
while (act_len < len) {
MXC_UART_WriteCharacter(ConsoleUart, *ch_ptr++);
act_len++;
}
return len;
}
#if CFG_TUSB_OS == OPT_OS_NONE
volatile uint32_t system_ticks = 0;
void SysTick_Handler(void) {
system_ticks++;
}
uint32_t board_millis(void) {
return system_ticks;
}
#endif
void HardFault_Handler(void) {
__asm("BKPT #0\n");
}
// Required by __libc_init_array in startup code if we are compiling using
// -nostdlib/-nostartfiles.
void _init(void) {
}

View File

@@ -0,0 +1,166 @@
include_guard()
set(MAX32_PERIPH ${TOP}/hw/mcu/analog/max32/Libraries/PeriphDrivers)
set(MAX32_CMSIS ${TOP}/hw/mcu/analog/max32/Libraries/CMSIS)
set(CMSIS_5 ${TOP}/lib/CMSIS_5)
# include board specific
include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake)
# Get the linker file from current location (family)
set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/max78002.ld)
set(LD_FILE_Clang ${LD_FILE_GNU})
# toolchain set up
set(CMAKE_SYSTEM_PROCESSOR cortex-m4 CACHE INTERNAL "System Processor")
set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake)
set(JLINK_DEVICE max78000)
set(FAMILY_MCUS MAX78002 CACHE INTERNAL "")
function(update_board TARGET)
target_compile_definitions(${TARGET} PUBLIC
TARGET=MAX78002
TARGET_REV=0x4131
MXC_ASSERT_ENABLE
MAX78002
IAR_PRAGMAS=0
CFG_TUSB_MCU=OPT_MCU_MAX78002
BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED
)
endfunction()
#------------------------------------
# BOARD_TARGET
#------------------------------------
# only need to be built ONCE for all examples
function(add_board_target BOARD_TARGET)
if (TARGET ${BOARD_TARGET})
return()
endif ()
# Startup & Linker script
set(STARTUP_FILE_GNU ${MAX32_CMSIS}/Device/Maxim/MAX78002/Source/GCC/startup_max78002.S)
set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU})
set(PERIPH_SRC ${MAX32_PERIPH}/Source)
add_library(${BOARD_TARGET} STATIC
${MAX32_CMSIS}/Device/Maxim/MAX78002/Source/heap.c
${MAX32_CMSIS}/Device/Maxim/MAX78002/Source/system_max78002.c
${PERIPH_SRC}/SYS/mxc_assert.c
${PERIPH_SRC}/SYS/mxc_delay.c
${PERIPH_SRC}/SYS/mxc_lock.c
${PERIPH_SRC}/SYS/nvic_table.c
${PERIPH_SRC}/SYS/pins_ai87.c
${PERIPH_SRC}/SYS/sys_ai87.c
${PERIPH_SRC}/AES/aes_ai87.c
${PERIPH_SRC}/AES/aes_revb.c
${PERIPH_SRC}/FLC/flc_common.c
${PERIPH_SRC}/FLC/flc_ai87.c
${PERIPH_SRC}/FLC/flc_reva.c
${PERIPH_SRC}/GPIO/gpio_common.c
${PERIPH_SRC}/GPIO/gpio_ai87.c
${PERIPH_SRC}/GPIO/gpio_reva.c
${PERIPH_SRC}/ICC/icc_ai87.c
${PERIPH_SRC}/ICC/icc_reva.c
${PERIPH_SRC}/TRNG/trng_ai87.c
${PERIPH_SRC}/TRNG/trng_revb.c
${PERIPH_SRC}/UART/uart_common.c
${PERIPH_SRC}/UART/uart_ai87.c
${PERIPH_SRC}/UART/uart_revb.c
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
)
target_include_directories(${BOARD_TARGET} PUBLIC
${CMAKE_CURRENT_FUNCTION_LIST_DIR}
${MAX32_CMSIS}/Include
${MAX32_CMSIS}/Device/Maxim/MAX78002/Include
${MAX32_PERIPH}/Include/MAX78002
${PERIPH_SRC}/SYS
${PERIPH_SRC}/GPIO
${PERIPH_SRC}/AES
${PERIPH_SRC}/TRNG
${PERIPH_SRC}/ICC
${PERIPH_SRC}/FLC
${PERIPH_SRC}/UART
)
target_compile_options(${BOARD_TARGET} PRIVATE
-Wno-error=strict-prototypes
-Wno-error=redundant-decls
)
update_board(${BOARD_TARGET})
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
target_link_options(${BOARD_TARGET} PUBLIC
"LINKER:--script=${LD_FILE_GNU}"
-nostartfiles
--specs=nosys.specs --specs=nano.specs
)
elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang")
target_link_options(${BOARD_TARGET} PUBLIC
"LINKER:--script=${LD_FILE_Clang}"
)
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}
)
target_compile_options(${TARGET} PRIVATE
-Wno-error=strict-prototypes
-Wno-error=redundant-decls
)
# Add TinyUSB target and port source
family_add_tinyusb(${TARGET} OPT_MCU_MAX78002 ${RTOS})
target_sources(${TARGET}-tinyusb PUBLIC
${TOP}/src/portable/mentor/musb/dcd_musb.c
)
target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD})
target_compile_options(${TARGET}-tinyusb PRIVATE
-Wno-error=strict-prototypes
-Wno-error=redundant-decls
)
# Link dependencies
target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb)
# Flashing
family_flash_jlink(${TARGET})
family_flash_msdk(${TARGET})
endfunction()
# Add flash msdk target
function(family_flash_msdk TARGET)
set(MAXIM_PATH "$ENV{MAXIM_PATH}")
add_custom_target(${TARGET}-msdk
DEPENDS ${TARGET}
COMMAND ${MAXIM_PATH}/Tools/OpenOCD/openocd -s ${MAXIM_PATH}/Tools/OpenOCD/scripts
-f interface/cmsis-dap.cfg -f target/max78002.cfg
-c "program $<TARGET_FILE:${TARGET}> verify; init; reset; exit"
VERBATIM
)
endfunction()

99
hw/bsp/max78002/family.mk Normal file
View File

@@ -0,0 +1,99 @@
DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/analog/max32
# Important locations in the hw support for MCU
MAX32_CMSIS = hw/mcu/analog/max32/Libraries/CMSIS
MAX32_PERIPH = hw/mcu/analog/max32/Libraries/PeriphDrivers
# Add any board specific make rules
include $(TOP)/$(BOARD_PATH)/board.mk
CPU_CORE ?= cortex-m4
PORT ?= 0
# GCC
SRC_S_GCC += $(MAX32_CMSIS)/Device/Maxim/MAX78002/Source/GCC/startup_max78002.S
LD_FILE = $(FAMILY_PATH)/max78002.ld
# --------------
# Compiler Flags
# --------------
# Flags for the MAX78002 SDK
CFLAGS += -DTARGET=MAX78002 \
-DTARGET_REV=0x4131 \
-DMXC_ASSERT_ENABLE \
-DMAX78002 \
-DIAR_PRAGMAS=0
# Flags for TUSB features
CFLAGS += \
-DCFG_TUSB_MCU=OPT_MCU_MAX78002 \
-DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED
# mcu driver cause following warnings
CFLAGS += -Wno-error=redundant-decls \
-Wno-error=strict-prototypes \
-Wno-error=unused-parameter \
-Wno-error=enum-conversion \
-Wno-error=sign-compare \
-Wno-error=cast-qual
LDFLAGS_GCC += -nostartfiles --specs=nosys.specs --specs=nano.specs
# For flash-jlink target
JLINK_DEVICE = max78000
# flash target using Jlink by default
flash: flash-jlink
# Optional flash option when running within an installed MSDK to use OpenOCD
# Mainline OpenOCD does not yet have the MAX32's flash algorithm integrated.
# If the MSDK is installed, flash-msdk can be run to utilize the the modified
# openocd with the algorithms
MAXIM_PATH := $(subst \,/,$(MAXIM_PATH))
flash-msdk: $(BUILD)/$(PROJECT).elf
$(MAXIM_PATH)/Tools/OpenOCD/openocd -s $(MAXIM_PATH)/Tools/OpenOCD/scripts \
-f interface/cmsis-dap.cfg -f target/max78002.cfg \
-c "program $(BUILD)/$(PROJECT).elf verify; init; reset; exit"
# -----------------
# Sources & Include
# -----------------
PERIPH_SRC = $(TOP)/$(MAX32_PERIPH)/Source
SRC_C += \
src/portable/mentor/musb/dcd_musb.c \
$(MAX32_CMSIS)/Device/Maxim/MAX78002/Source/heap.c \
$(MAX32_CMSIS)/Device/Maxim/MAX78002/Source/system_max78002.c \
$(PERIPH_SRC)/SYS/mxc_assert.c \
$(PERIPH_SRC)/SYS/mxc_delay.c \
$(PERIPH_SRC)/SYS/mxc_lock.c \
$(PERIPH_SRC)/SYS/nvic_table.c \
$(PERIPH_SRC)/SYS/pins_ai87.c \
$(PERIPH_SRC)/SYS/sys_ai87.c \
$(PERIPH_SRC)/AES/aes_ai87.c \
$(PERIPH_SRC)/AES/aes_revb.c \
$(PERIPH_SRC)/FLC/flc_common.c \
$(PERIPH_SRC)/FLC/flc_ai87.c \
$(PERIPH_SRC)/FLC/flc_reva.c \
$(PERIPH_SRC)/GPIO/gpio_common.c \
$(PERIPH_SRC)/GPIO/gpio_ai87.c \
$(PERIPH_SRC)/GPIO/gpio_reva.c \
$(PERIPH_SRC)/ICC/icc_ai87.c \
$(PERIPH_SRC)/ICC/icc_reva.c \
$(PERIPH_SRC)/TRNG/trng_ai87.c \
$(PERIPH_SRC)/TRNG/trng_revb.c \
$(PERIPH_SRC)/UART/uart_common.c \
$(PERIPH_SRC)/UART/uart_ai87.c \
$(PERIPH_SRC)/UART/uart_revb.c \
INC += \
$(TOP)/$(BOARD_PATH) \
$(TOP)/$(MAX32_CMSIS)/Include \
$(TOP)/$(MAX32_CMSIS)/Device/Maxim/MAX78002/Include \
$(TOP)/$(MAX32_PERIPH)/Include/MAX78002 \
$(PERIPH_SRC)/SYS \
$(PERIPH_SRC)/GPIO \
$(PERIPH_SRC)/AES \
$(PERIPH_SRC)/ICC \
$(PERIPH_SRC)/FLC \
$(PERIPH_SRC)/TRNG \
$(PERIPH_SRC)/UART

182
hw/bsp/max78002/max78002.ld Normal file
View File

@@ -0,0 +1,182 @@
MEMORY {
ROM (rx) : ORIGIN = 0x00000000, LENGTH = 0x00010000 /* 64 kB ROM */
FLASH (rx) : ORIGIN = 0x10000000, LENGTH = 0x00280000 /* 2.5 MB Flash */
SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00060000 /* 384 kB SRAM */
/*CSI2 (rwx) : ORIGIN = 0x2001F000, LENGTH = 0x00001000 4096 B CSI2 Buffer */
}
SECTIONS {
.rom :
{
KEEP(*(.rom_vector))
*(.rom_handlers*)
} > ROM
.text :
{
_text = .;
KEEP(*(.isr_vector))
EXCLUDE_FILE (*riscv.o) *(.text*) /* Program code (exclude RISCV code) */
*(.rodata*) /* read-only data: "const" */
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
/* C++ Exception handling */
KEEP(*(.eh_frame*))
_etext = .;
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
/* Binary import */
.bin_storage :
{
FILL(0xFF)
_bin_start_ = .;
KEEP(*(.bin_storage_img))
_bin_end_ = .;
. = ALIGN(4);
} > FLASH
.rom_code :
{
. = ALIGN(16);
_sran_code = .;
*(.rom_code_section)
_esran_code = .;
} > ROM
.flash_code :
{
. = ALIGN(16);
_sran_code = .;
*(.flash_code_section)
_esran_code = .;
} > FLASH
.sram_code :
{
. = ALIGN(16);
_sran_code = .;
*(.sram_code_section)
_esran_code = .;
} > SRAM
/* it's used for C++ exception handling */
/* we need to keep this to avoid overlapping */
.ARM.exidx :
{
__exidx_start = .;
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
__exidx_end = .;
} > FLASH
.data :
{
_data = ALIGN(., 4);
_csi = . + 0x20000;
*(vtable)
*(.data*) /*read-write initialized data: initialized global variable*/
/* These array sections are used by __libc_init_array to call static C++ constructors */
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
_edata = ALIGN(., 4);
} > SRAM AT>FLASH
__load_data = LOADADDR(.data);
.bss :
{
. = ALIGN(4);
_bss = .;
*(.bss*) /*read-write zero initialized data: uninitialized global variable*/
*(COMMON)
_ebss = ALIGN(., 4);
} > SRAM
.shared :
{
. = ALIGN(4);
_shared = .;
*(.mailbox*)
. = ALIGN(4);
*(.shared*) /*read-write zero initialized data: uninitialized global variable*/
_eshared = ALIGN(., 4);
} > SRAM
__shared_data = LOADADDR(.shared);
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(SRAM) + LENGTH(SRAM);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (COPY):
{
*(.stack*)
} > SRAM
.heap (COPY):
{
. = ALIGN(4);
PROVIDE ( end = . );
PROVIDE ( _end = . );
*(.heap*)
__HeapLimit = ABSOLUTE(__StackLimit);
} > SRAM
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= _ebss, "region RAM overflowed with stack")
/* Section used by RISCV loader projects. See RISCV_LOAD documentation in the build system. */
.riscv_flash :
{
/* Align address to mod 256 with a small offset. This is required to match the flash page size.*/
. = ALIGN(256); /* ALIGN operatator is used here. Note that (. & 0x1FFFFF00) was used in the past, but a strange bug was seen on Windows where the & did not behave as expected.*/
. += 0x100;
_riscv_boot = .;
KEEP(*riscv.o (.text*))
} > FLASH
}

View File

@@ -2,7 +2,7 @@ set(MCU_VARIANT nrf52840)
set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/nrf52840_s140_v6.ld)
# enable max3421 host driver for this board
set(MAX3421_HOST 1)
# set(MAX3421_HOST 1)
function(update_board TARGET)
endfunction()

View File

@@ -1,5 +0,0 @@
set(MCU_VARIANT nrf52840)
set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/nrf52840_mdk_dongle.ld)
function(update_board TARGET)
endfunction()

View File

@@ -1,15 +0,0 @@
MCU_VARIANT = nrf52840
CFLAGS += -DNRF52840_XXAA
LD_FILE = $(BOARD_PATH)/$(BOARD).ld
# flash using Nordic nrfutil (pip3 install nrfutil)
# make BOARD=nrf52840_mdk_dongle SERIAL=/dev/ttyACM0 all flash
NRFUTIL = nrfutil
$(BUILD)/$(PROJECT).zip: $(BUILD)/$(PROJECT).hex
$(NRFUTIL) pkg generate --hw-version 52 --sd-req 0x0000 --debug-mode --application $^ $@
flash: $(BUILD)/$(PROJECT).zip
@:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyACM0)
$(NRFUTIL) dfu usb-serial --package $^ -p $(SERIAL) -b 115200

View File

@@ -1,13 +0,0 @@
/* Linker script to configure memory regions. */
SEARCH_DIR(.)
/*GROUP(-lgcc -lc -lnosys) not compatible with clang*/
MEMORY
{
FLASH (rx) : ORIGIN = 0x1000, LENGTH = 0xE0000-0x1000
RAM (rwx) : ORIGIN = 0x20000008, LENGTH = 0x3fff8
}
INCLUDE "nrf_common.ld"

View File

@@ -1,4 +0,0 @@
set(MCU_VARIANT nrf52840)
function(update_board TARGET)
endfunction()

View File

@@ -1,7 +0,0 @@
MCU_VARIANT = nrf52840
CFLAGS += -DNRF52840_XXAA
LD_FILE = hw/mcu/nordic/nrfx/mdk/nrf52840_xxaa.ld
# flash using jlink
flash: flash-jlink

View File

@@ -78,7 +78,12 @@
// USB Host MAX3421E
//--------------------------------------------------------------------
#define MAX3421_SPI PICO_DEFAULT_SPI_INSTANCE
#ifdef PICO_DEFAULT_SPI
#define MAX3421_SPI PICO_DEFAULT_SPI // sdk v2
#else
#define MAX3421_SPI PICO_DEFAULT_SPI_INSTANCE // sdk v1
#endif
#define MAX3421_SCK_PIN PICO_DEFAULT_SPI_SCK_PIN
#define MAX3421_MOSI_PIN PICO_DEFAULT_SPI_TX_PIN
#define MAX3421_MISO_PIN PICO_DEFAULT_SPI_RX_PIN

Some files were not shown because too many files have changed in this diff Show More