mirror of
https://github.com/hathach/tinyusb.git
synced 2025-04-16 05:42:56 +00:00
Merge remote-tracking branch 'remotes/tinyusb/master' into rx_fb
This commit is contained in:
commit
8133af4e08
66
.clang-format
Normal file
66
.clang-format
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
# Generated from CLion C/C++ Code Style settings
|
||||||
|
BasedOnStyle: LLVM
|
||||||
|
AccessModifierOffset: -2
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignConsecutiveAssignments: None
|
||||||
|
AlignOperands: Align
|
||||||
|
AllowAllArgumentsOnNextLine: false
|
||||||
|
AllowAllConstructorInitializersOnNextLine: false
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
|
AllowShortBlocksOnASingleLine: Always
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: All
|
||||||
|
AllowShortIfStatementsOnASingleLine: Always
|
||||||
|
AllowShortLambdasOnASingleLine: All
|
||||||
|
AllowShortLoopsOnASingleLine: true
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakTemplateDeclarations: Yes
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: false
|
||||||
|
AfterClass: false
|
||||||
|
AfterControlStatement: Never
|
||||||
|
AfterEnum: false
|
||||||
|
AfterFunction: false
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterUnion: false
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: false
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: false
|
||||||
|
SplitEmptyRecord: true
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
BreakInheritanceList: BeforeColon
|
||||||
|
ColumnLimit: 0
|
||||||
|
CompactNamespaces: false
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
IndentCaseLabels: true
|
||||||
|
IndentPPDirectives: BeforeHash
|
||||||
|
IndentWidth: 2
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||||
|
MaxEmptyLinesToKeep: 2
|
||||||
|
NamespaceIndentation: All
|
||||||
|
ObjCSpaceAfterProperty: false
|
||||||
|
ObjCSpaceBeforeProtocolList: true
|
||||||
|
PointerAlignment: Right
|
||||||
|
ReflowComments: false
|
||||||
|
SpaceAfterCStyleCast: true
|
||||||
|
SpaceAfterLogicalNot: false
|
||||||
|
SpaceAfterTemplateKeyword: false
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCpp11BracedList: false
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: false
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: 0
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInContainerLiterals: true
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
TabWidth: 2
|
||||||
|
UseTab: Never
|
9
.github/workflows/build_arm.yml
vendored
9
.github/workflows/build_arm.yml
vendored
@ -35,14 +35,7 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
family:
|
family:
|
||||||
# Alphabetical order
|
# Alphabetical order
|
||||||
- 'broadcom_32bit'
|
- 'mm32'
|
||||||
- 'kinetis_k32l2'
|
|
||||||
- 'lpc11 lpc13 lpc15'
|
|
||||||
- 'lpc51'
|
|
||||||
- 'mm32 msp432e4'
|
|
||||||
- 'samd11 same5x saml2x'
|
|
||||||
- 'stm32l0 stm32wb'
|
|
||||||
- 'tm4c123 xmc4000'
|
|
||||||
steps:
|
steps:
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
|
28
.github/workflows/build_cmake.yml
vendored
28
.github/workflows/build_cmake.yml
vendored
@ -37,16 +37,19 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
family:
|
family:
|
||||||
# Alphabetical order
|
# Alphabetical order
|
||||||
|
- 'broadcom_32bit'
|
||||||
- 'imxrt'
|
- 'imxrt'
|
||||||
- 'kinetis_k kinetis_kl'
|
- 'kinetis_k kinetis_kl kinetis_k32l2'
|
||||||
|
- 'lpc11 lpc13 lpc15'
|
||||||
- 'lpc17 lpc18 lpc40 lpc43'
|
- 'lpc17 lpc18 lpc40 lpc43'
|
||||||
- 'lpc54 lpc55'
|
- 'lpc51 lpc54 lpc55'
|
||||||
- 'mcx'
|
- 'mcx'
|
||||||
|
- 'msp432e4'
|
||||||
|
- 'mm32'
|
||||||
- 'nrf'
|
- 'nrf'
|
||||||
- 'ra'
|
- 'ra'
|
||||||
- 'rp2040'
|
- 'rp2040'
|
||||||
- 'samd21'
|
- 'samd11 samd21 saml2x samd5x_e5x samg'
|
||||||
- 'samd51'
|
|
||||||
- 'stm32f0'
|
- 'stm32f0'
|
||||||
- 'stm32f1'
|
- 'stm32f1'
|
||||||
- 'stm32f2'
|
- 'stm32f2'
|
||||||
@ -59,6 +62,9 @@ jobs:
|
|||||||
- 'stm32h7'
|
- 'stm32h7'
|
||||||
- 'stm32l4'
|
- 'stm32l4'
|
||||||
- 'stm32u5'
|
- 'stm32u5'
|
||||||
|
- 'stm32wb'
|
||||||
|
- 'tm4c'
|
||||||
|
- 'xmc4000'
|
||||||
steps:
|
steps:
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
@ -87,12 +93,12 @@ jobs:
|
|||||||
python3 tools/get_deps.py ${{ matrix.family }}
|
python3 tools/get_deps.py ${{ matrix.family }}
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: python tools/build_cmake.py ${{ matrix.family }} -DCMAKE_BUILD_TYPE=MinSizeRel
|
run: python tools/build_cmake.py ${{ matrix.family }}
|
||||||
env:
|
env:
|
||||||
PICO_SDK_PATH: ${{ github.workspace }}/pico-sdk
|
PICO_SDK_PATH: ${{ github.workspace }}/pico-sdk
|
||||||
|
|
||||||
- name: Upload Artifacts for Hardware Testing (rp2040)
|
- name: Upload Artifacts for Hardware Testing (rp2040)
|
||||||
if: matrix.family == 'rp2040' && github.repository_owner == 'hathach'
|
if: contains(matrix.family, 'rp2040') && github.repository_owner == 'hathach'
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: raspberry_pi_pico
|
name: raspberry_pi_pico
|
||||||
@ -100,7 +106,7 @@ jobs:
|
|||||||
cmake-build/cmake-build-raspberry_pi_pico/*/*/*.elf
|
cmake-build/cmake-build-raspberry_pi_pico/*/*/*.elf
|
||||||
|
|
||||||
- name: Upload Artifacts for Hardware Testing (nRF)
|
- name: Upload Artifacts for Hardware Testing (nRF)
|
||||||
if: matrix.family == 'nrf' && github.repository_owner == 'hathach'
|
if: contains(matrix.family, 'nrf') && github.repository_owner == 'hathach'
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: feather_nrf52840_express
|
name: feather_nrf52840_express
|
||||||
@ -108,7 +114,7 @@ jobs:
|
|||||||
cmake-build/cmake-build-feather_nrf52840_express/*/*/*.elf
|
cmake-build/cmake-build-feather_nrf52840_express/*/*/*.elf
|
||||||
|
|
||||||
- name: Upload Artifacts for Hardware Testing (samd51)
|
- name: Upload Artifacts for Hardware Testing (samd51)
|
||||||
if: matrix.family == 'samd51' && github.repository_owner == 'hathach'
|
if: contains(matrix.family, 'samd5x_e5x') && github.repository_owner == 'hathach'
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: itsybitsy_m4
|
name: itsybitsy_m4
|
||||||
@ -134,7 +140,7 @@ jobs:
|
|||||||
#- 'ra' port later
|
#- 'ra' port later
|
||||||
#- 'rp2040' port later
|
#- 'rp2040' port later
|
||||||
- 'samd21'
|
- 'samd21'
|
||||||
- 'samd51'
|
- 'samd5x_e5x'
|
||||||
- 'stm32f0'
|
- 'stm32f0'
|
||||||
- 'stm32f1'
|
- 'stm32f1'
|
||||||
- 'stm32f2'
|
- 'stm32f2'
|
||||||
@ -188,7 +194,7 @@ jobs:
|
|||||||
python3 tools/get_deps.py ${{ matrix.family }}
|
python3 tools/get_deps.py ${{ matrix.family }}
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: python tools/build_cmake.py ${{ matrix.family }} -DTOOLCHAIN=clang -DCMAKE_BUILD_TYPE=MinSizeRel
|
run: python tools/build_cmake.py ${{ matrix.family }} -DTOOLCHAIN=clang
|
||||||
env:
|
env:
|
||||||
PICO_SDK_PATH: ${{ github.workspace }}/pico-sdk
|
PICO_SDK_PATH: ${{ github.workspace }}/pico-sdk
|
||||||
|
|
||||||
@ -236,7 +242,7 @@ jobs:
|
|||||||
python3 tools/get_deps.py ${{ matrix.family }}
|
python3 tools/get_deps.py ${{ matrix.family }}
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: python tools/build_cmake.py ${{ matrix.family }} -DCMAKE_BUILD_TYPE=MinSizeRel
|
run: python tools/build_cmake.py ${{ matrix.family }}
|
||||||
|
|
||||||
# ---------------------------------------
|
# ---------------------------------------
|
||||||
# Hardware in the loop (HIL)
|
# Hardware in the loop (HIL)
|
||||||
|
2
.github/workflows/build_iar.yml
vendored
2
.github/workflows/build_iar.yml
vendored
@ -52,7 +52,7 @@ jobs:
|
|||||||
run: python3 tools/get_deps.py ${{ matrix.family }}
|
run: python3 tools/get_deps.py ${{ matrix.family }}
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: python3 tools/build_cmake.py ${{ matrix.family }} -DTOOLCHAIN=iar -DCMAKE_BUILD_TYPE=MinSizeRel
|
run: python3 tools/build_cmake.py ${{ matrix.family }} -DTOOLCHAIN=iar
|
||||||
|
|
||||||
- name: Test on actual hardware (hardware in the loop)
|
- name: Test on actual hardware (hardware in the loop)
|
||||||
run: |
|
run: |
|
||||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -57,6 +57,7 @@ hw/mcu/st/cmsis_device_f4
|
|||||||
hw/mcu/st/cmsis_device_f7
|
hw/mcu/st/cmsis_device_f7
|
||||||
hw/mcu/st/cmsis_device_g0
|
hw/mcu/st/cmsis_device_g0
|
||||||
hw/mcu/st/cmsis_device_g4
|
hw/mcu/st/cmsis_device_g4
|
||||||
|
hw/mcu/st/cmsis_device_h5
|
||||||
hw/mcu/st/cmsis_device_h7
|
hw/mcu/st/cmsis_device_h7
|
||||||
hw/mcu/st/cmsis_device_l0
|
hw/mcu/st/cmsis_device_l0
|
||||||
hw/mcu/st/cmsis_device_l1
|
hw/mcu/st/cmsis_device_l1
|
||||||
@ -72,6 +73,7 @@ hw/mcu/st/stm32f4xx_hal_driver
|
|||||||
hw/mcu/st/stm32f7xx_hal_driver
|
hw/mcu/st/stm32f7xx_hal_driver
|
||||||
hw/mcu/st/stm32g0xx_hal_driver
|
hw/mcu/st/stm32g0xx_hal_driver
|
||||||
hw/mcu/st/stm32g4xx_hal_driver
|
hw/mcu/st/stm32g4xx_hal_driver
|
||||||
|
hw/mcu/st/stm32h5xx_hal_driver
|
||||||
hw/mcu/st/stm32h7xx_hal_driver
|
hw/mcu/st/stm32h7xx_hal_driver
|
||||||
hw/mcu/st/stm32l0xx_hal_driver
|
hw/mcu/st/stm32l0xx_hal_driver
|
||||||
hw/mcu/st/stm32l1xx_hal_driver
|
hw/mcu/st/stm32l1xx_hal_driver
|
||||||
|
41
.idea/cmake.xml
generated
41
.idea/cmake.xml
generated
@ -41,10 +41,32 @@
|
|||||||
</envs>
|
</envs>
|
||||||
</ADDITIONAL_GENERATION_ENVIRONMENT>
|
</ADDITIONAL_GENERATION_ENVIRONMENT>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
<configuration PROFILE_NAME="adafruit_metro_esp32s2" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=adafruit_metro_esp32s2 -DMAX3421_HOST=1 -DLOG=2">
|
||||||
|
<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">
|
||||||
|
<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">
|
||||||
|
<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="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="true" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=metro_m0_express -DLOG=3 -DLOGGER=RTT -DMAX3421_HOST=1" />
|
<configuration PROFILE_NAME="metro_m0_express" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=metro_m0_express -DLOG=3 -DLOGGER=RTT -DMAX3421_HOST=1" />
|
||||||
<configuration PROFILE_NAME="feather_m4_express" ENABLED="true" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=feather_m4_express -DLOG=3 -DLOGGER=RTT -DMAX3421_HOST=1" />
|
<configuration PROFILE_NAME="feather_m4_express" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=feather_m4_express -DLOG=3 -DLOGGER=RTT -DMAX3421_HOST=1" />
|
||||||
<configuration PROFILE_NAME="metro_m4_express" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=metro_m4_express -DLOG=3 -DLOGGER=RTT -DMAX3421_HOST=1" />
|
<configuration PROFILE_NAME="metro_m4_express" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=metro_m4_express -DLOG=3 -DLOGGER=RTT -DMAX3421_HOST=1" />
|
||||||
|
<configuration PROFILE_NAME="same54_xplained" ENABLED="false" GENERATION_OPTIONS="-DBOARD=same54_xplained -DLOG=2 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="feather_nrf52840_express" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=feather_nrf52840_express -DLOG=3 -DLOGGER=RTT -DMAX3421_HOST=1" />
|
<configuration PROFILE_NAME="feather_nrf52840_express" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=feather_nrf52840_express -DLOG=3 -DLOGGER=RTT -DMAX3421_HOST=1" />
|
||||||
<configuration PROFILE_NAME="pca10056" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=pca10056 -DLOG=3 -DLOGGER=RTT -DTRACE_ETM=1" />
|
<configuration PROFILE_NAME="pca10056" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=pca10056 -DLOG=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="pca10095" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=pca10095 -DLOG=3 -DLOGGER=RTT -DTRACE_ETM=1" />
|
||||||
@ -89,6 +111,21 @@
|
|||||||
<configuration PROFILE_NAME="uno_r4" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=uno_r4 -DLOG=4 -DLOGGER=RTT" />
|
<configuration PROFILE_NAME="uno_r4" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=uno_r4 -DLOG=4 -DLOGGER=RTT" />
|
||||||
<configuration PROFILE_NAME="portenta_c33" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=portenta_c33 -DLOG=3" />
|
<configuration PROFILE_NAME="portenta_c33" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=portenta_c33 -DLOG=3" />
|
||||||
<configuration PROFILE_NAME="msp430f5529" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=msp_exp430f5529lp" />
|
<configuration PROFILE_NAME="msp430f5529" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=msp_exp430f5529lp" />
|
||||||
|
<configuration PROFILE_NAME="raspberrypi_zero" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=raspberrypi_zero -DLOG=2" />
|
||||||
|
<configuration PROFILE_NAME="raspberrypi_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="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" 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="atsaml21_xpro" ENABLED="false" GENERATION_OPTIONS="-DBOARD=atsaml21_xpro" />
|
||||||
|
<configuration PROFILE_NAME="stm32wb55nucleo" ENABLED="false" GENERATION_OPTIONS="-DBOARD=stm32wb55nucleo" />
|
||||||
|
<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="f1c100s" ENABLED="false" GENERATION_OPTIONS="-DBOARD=f1c100s" />
|
||||||
|
<configuration PROFILE_NAME="samg55_xplained" ENABLED="true" GENERATION_OPTIONS="-DBOARD=samg55_xplained" />
|
||||||
</configurations>
|
</configurations>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
2
.idea/runConfigurations/rp2040.xml
generated
2
.idea/runConfigurations/rp2040.xml
generated
@ -1,5 +1,5 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="rp2040" type="com.jetbrains.cidr.embedded.openocd.conf.type" factoryName="com.jetbrains.cidr.embedded.openocd.conf.factory" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="tinyusb_examples" TARGET_NAME="cdc_msc" CONFIG_NAME="metro_m4_express" version="1" RUN_TARGET_PROJECT_NAME="tinyusb_examples" RUN_TARGET_NAME="cdc_msc">
|
<configuration default="false" name="rp2040" type="com.jetbrains.cidr.embedded.openocd.conf.type" factoryName="com.jetbrains.cidr.embedded.openocd.conf.factory" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="tinyusb_examples" TARGET_NAME="cdc_msc" version="1" RUN_TARGET_PROJECT_NAME="tinyusb_examples" RUN_TARGET_NAME="cdc_msc">
|
||||||
<openocd version="1" gdb-port="3333" telnet-port="4444" board-config="$PROJECT_DIR$/hw/bsp/rp2040/rp2040-openocd.cfg" reset-type="INIT" download-type="UPDATED_ONLY">
|
<openocd version="1" gdb-port="3333" telnet-port="4444" board-config="$PROJECT_DIR$/hw/bsp/rp2040/rp2040-openocd.cfg" reset-type="INIT" download-type="UPDATED_ONLY">
|
||||||
<debugger kind="GDB" isBundled="true" />
|
<debugger kind="GDB" isBundled="true" />
|
||||||
</openocd>
|
</openocd>
|
||||||
|
21
examples/build_system/cmake/cpu/arm1176jzf-s.cmake
Normal file
21
examples/build_system/cmake/cpu/arm1176jzf-s.cmake
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
if (TOOLCHAIN STREQUAL "gcc")
|
||||||
|
set(TOOLCHAIN_COMMON_FLAGS
|
||||||
|
-mcpu=arm1176jzf-s
|
||||||
|
-ffreestanding
|
||||||
|
)
|
||||||
|
# set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "")
|
||||||
|
|
||||||
|
elseif (TOOLCHAIN STREQUAL "clang")
|
||||||
|
set(TOOLCHAIN_COMMON_FLAGS
|
||||||
|
--target=arm-none-eabi
|
||||||
|
-mcpu=arm1176jzf-s
|
||||||
|
-mfpu=none
|
||||||
|
-mfloat-abi=soft
|
||||||
|
-ffreestanding
|
||||||
|
)
|
||||||
|
#set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "")
|
||||||
|
|
||||||
|
elseif (TOOLCHAIN STREQUAL "iar")
|
||||||
|
message(FATAL_ERROR "IAR not supported")
|
||||||
|
|
||||||
|
endif ()
|
21
examples/build_system/cmake/cpu/arm926ej-s.cmake
Normal file
21
examples/build_system/cmake/cpu/arm926ej-s.cmake
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
if (TOOLCHAIN STREQUAL "gcc")
|
||||||
|
set(TOOLCHAIN_COMMON_FLAGS
|
||||||
|
-mcpu=arm926ej-s
|
||||||
|
-ffreestanding
|
||||||
|
)
|
||||||
|
# set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "")
|
||||||
|
|
||||||
|
elseif (TOOLCHAIN STREQUAL "clang")
|
||||||
|
set(TOOLCHAIN_COMMON_FLAGS
|
||||||
|
--target=arm-none-eabi
|
||||||
|
-mcpu=arm926ej-s
|
||||||
|
-mfpu=none
|
||||||
|
-mfloat-abi=soft
|
||||||
|
-ffreestanding
|
||||||
|
)
|
||||||
|
#set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "")
|
||||||
|
|
||||||
|
elseif (TOOLCHAIN STREQUAL "iar")
|
||||||
|
message(FATAL_ERROR "IAR not supported")
|
||||||
|
|
||||||
|
endif ()
|
17
examples/build_system/cmake/cpu/cortex-a53.cmake
Normal file
17
examples/build_system/cmake/cpu/cortex-a53.cmake
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
if (TOOLCHAIN STREQUAL "gcc")
|
||||||
|
set(TOOLCHAIN_COMMON_FLAGS
|
||||||
|
-mcpu=cortex-a53
|
||||||
|
)
|
||||||
|
# set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "")
|
||||||
|
|
||||||
|
elseif (TOOLCHAIN STREQUAL "clang")
|
||||||
|
set(TOOLCHAIN_COMMON_FLAGS
|
||||||
|
--target=arm-none-eabi
|
||||||
|
-mcpu=cortex-a53
|
||||||
|
)
|
||||||
|
#set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "")
|
||||||
|
|
||||||
|
elseif (TOOLCHAIN STREQUAL "iar")
|
||||||
|
message(FATAL_ERROR "IAR not supported")
|
||||||
|
|
||||||
|
endif ()
|
17
examples/build_system/cmake/cpu/cortex-a72.cmake
Normal file
17
examples/build_system/cmake/cpu/cortex-a72.cmake
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
if (TOOLCHAIN STREQUAL "gcc")
|
||||||
|
set(TOOLCHAIN_COMMON_FLAGS
|
||||||
|
-mcpu=cortex-a72
|
||||||
|
)
|
||||||
|
# set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "")
|
||||||
|
|
||||||
|
elseif (TOOLCHAIN STREQUAL "clang")
|
||||||
|
set(TOOLCHAIN_COMMON_FLAGS
|
||||||
|
--target=arm-none-eabi
|
||||||
|
-mcpu=cortex-a72
|
||||||
|
)
|
||||||
|
#set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "")
|
||||||
|
|
||||||
|
elseif (TOOLCHAIN STREQUAL "iar")
|
||||||
|
message(FATAL_ERROR "IAR not supported")
|
||||||
|
|
||||||
|
endif ()
|
25
examples/build_system/cmake/cpu/cortex-m7-fpsp.cmake
Normal file
25
examples/build_system/cmake/cpu/cortex-m7-fpsp.cmake
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
if (TOOLCHAIN STREQUAL "gcc")
|
||||||
|
set(TOOLCHAIN_COMMON_FLAGS
|
||||||
|
-mthumb
|
||||||
|
-mcpu=cortex-m7
|
||||||
|
-mfloat-abi=hard
|
||||||
|
-mfpu=fpv5-sp-d16
|
||||||
|
)
|
||||||
|
set(FREERTOS_PORT GCC_ARM_CM7 CACHE INTERNAL "")
|
||||||
|
|
||||||
|
elseif (TOOLCHAIN STREQUAL "clang")
|
||||||
|
set(TOOLCHAIN_COMMON_FLAGS
|
||||||
|
--target=arm-none-eabi
|
||||||
|
-mcpu=cortex-m7
|
||||||
|
-mfpu=fpv5-sp-d16
|
||||||
|
)
|
||||||
|
set(FREERTOS_PORT GCC_ARM_CM7 CACHE INTERNAL "")
|
||||||
|
|
||||||
|
elseif (TOOLCHAIN STREQUAL "iar")
|
||||||
|
set(TOOLCHAIN_COMMON_FLAGS
|
||||||
|
--cpu cortex-m7
|
||||||
|
--fpu VFPv5_sp
|
||||||
|
)
|
||||||
|
set(FREERTOS_PORT IAR_ARM_CM7 CACHE INTERNAL "")
|
||||||
|
|
||||||
|
endif ()
|
21
examples/build_system/cmake/toolchain/aarch64_gcc.cmake
Normal file
21
examples/build_system/cmake/toolchain/aarch64_gcc.cmake
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
if (NOT DEFINED CMAKE_C_COMPILER)
|
||||||
|
set(CMAKE_C_COMPILER "aarch64-none-elf-gcc")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (NOT DEFINED CMAKE_CXX_COMPILER)
|
||||||
|
set(CMAKE_CXX_COMPILER "aarch64-none-elf-g++")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER})
|
||||||
|
set(CMAKE_SIZE "aarch64-none-elf-size" CACHE FILEPATH "")
|
||||||
|
set(CMAKE_OBJCOPY "aarch64-none-elf-objcopy" CACHE FILEPATH "")
|
||||||
|
set(CMAKE_OBJDUMP "aarch64-none-elf-objdump" CACHE FILEPATH "")
|
||||||
|
|
||||||
|
include(${CMAKE_CURRENT_LIST_DIR}/common.cmake)
|
||||||
|
|
||||||
|
get_property(IS_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE)
|
||||||
|
if (IS_IN_TRY_COMPILE)
|
||||||
|
set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -nostdlib")
|
||||||
|
set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -nostdlib")
|
||||||
|
cmake_print_variables(CMAKE_C_LINK_FLAGS)
|
||||||
|
endif ()
|
9
examples/build_system/make/cpu/arm926ej-s.mk
Normal file
9
examples/build_system/make/cpu/arm926ej-s.mk
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
ifeq ($(TOOLCHAIN),gcc)
|
||||||
|
CFLAGS += \
|
||||||
|
-mcpu=arm926ej-s \
|
||||||
|
|
||||||
|
else ifeq ($(TOOLCHAIN),iar)
|
||||||
|
#CFLAGS += --cpu cortex-a53
|
||||||
|
#ASFLAGS += --cpu cortex-a53
|
||||||
|
|
||||||
|
endif
|
27
examples/build_system/make/cpu/cortex-m7-fpsp.mk
Normal file
27
examples/build_system/make/cpu/cortex-m7-fpsp.mk
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
ifeq ($(TOOLCHAIN),gcc)
|
||||||
|
CFLAGS += \
|
||||||
|
-mthumb \
|
||||||
|
-mcpu=cortex-m7 \
|
||||||
|
-mfloat-abi=hard \
|
||||||
|
-mfpu=fpv5-sp-d16 \
|
||||||
|
|
||||||
|
else ifeq ($(TOOLCHAIN),clang)
|
||||||
|
CFLAGS += \
|
||||||
|
--target=arm-none-eabi \
|
||||||
|
-mcpu=cortex-m7 \
|
||||||
|
-mfpu=fpv5-sp-d16 \
|
||||||
|
|
||||||
|
else ifeq ($(TOOLCHAIN),iar)
|
||||||
|
CFLAGS += \
|
||||||
|
--cpu cortex-m7 \
|
||||||
|
--fpu VFPv5_sp \
|
||||||
|
|
||||||
|
ASFLAGS += \
|
||||||
|
--cpu cortex-m7 \
|
||||||
|
--fpu VFPv5_sp \
|
||||||
|
|
||||||
|
else
|
||||||
|
$(error "TOOLCHAIN is not supported")
|
||||||
|
endif
|
||||||
|
|
||||||
|
FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM7/r0p1
|
@ -8,6 +8,8 @@ family_initialize_project(tinyusb_device_examples ${CMAKE_CURRENT_LIST_DIR})
|
|||||||
# family_add_subdirectory will filter what to actually add based on selected FAMILY
|
# family_add_subdirectory will filter what to actually add based on selected FAMILY
|
||||||
family_add_subdirectory(audio_4_channel_mic)
|
family_add_subdirectory(audio_4_channel_mic)
|
||||||
family_add_subdirectory(audio_test)
|
family_add_subdirectory(audio_test)
|
||||||
|
family_add_subdirectory(audio_4_channel_mic_freertos)
|
||||||
|
family_add_subdirectory(audio_test_freertos)
|
||||||
family_add_subdirectory(audio_test_multi_rate)
|
family_add_subdirectory(audio_test_multi_rate)
|
||||||
family_add_subdirectory(board_test)
|
family_add_subdirectory(board_test)
|
||||||
family_add_subdirectory(cdc_dual_ports)
|
family_add_subdirectory(cdc_dual_ports)
|
||||||
|
39
examples/device/audio_4_channel_mic_freertos/CMakeLists.txt
Normal file
39
examples/device/audio_4_channel_mic_freertos/CMakeLists.txt
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.17)
|
||||||
|
|
||||||
|
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
|
||||||
|
|
||||||
|
# gets PROJECT name for the example (e.g. <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/freertos_hook.c
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
|
||||||
|
)
|
||||||
|
|
||||||
|
# Example include
|
||||||
|
target_include_directories(${PROJECT} PUBLIC
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add libm for GCC
|
||||||
|
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||||
|
target_link_libraries(${PROJECT} PUBLIC m)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Configure compilation flags and libraries for the example with FreeRTOS.
|
||||||
|
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
|
||||||
|
family_configure_device_example(${PROJECT} freertos)
|
38
examples/device/audio_4_channel_mic_freertos/Makefile
Normal file
38
examples/device/audio_4_channel_mic_freertos/Makefile
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
include ../../build_system/make/make.mk
|
||||||
|
|
||||||
|
FREERTOS_SRC = lib/FreeRTOS-Kernel
|
||||||
|
FREERTOS_PORTABLE_PATH = $(FREERTOS_SRC)/portable/$(if $(findstring iar,$(TOOLCHAIN)),IAR,GCC)
|
||||||
|
|
||||||
|
INC += \
|
||||||
|
src \
|
||||||
|
src/FreeRTOSConfig \
|
||||||
|
$(TOP)/hw \
|
||||||
|
$(TOP)/$(FREERTOS_SRC)/include \
|
||||||
|
$(TOP)/$(FREERTOS_PORTABLE_SRC) \
|
||||||
|
|
||||||
|
# Example source
|
||||||
|
EXAMPLE_SOURCE = \
|
||||||
|
src/freertos_hook.c \
|
||||||
|
src/main.c \
|
||||||
|
src/usb_descriptors.c
|
||||||
|
|
||||||
|
SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE))
|
||||||
|
|
||||||
|
# FreeRTOS source, all files in port folder
|
||||||
|
SRC_C += \
|
||||||
|
$(FREERTOS_SRC)/list.c \
|
||||||
|
$(FREERTOS_SRC)/queue.c \
|
||||||
|
$(FREERTOS_SRC)/tasks.c \
|
||||||
|
$(FREERTOS_SRC)/timers.c \
|
||||||
|
$(subst $(TOP)/,,$(wildcard $(TOP)/$(FREERTOS_PORTABLE_SRC)/*.c))
|
||||||
|
|
||||||
|
SRC_S += \
|
||||||
|
$(subst $(TOP)/,,$(wildcard $(TOP)/$(FREERTOS_PORTABLE_SRC)/*.s))
|
||||||
|
|
||||||
|
# Suppress FreeRTOS warnings
|
||||||
|
CFLAGS += -Wno-error=cast-qual -Wno-error=redundant-decls
|
||||||
|
|
||||||
|
# FreeRTOS (lto + Os) linker issue
|
||||||
|
LDFLAGS += -Wl,--undefined=vTaskSwitchContext
|
||||||
|
|
||||||
|
include ../../build_system/make/rules.mk
|
19
examples/device/audio_4_channel_mic_freertos/README.md
Normal file
19
examples/device/audio_4_channel_mic_freertos/README.md
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# How to build example for Esp32s3
|
||||||
|
1. Load idf environment variables (eg. using the esp-idf alias `get_idf` if configured)
|
||||||
|
|
||||||
|
2. cd into examples directory
|
||||||
|
```
|
||||||
|
$ cd /tinyusb/examples/device/audio_4_channel_mic_freertos
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Run cmake in project directory specifying the board
|
||||||
|
```
|
||||||
|
$ cmake -DBOARD=espressif_s3_devkitc -B build -G Ninja .
|
||||||
|
$ ninja.exe -C build
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Flash the binary onto the esp32-s3 by copy-paste of the full command output by the esp-idf build system replacing **(PORT)** with eg. /dev/ttyUSB0
|
||||||
|
|
||||||
|
eg.
|
||||||
|
|
||||||
|
> /home/kaspernyhus/.espressif/python_env/idf4.4_py3.8_env/bin/python ../../../../esp-idf/components/esptool_py/esptool/esptool.py -p /dev/ttyUSB0 -b 460800 --before default_reset --after hard_reset --chip esp32s3 write_flash --flash_mode dio --flash_size detect --flash_freq 80m 0x0 _build/espressif_s3_devkitc/bootloader/bootloader.bin 0x8000 _build/espressif_s3_devkitc/partition_table/partition-table.bin 0x10000 _build/espressif_s3_devkitc/audio_4_channel_mic_freertos.bin
|
@ -0,0 +1,4 @@
|
|||||||
|
CONFIG_IDF_CMAKE=y
|
||||||
|
CONFIG_FREERTOS_HZ=1000
|
||||||
|
CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y
|
||||||
|
CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y
|
16
examples/device/audio_4_channel_mic_freertos/skip.txt
Normal file
16
examples/device/audio_4_channel_mic_freertos/skip.txt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
mcu:CH32V307
|
||||||
|
mcu:CXD56
|
||||||
|
mcu:F1C100S
|
||||||
|
mcu:GD32VF103
|
||||||
|
mcu:MKL25ZXX
|
||||||
|
mcu:MSP430x5xx
|
||||||
|
mcu:RP2040
|
||||||
|
mcu:SAMD11
|
||||||
|
mcu:SAMX7X
|
||||||
|
mcu:VALENTYUSB_EPTRI
|
||||||
|
mcu:RAXXX
|
||||||
|
mcu:STM32L0
|
||||||
|
board:lpcxpresso11u37
|
||||||
|
board:lpcxpresso1347
|
||||||
|
family:broadcom_32bit
|
||||||
|
family:broadcom_64bit
|
@ -0,0 +1,4 @@
|
|||||||
|
# This file is for ESP-IDF only
|
||||||
|
idf_component_register(SRCS "main.c" "usb_descriptors.c"
|
||||||
|
INCLUDE_DIRS "."
|
||||||
|
REQUIRES boards tinyusb_src)
|
@ -0,0 +1,190 @@
|
|||||||
|
/*
|
||||||
|
* FreeRTOS Kernel V10.0.0
|
||||||
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software. If you wish to use our Amazon
|
||||||
|
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* http://www.FreeRTOS.org
|
||||||
|
* http://aws.amazon.com/freertos
|
||||||
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef FREERTOS_CONFIG_H
|
||||||
|
#define FREERTOS_CONFIG_H
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Application specific definitions.
|
||||||
|
*
|
||||||
|
* These definitions should be adjusted for your particular hardware and
|
||||||
|
* application requirements.
|
||||||
|
*
|
||||||
|
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
|
||||||
|
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
|
||||||
|
*
|
||||||
|
* See http://www.freertos.org/a00110.html.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
// skip if included from IAR assembler
|
||||||
|
#ifndef __IASMARM__
|
||||||
|
|
||||||
|
// Include MCU header
|
||||||
|
#include "bsp/board_mcu.h"
|
||||||
|
|
||||||
|
#if CFG_TUSB_MCU == OPT_MCU_ESP32S2 || CFG_TUSB_MCU == OPT_MCU_ESP32S3
|
||||||
|
#error "ESP32-Sx should use IDF's FreeRTOSConfig.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// TODO fix later
|
||||||
|
#if CFG_TUSB_MCU == OPT_MCU_MM32F327X
|
||||||
|
extern u32 SystemCoreClock;
|
||||||
|
#else
|
||||||
|
// FIXME cause redundant-decls warnings
|
||||||
|
extern uint32_t SystemCoreClock;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Cortex M23/M33 port configuration. */
|
||||||
|
#define configENABLE_MPU 0
|
||||||
|
#define configENABLE_FPU 1
|
||||||
|
#define configENABLE_TRUSTZONE 0
|
||||||
|
#define configMINIMAL_SECURE_STACK_SIZE ( 1024 )
|
||||||
|
|
||||||
|
#define configUSE_PREEMPTION 1
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||||
|
#define configCPU_CLOCK_HZ SystemCoreClock
|
||||||
|
#define configTICK_RATE_HZ ( 1000 )
|
||||||
|
#define configMAX_PRIORITIES ( 5 )
|
||||||
|
#define configMINIMAL_STACK_SIZE ( 128 )
|
||||||
|
#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 )
|
||||||
|
#define configMAX_TASK_NAME_LEN 16
|
||||||
|
#define configUSE_16_BIT_TICKS 0
|
||||||
|
#define configIDLE_SHOULD_YIELD 1
|
||||||
|
#define configUSE_MUTEXES 1
|
||||||
|
#define configUSE_RECURSIVE_MUTEXES 1
|
||||||
|
#define configUSE_COUNTING_SEMAPHORES 1
|
||||||
|
#define configQUEUE_REGISTRY_SIZE 4
|
||||||
|
#define configUSE_QUEUE_SETS 0
|
||||||
|
#define configUSE_TIME_SLICING 0
|
||||||
|
#define configUSE_NEWLIB_REENTRANT 0
|
||||||
|
#define configENABLE_BACKWARD_COMPATIBILITY 1
|
||||||
|
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
|
||||||
|
|
||||||
|
#define configSUPPORT_STATIC_ALLOCATION 1
|
||||||
|
#define configSUPPORT_DYNAMIC_ALLOCATION 0
|
||||||
|
|
||||||
|
/* Hook function related definitions. */
|
||||||
|
#define configUSE_IDLE_HOOK 0
|
||||||
|
#define configUSE_TICK_HOOK 0
|
||||||
|
#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning
|
||||||
|
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||||
|
#define configCHECK_HANDLER_INSTALLATION 0
|
||||||
|
|
||||||
|
/* Run time and task stats gathering related definitions. */
|
||||||
|
#define configGENERATE_RUN_TIME_STATS 0
|
||||||
|
#define configUSE_TRACE_FACILITY 1 // legacy trace
|
||||||
|
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
|
||||||
|
|
||||||
|
/* Co-routine definitions. */
|
||||||
|
#define configUSE_CO_ROUTINES 0
|
||||||
|
#define configMAX_CO_ROUTINE_PRIORITIES 2
|
||||||
|
|
||||||
|
/* Software timer related definitions. */
|
||||||
|
#define configUSE_TIMERS 1
|
||||||
|
#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2)
|
||||||
|
#define configTIMER_QUEUE_LENGTH 32
|
||||||
|
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
|
||||||
|
|
||||||
|
/* Optional functions - most linkers will remove unused functions anyway. */
|
||||||
|
#define INCLUDE_vTaskPrioritySet 0
|
||||||
|
#define INCLUDE_uxTaskPriorityGet 0
|
||||||
|
#define INCLUDE_vTaskDelete 0
|
||||||
|
#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY
|
||||||
|
#define INCLUDE_xResumeFromISR 0
|
||||||
|
#define INCLUDE_vTaskDelayUntil 1
|
||||||
|
#define INCLUDE_vTaskDelay 1
|
||||||
|
#define INCLUDE_xTaskGetSchedulerState 0
|
||||||
|
#define INCLUDE_xTaskGetCurrentTaskHandle 0
|
||||||
|
#define INCLUDE_uxTaskGetStackHighWaterMark 0
|
||||||
|
#define INCLUDE_xTaskGetIdleTaskHandle 0
|
||||||
|
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
|
||||||
|
#define INCLUDE_pcTaskGetTaskName 0
|
||||||
|
#define INCLUDE_eTaskGetState 0
|
||||||
|
#define INCLUDE_xEventGroupSetBitFromISR 0
|
||||||
|
#define INCLUDE_xTimerPendFunctionCall 0
|
||||||
|
|
||||||
|
#ifdef __RX__
|
||||||
|
/* Renesas RX series */
|
||||||
|
#define vSoftwareInterruptISR INT_Excep_ICU_SWINT
|
||||||
|
#define vTickISR INT_Excep_CMT0_CMI0
|
||||||
|
#define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2)
|
||||||
|
#define configKERNEL_INTERRUPT_PRIORITY 1
|
||||||
|
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 4
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* FreeRTOS hooks to NVIC vectors */
|
||||||
|
#define xPortPendSVHandler PendSV_Handler
|
||||||
|
#define xPortSysTickHandler SysTick_Handler
|
||||||
|
#define vPortSVCHandler SVC_Handler
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Interrupt nesting behavior configuration.
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
#if defined(__NVIC_PRIO_BITS)
|
||||||
|
// For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h
|
||||||
|
#define configPRIO_BITS __NVIC_PRIO_BITS
|
||||||
|
|
||||||
|
#elif defined(__ECLIC_INTCTLBITS)
|
||||||
|
// RISC-V Bumblebee core from nuclei
|
||||||
|
#define configPRIO_BITS __ECLIC_INTCTLBITS
|
||||||
|
|
||||||
|
#elif defined(__IASMARM__)
|
||||||
|
// FIXME: IAR Assembler cannot include mcu header directly to get __NVIC_PRIO_BITS.
|
||||||
|
// Therefore we will hard coded it to minimum value of 2 to get pass ci build.
|
||||||
|
// IAR user must update this to correct value of the target MCU
|
||||||
|
#message "configPRIO_BITS is hard coded to 2 to pass IAR build only. User should update it per MCU"
|
||||||
|
#define configPRIO_BITS 2
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "FreeRTOS configPRIO_BITS to be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The lowest interrupt priority that can be used in a call to a "set priority" function. */
|
||||||
|
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<<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
|
||||||
|
|
||||||
|
#endif /* __FREERTOS_CONFIG__H */
|
115
examples/device/audio_4_channel_mic_freertos/src/freertos_hook.c
Normal file
115
examples/device/audio_4_channel_mic_freertos/src/freertos_hook.c
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// INCLUDE
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "common/tusb_common.h"
|
||||||
|
|
||||||
|
|
||||||
|
void vApplicationMallocFailedHook(void)
|
||||||
|
{
|
||||||
|
taskDISABLE_INTERRUPTS();
|
||||||
|
TU_ASSERT(false, );
|
||||||
|
}
|
||||||
|
|
||||||
|
void vApplicationStackOverflowHook(xTaskHandle pxTask, char *pcTaskName)
|
||||||
|
{
|
||||||
|
(void) pxTask;
|
||||||
|
(void) pcTaskName;
|
||||||
|
|
||||||
|
taskDISABLE_INTERRUPTS();
|
||||||
|
TU_ASSERT(false, );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* configSUPPORT_STATIC_ALLOCATION is set to 1, so the application must provide an
|
||||||
|
* implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
|
||||||
|
* used by the Idle task. */
|
||||||
|
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
|
||||||
|
{
|
||||||
|
/* If the buffers to be provided to the Idle task are declared inside this
|
||||||
|
* function then they must be declared static - otherwise they will be allocated on
|
||||||
|
* the stack and so not exists after this function exits. */
|
||||||
|
static StaticTask_t xIdleTaskTCB;
|
||||||
|
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
|
||||||
|
|
||||||
|
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's
|
||||||
|
state will be stored. */
|
||||||
|
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
|
||||||
|
|
||||||
|
/* Pass out the array that will be used as the Idle task's stack. */
|
||||||
|
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
|
||||||
|
|
||||||
|
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
|
||||||
|
Note that, as the array is necessarily of type StackType_t,
|
||||||
|
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
|
||||||
|
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* configSUPPORT_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
|
||||||
|
* application must provide an implementation of vApplicationGetTimerTaskMemory()
|
||||||
|
* to provide the memory that is used by the Timer service task. */
|
||||||
|
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize )
|
||||||
|
{
|
||||||
|
/* If the buffers to be provided to the Timer task are declared inside this
|
||||||
|
* function then they must be declared static - otherwise they will be allocated on
|
||||||
|
* the stack and so not exists after this function exits. */
|
||||||
|
static StaticTask_t xTimerTaskTCB;
|
||||||
|
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
|
||||||
|
|
||||||
|
/* Pass out a pointer to the StaticTask_t structure in which the Timer
|
||||||
|
task's state will be stored. */
|
||||||
|
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
|
||||||
|
|
||||||
|
/* Pass out the array that will be used as the Timer task's stack. */
|
||||||
|
*ppxTimerTaskStackBuffer = uxTimerTaskStack;
|
||||||
|
|
||||||
|
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
|
||||||
|
Note that, as the array is necessarily of type StackType_t,
|
||||||
|
configTIMER_TASK_STACK_DEPTH is specified in words, not bytes. */
|
||||||
|
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CFG_TUSB_MCU == OPT_MCU_RX63X | CFG_TUSB_MCU == OPT_MCU_RX65X
|
||||||
|
#include "iodefine.h"
|
||||||
|
void vApplicationSetupTimerInterrupt(void)
|
||||||
|
{
|
||||||
|
/* Enable CMT0 */
|
||||||
|
unsigned short oldPRCR = SYSTEM.PRCR.WORD;
|
||||||
|
SYSTEM.PRCR.WORD = (0xA5u<<8) | TU_BIT(1);
|
||||||
|
MSTP(CMT0) = 0;
|
||||||
|
SYSTEM.PRCR.WORD = (0xA5u<<8) | oldPRCR;
|
||||||
|
|
||||||
|
CMT0.CMCNT = 0;
|
||||||
|
CMT0.CMCOR = (unsigned short)(((configPERIPHERAL_CLOCK_HZ/configTICK_RATE_HZ)-1)/128);
|
||||||
|
CMT0.CMCR.WORD = TU_BIT(6) | 2;
|
||||||
|
IR(CMT0, CMI0) = 0;
|
||||||
|
IPR(CMT0, CMI0) = configKERNEL_INTERRUPT_PRIORITY;
|
||||||
|
IEN(CMT0, CMI0) = 1;
|
||||||
|
CMT.CMSTR0.BIT.STR0 = 1;
|
||||||
|
}
|
||||||
|
#endif
|
580
examples/device/audio_4_channel_mic_freertos/src/main.c
Normal file
580
examples/device/audio_4_channel_mic_freertos/src/main.c
Normal file
@ -0,0 +1,580 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Reinhard Panhuber
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* plot_audio_samples.py requires following modules:
|
||||||
|
* $ sudo apt install libportaudio
|
||||||
|
* $ pip3 install sounddevice matplotlib
|
||||||
|
*
|
||||||
|
* Then run
|
||||||
|
* $ python3 plot_audio_samples.py
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "bsp/board_api.h"
|
||||||
|
#include "tusb.h"
|
||||||
|
|
||||||
|
#if TUP_MCU_ESPRESSIF
|
||||||
|
// ESP-IDF need "freertos/" prefix in include path.
|
||||||
|
// CFG_TUSB_OS_INC_PATH should be defined accordingly.
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/semphr.h"
|
||||||
|
#include "freertos/queue.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "freertos/timers.h"
|
||||||
|
|
||||||
|
#define USBD_STACK_SIZE 4096
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
#include "queue.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "timers.h"
|
||||||
|
|
||||||
|
// Increase stack size when debug log is enabled
|
||||||
|
#define USBD_STACK_SIZE (4*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE
|
||||||
|
#define AUDIO_STACK_SIZE configMINIMAL_STACK_SIZE
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// MACRO CONSTANT TYPEDEF PROTYPES
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
#define AUDIO_SAMPLE_RATE CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE
|
||||||
|
|
||||||
|
/* Blink pattern
|
||||||
|
* - 250 ms : device not mounted
|
||||||
|
* - 1000 ms : device mounted
|
||||||
|
* - 2500 ms : device is suspended
|
||||||
|
*/
|
||||||
|
enum {
|
||||||
|
BLINK_NOT_MOUNTED = 250,
|
||||||
|
BLINK_MOUNTED = 1000,
|
||||||
|
BLINK_SUSPENDED = 2500,
|
||||||
|
};
|
||||||
|
|
||||||
|
// static task
|
||||||
|
#if configSUPPORT_STATIC_ALLOCATION
|
||||||
|
StackType_t blinky_stack[BLINKY_STACK_SIZE];
|
||||||
|
StaticTask_t blinky_taskdef;
|
||||||
|
|
||||||
|
StackType_t usb_device_stack[USBD_STACK_SIZE];
|
||||||
|
StaticTask_t usb_device_taskdef;
|
||||||
|
|
||||||
|
StackType_t audio_stack[AUDIO_STACK_SIZE];
|
||||||
|
StaticTask_t audio_taskdef;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
|
||||||
|
|
||||||
|
// Audio controls
|
||||||
|
// Current states
|
||||||
|
bool mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0
|
||||||
|
uint16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0
|
||||||
|
uint32_t sampFreq;
|
||||||
|
uint8_t clkValid;
|
||||||
|
|
||||||
|
// Range states
|
||||||
|
audio_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX+1]; // Volume range state
|
||||||
|
audio_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state
|
||||||
|
|
||||||
|
#if CFG_TUD_AUDIO_ENABLE_ENCODING
|
||||||
|
// Audio test data, each buffer contains 2 channels, buffer[0] for CH0-1, buffer[1] for CH1-2
|
||||||
|
uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX*CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE/1000/CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO];
|
||||||
|
#else
|
||||||
|
// Audio test data, 4 channels muxed together, buffer[0] for CH0, buffer[1] for CH1, buffer[2] for CH2, buffer[3] for CH3
|
||||||
|
uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX*CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE/1000];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void led_blinking_task(void* param);
|
||||||
|
void usb_device_task(void* param);
|
||||||
|
void audio_task(void* param);
|
||||||
|
|
||||||
|
/*------------- MAIN -------------*/
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
board_init();
|
||||||
|
|
||||||
|
// Init values
|
||||||
|
sampFreq = AUDIO_SAMPLE_RATE;
|
||||||
|
clkValid = 1;
|
||||||
|
|
||||||
|
sampleFreqRng.wNumSubRanges = 1;
|
||||||
|
sampleFreqRng.subrange[0].bMin = AUDIO_SAMPLE_RATE;
|
||||||
|
sampleFreqRng.subrange[0].bMax = AUDIO_SAMPLE_RATE;
|
||||||
|
sampleFreqRng.subrange[0].bRes = 0;
|
||||||
|
|
||||||
|
// Generate dummy data
|
||||||
|
#if CFG_TUD_AUDIO_ENABLE_ENCODING
|
||||||
|
uint16_t * p_buff = i2s_dummy_buffer[0];
|
||||||
|
uint16_t dataVal = 0;
|
||||||
|
for (uint16_t cnt = 0; cnt < AUDIO_SAMPLE_RATE/1000; cnt++)
|
||||||
|
{
|
||||||
|
// CH0 saw wave
|
||||||
|
*p_buff++ = dataVal;
|
||||||
|
// CH1 inverted saw wave
|
||||||
|
*p_buff++ = 3200 + AUDIO_SAMPLE_RATE/1000 - dataVal;
|
||||||
|
dataVal+= 32;
|
||||||
|
}
|
||||||
|
p_buff = i2s_dummy_buffer[1];
|
||||||
|
for (uint16_t cnt = 0; cnt < AUDIO_SAMPLE_RATE/1000; cnt++)
|
||||||
|
{
|
||||||
|
// CH3 square wave
|
||||||
|
*p_buff++ = cnt < (AUDIO_SAMPLE_RATE/1000/2) ? 3400:5000;
|
||||||
|
// CH4 sinus wave
|
||||||
|
float t = 2*3.1415f * cnt / (AUDIO_SAMPLE_RATE/1000);
|
||||||
|
*p_buff++ = (uint16_t)((int16_t)(sinf(t) * 750) + 6000);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
uint16_t * p_buff = i2s_dummy_buffer;
|
||||||
|
uint16_t dataVal = 0;
|
||||||
|
for (uint16_t cnt = 0; cnt < AUDIO_SAMPLE_RATE/1000; cnt++)
|
||||||
|
{
|
||||||
|
// CH0 saw wave
|
||||||
|
*p_buff++ = dataVal;
|
||||||
|
// CH1 inverted saw wave
|
||||||
|
*p_buff++ = 3200 + AUDIO_SAMPLE_RATE/1000 - dataVal;
|
||||||
|
dataVal+= 32;
|
||||||
|
// CH3 square wave
|
||||||
|
*p_buff++ = cnt < (AUDIO_SAMPLE_RATE/1000/2) ? 3400:5000;
|
||||||
|
// CH4 sinus wave
|
||||||
|
float t = 2*3.1415f * cnt / (AUDIO_SAMPLE_RATE/1000);
|
||||||
|
*p_buff++ = (uint16_t)((int16_t)(sinf(t) * 750) + 6000);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if configSUPPORT_STATIC_ALLOCATION
|
||||||
|
// blinky task
|
||||||
|
xTaskCreateStatic(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, blinky_stack, &blinky_taskdef);
|
||||||
|
|
||||||
|
// Create a task for tinyusb device stack
|
||||||
|
xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef);
|
||||||
|
|
||||||
|
// Create a task for audio
|
||||||
|
xTaskCreateStatic(audio_task, "audio", AUDIO_STACK_SIZE, NULL, configMAX_PRIORITIES-1, audio_stack, &audio_taskdef);
|
||||||
|
#else
|
||||||
|
xTaskCreate(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, NULL);
|
||||||
|
xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL);
|
||||||
|
xTaskCreate(audio_task, "audio", AUDIO_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// skip starting scheduler (and return) for ESP32-S2 or ESP32-S3
|
||||||
|
#if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
|
||||||
|
vTaskStartScheduler();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
|
||||||
|
void app_main(void)
|
||||||
|
{
|
||||||
|
main();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// USB Device Driver task
|
||||||
|
// This top level thread process all usb events and invoke callbacks
|
||||||
|
void usb_device_task(void* param)
|
||||||
|
{
|
||||||
|
(void) param;
|
||||||
|
|
||||||
|
// init device stack on configured roothub port
|
||||||
|
// This should be called after scheduler/kernel is started.
|
||||||
|
// Otherwise it could cause kernel issue since USB IRQ handler does use RTOS queue API.
|
||||||
|
tud_init(BOARD_TUD_RHPORT);
|
||||||
|
|
||||||
|
if (board_init_after_tusb) {
|
||||||
|
board_init_after_tusb();
|
||||||
|
}
|
||||||
|
|
||||||
|
// RTOS forever loop
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
// tinyusb device task
|
||||||
|
tud_task();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Device callbacks
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// Invoked when device is mounted
|
||||||
|
void tud_mount_cb(void)
|
||||||
|
{
|
||||||
|
blink_interval_ms = BLINK_MOUNTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when device is unmounted
|
||||||
|
void tud_umount_cb(void)
|
||||||
|
{
|
||||||
|
blink_interval_ms = BLINK_NOT_MOUNTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when usb bus is suspended
|
||||||
|
// remote_wakeup_en : if host allow us to perform remote wakeup
|
||||||
|
// Within 7ms, device must draw an average of current less than 2.5 mA from bus
|
||||||
|
void tud_suspend_cb(bool remote_wakeup_en)
|
||||||
|
{
|
||||||
|
(void) remote_wakeup_en;
|
||||||
|
blink_interval_ms = BLINK_SUSPENDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when usb bus is resumed
|
||||||
|
void tud_resume_cb(void)
|
||||||
|
{
|
||||||
|
blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// AUDIO Task
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
void audio_task(void* param)
|
||||||
|
{
|
||||||
|
(void) param;
|
||||||
|
// Yet to be filled - e.g. read audio from I2S buffer.
|
||||||
|
// Here we simulate a I2S receive callback every 1ms.
|
||||||
|
while (1) {
|
||||||
|
vTaskDelay(1);
|
||||||
|
#if CFG_TUD_AUDIO_ENABLE_ENCODING
|
||||||
|
// Write I2S buffer into FIFO
|
||||||
|
for (uint8_t cnt=0; cnt < 2; cnt++)
|
||||||
|
{
|
||||||
|
tud_audio_write_support_ff(cnt, i2s_dummy_buffer[cnt], AUDIO_SAMPLE_RATE/1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
tud_audio_write(i2s_dummy_buffer, AUDIO_SAMPLE_RATE/1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Application Callback API Implementations
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// Invoked when audio class specific set request received for an EP
|
||||||
|
bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff)
|
||||||
|
{
|
||||||
|
(void) rhport;
|
||||||
|
(void) pBuff;
|
||||||
|
|
||||||
|
// We do not support any set range requests here, only current value requests
|
||||||
|
TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR);
|
||||||
|
|
||||||
|
// Page 91 in UAC2 specification
|
||||||
|
uint8_t channelNum = TU_U16_LOW(p_request->wValue);
|
||||||
|
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
|
||||||
|
uint8_t ep = TU_U16_LOW(p_request->wIndex);
|
||||||
|
|
||||||
|
(void) channelNum; (void) ctrlSel; (void) ep;
|
||||||
|
|
||||||
|
return false; // Yet not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when audio class specific set request received for an interface
|
||||||
|
bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff)
|
||||||
|
{
|
||||||
|
(void) rhport;
|
||||||
|
(void) pBuff;
|
||||||
|
|
||||||
|
// We do not support any set range requests here, only current value requests
|
||||||
|
TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR);
|
||||||
|
|
||||||
|
// Page 91 in UAC2 specification
|
||||||
|
uint8_t channelNum = TU_U16_LOW(p_request->wValue);
|
||||||
|
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
|
||||||
|
uint8_t itf = TU_U16_LOW(p_request->wIndex);
|
||||||
|
|
||||||
|
(void) channelNum; (void) ctrlSel; (void) itf;
|
||||||
|
|
||||||
|
return false; // Yet not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when audio class specific set request received for an entity
|
||||||
|
bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff)
|
||||||
|
{
|
||||||
|
(void) rhport;
|
||||||
|
|
||||||
|
// Page 91 in UAC2 specification
|
||||||
|
uint8_t channelNum = TU_U16_LOW(p_request->wValue);
|
||||||
|
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
|
||||||
|
uint8_t itf = TU_U16_LOW(p_request->wIndex);
|
||||||
|
uint8_t entityID = TU_U16_HIGH(p_request->wIndex);
|
||||||
|
|
||||||
|
(void) itf;
|
||||||
|
|
||||||
|
// We do not support any set range requests here, only current value requests
|
||||||
|
TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR);
|
||||||
|
|
||||||
|
// If request is for our feature unit
|
||||||
|
if ( entityID == 2 )
|
||||||
|
{
|
||||||
|
switch ( ctrlSel )
|
||||||
|
{
|
||||||
|
case AUDIO_FU_CTRL_MUTE:
|
||||||
|
// Request uses format layout 1
|
||||||
|
TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_1_t));
|
||||||
|
|
||||||
|
mute[channelNum] = ((audio_control_cur_1_t*) pBuff)->bCur;
|
||||||
|
|
||||||
|
TU_LOG2(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case AUDIO_FU_CTRL_VOLUME:
|
||||||
|
// Request uses format layout 2
|
||||||
|
TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_2_t));
|
||||||
|
|
||||||
|
volume[channelNum] = ((audio_control_cur_2_t*) pBuff)->bCur;
|
||||||
|
|
||||||
|
TU_LOG2(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Unknown/Unsupported control
|
||||||
|
default:
|
||||||
|
TU_BREAKPOINT();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false; // Yet not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when audio class specific get request received for an EP
|
||||||
|
bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request)
|
||||||
|
{
|
||||||
|
(void) rhport;
|
||||||
|
|
||||||
|
// Page 91 in UAC2 specification
|
||||||
|
uint8_t channelNum = TU_U16_LOW(p_request->wValue);
|
||||||
|
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
|
||||||
|
uint8_t ep = TU_U16_LOW(p_request->wIndex);
|
||||||
|
|
||||||
|
(void) channelNum; (void) ctrlSel; (void) ep;
|
||||||
|
|
||||||
|
return false; // Yet not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when audio class specific get request received for an interface
|
||||||
|
bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request)
|
||||||
|
{
|
||||||
|
(void) rhport;
|
||||||
|
|
||||||
|
// Page 91 in UAC2 specification
|
||||||
|
uint8_t channelNum = TU_U16_LOW(p_request->wValue);
|
||||||
|
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
|
||||||
|
uint8_t itf = TU_U16_LOW(p_request->wIndex);
|
||||||
|
|
||||||
|
(void) channelNum; (void) ctrlSel; (void) itf;
|
||||||
|
|
||||||
|
return false; // Yet not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when audio class specific get request received for an entity
|
||||||
|
bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request)
|
||||||
|
{
|
||||||
|
(void) rhport;
|
||||||
|
|
||||||
|
// Page 91 in UAC2 specification
|
||||||
|
uint8_t channelNum = TU_U16_LOW(p_request->wValue);
|
||||||
|
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
|
||||||
|
// uint8_t itf = TU_U16_LOW(p_request->wIndex); // Since we have only one audio function implemented, we do not need the itf value
|
||||||
|
uint8_t entityID = TU_U16_HIGH(p_request->wIndex);
|
||||||
|
|
||||||
|
// Input terminal (Microphone input)
|
||||||
|
if (entityID == 1)
|
||||||
|
{
|
||||||
|
switch ( ctrlSel )
|
||||||
|
{
|
||||||
|
case AUDIO_TE_CTRL_CONNECTOR:
|
||||||
|
{
|
||||||
|
// The terminal connector control only has a get request with only the CUR attribute.
|
||||||
|
audio_desc_channel_cluster_t ret;
|
||||||
|
|
||||||
|
// Those are dummy values for now
|
||||||
|
ret.bNrChannels = 1;
|
||||||
|
ret.bmChannelConfig = 0;
|
||||||
|
ret.iChannelNames = 0;
|
||||||
|
|
||||||
|
TU_LOG2(" Get terminal connector\r\n");
|
||||||
|
|
||||||
|
return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void*) &ret, sizeof(ret));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Unknown/Unsupported control selector
|
||||||
|
default:
|
||||||
|
TU_BREAKPOINT();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Feature unit
|
||||||
|
if (entityID == 2)
|
||||||
|
{
|
||||||
|
switch ( ctrlSel )
|
||||||
|
{
|
||||||
|
case AUDIO_FU_CTRL_MUTE:
|
||||||
|
// Audio control mute cur parameter block consists of only one byte - we thus can send it right away
|
||||||
|
// There does not exist a range parameter block for mute
|
||||||
|
TU_LOG2(" Get Mute of channel: %u\r\n", channelNum);
|
||||||
|
return tud_control_xfer(rhport, p_request, &mute[channelNum], 1);
|
||||||
|
|
||||||
|
case AUDIO_FU_CTRL_VOLUME:
|
||||||
|
switch ( p_request->bRequest )
|
||||||
|
{
|
||||||
|
case AUDIO_CS_REQ_CUR:
|
||||||
|
TU_LOG2(" Get Volume of channel: %u\r\n", channelNum);
|
||||||
|
return tud_control_xfer(rhport, p_request, &volume[channelNum], sizeof(volume[channelNum]));
|
||||||
|
|
||||||
|
case AUDIO_CS_REQ_RANGE:
|
||||||
|
TU_LOG2(" Get Volume range of channel: %u\r\n", channelNum);
|
||||||
|
|
||||||
|
// Copy values - only for testing - better is version below
|
||||||
|
audio_control_range_2_n_t(1)
|
||||||
|
ret;
|
||||||
|
|
||||||
|
ret.wNumSubRanges = 1;
|
||||||
|
ret.subrange[0].bMin = -90; // -90 dB
|
||||||
|
ret.subrange[0].bMax = 90; // +90 dB
|
||||||
|
ret.subrange[0].bRes = 1; // 1 dB steps
|
||||||
|
|
||||||
|
return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void*) &ret, sizeof(ret));
|
||||||
|
|
||||||
|
// Unknown/Unsupported control
|
||||||
|
default:
|
||||||
|
TU_BREAKPOINT();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Unknown/Unsupported control
|
||||||
|
default:
|
||||||
|
TU_BREAKPOINT();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clock Source unit
|
||||||
|
if ( entityID == 4 )
|
||||||
|
{
|
||||||
|
switch ( ctrlSel )
|
||||||
|
{
|
||||||
|
case AUDIO_CS_CTRL_SAM_FREQ:
|
||||||
|
// channelNum is always zero in this case
|
||||||
|
switch ( p_request->bRequest )
|
||||||
|
{
|
||||||
|
case AUDIO_CS_REQ_CUR:
|
||||||
|
TU_LOG2(" Get Sample Freq.\r\n");
|
||||||
|
// Buffered control transfer is needed for IN flow control to work
|
||||||
|
return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &sampFreq, sizeof(sampFreq));
|
||||||
|
|
||||||
|
case AUDIO_CS_REQ_RANGE:
|
||||||
|
TU_LOG2(" Get Sample Freq. range\r\n");
|
||||||
|
return tud_control_xfer(rhport, p_request, &sampleFreqRng, sizeof(sampleFreqRng));
|
||||||
|
|
||||||
|
// Unknown/Unsupported control
|
||||||
|
default:
|
||||||
|
TU_BREAKPOINT();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AUDIO_CS_CTRL_CLK_VALID:
|
||||||
|
// Only cur attribute exists for this request
|
||||||
|
TU_LOG2(" Get Sample Freq. valid\r\n");
|
||||||
|
return tud_control_xfer(rhport, p_request, &clkValid, sizeof(clkValid));
|
||||||
|
|
||||||
|
// Unknown/Unsupported control
|
||||||
|
default:
|
||||||
|
TU_BREAKPOINT();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TU_LOG2(" Unsupported entity: %d\r\n", entityID);
|
||||||
|
return false; // Yet not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tud_audio_tx_done_pre_load_cb(uint8_t rhport, uint8_t itf, uint8_t ep_in, uint8_t cur_alt_setting)
|
||||||
|
{
|
||||||
|
(void) rhport;
|
||||||
|
(void) itf;
|
||||||
|
(void) ep_in;
|
||||||
|
(void) cur_alt_setting;
|
||||||
|
|
||||||
|
|
||||||
|
// In read world application data flow is driven by I2S clock,
|
||||||
|
// both tud_audio_tx_done_pre_load_cb() & tud_audio_tx_done_post_load_cb() are hardly used.
|
||||||
|
// For example in your I2S receive callback:
|
||||||
|
// void I2S_Rx_Callback(int channel, const void* data, uint16_t samples)
|
||||||
|
// {
|
||||||
|
// tud_audio_write_support_ff(channel, data, samples * N_BYTES_PER_SAMPLE * N_CHANNEL_PER_FIFO);
|
||||||
|
// }
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tud_audio_tx_done_post_load_cb(uint8_t rhport, uint16_t n_bytes_copied, uint8_t itf, uint8_t ep_in, uint8_t cur_alt_setting)
|
||||||
|
{
|
||||||
|
(void) rhport;
|
||||||
|
(void) n_bytes_copied;
|
||||||
|
(void) itf;
|
||||||
|
(void) ep_in;
|
||||||
|
(void) cur_alt_setting;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const * p_request)
|
||||||
|
{
|
||||||
|
(void) rhport;
|
||||||
|
(void) p_request;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
///--------------------------------------------------------------------+
|
||||||
|
// BLINKING TASK
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
void led_blinking_task(void* param) {
|
||||||
|
(void) param;
|
||||||
|
static uint32_t start_ms = 0;
|
||||||
|
static bool led_state = false;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
// Blink every interval ms
|
||||||
|
vTaskDelay(blink_interval_ms / portTICK_PERIOD_MS);
|
||||||
|
start_ms += blink_interval_ms;
|
||||||
|
|
||||||
|
board_led_write(led_state);
|
||||||
|
led_state = 1 - led_state; // toggle
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
import sounddevice as sd
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import numpy as np
|
||||||
|
import platform
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
# If you got "ValueError: No input device matching", that is because your PC name example device
|
||||||
|
# differently from tested list below. Uncomment the next line to see full list and try to pick correct one
|
||||||
|
# print(sd.query_devices())
|
||||||
|
|
||||||
|
fs = 48000 # Sample rate
|
||||||
|
duration = 100e-3 # Duration of recording
|
||||||
|
|
||||||
|
if platform.system() == 'Windows':
|
||||||
|
# WDM-KS is needed since there are more than one MicNode device APIs (at least in Windows)
|
||||||
|
device = 'Microphone (MicNode_4_Ch), Windows WDM-KS'
|
||||||
|
elif platform.system() == 'Darwin':
|
||||||
|
device = 'MicNode_4_Ch'
|
||||||
|
else:
|
||||||
|
device ='default'
|
||||||
|
|
||||||
|
myrecording = sd.rec(int(duration * fs), samplerate=fs, channels=4, dtype='int16', device=device)
|
||||||
|
print('Waiting...')
|
||||||
|
sd.wait() # Wait until recording is finished
|
||||||
|
print('Done!')
|
||||||
|
|
||||||
|
time = np.arange(0, duration, 1 / fs) # time vector
|
||||||
|
plt.plot(time, myrecording)
|
||||||
|
plt.xlabel('Time [s]')
|
||||||
|
plt.ylabel('Amplitude')
|
||||||
|
plt.title('MicNode 4 Channel')
|
||||||
|
plt.show()
|
148
examples/device/audio_4_channel_mic_freertos/src/tusb_config.h
Normal file
148
examples/device/audio_4_channel_mic_freertos/src/tusb_config.h
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _TUSB_CONFIG_H_
|
||||||
|
#define _TUSB_CONFIG_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Board Specific Configuration
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// RHPort number used for device can be defined by board.mk, default to port 0
|
||||||
|
#ifndef BOARD_TUD_RHPORT
|
||||||
|
#define BOARD_TUD_RHPORT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// RHPort max operational speed can defined by board.mk
|
||||||
|
#ifndef BOARD_TUD_MAX_SPEED
|
||||||
|
#define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// COMMON CONFIGURATION
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
|
// defined by compiler flags for flexibility
|
||||||
|
#ifndef CFG_TUSB_MCU
|
||||||
|
#error CFG_TUSB_MCU must be defined
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// This examples use FreeRTOS
|
||||||
|
#ifndef CFG_TUSB_OS
|
||||||
|
#define CFG_TUSB_OS OPT_OS_FREERTOS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Espressif IDF requires "freertos/" prefix in include path
|
||||||
|
#if TUP_MCU_ESPRESSIF
|
||||||
|
#define CFG_TUSB_OS_INC_PATH freertos/
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CFG_TUSB_DEBUG
|
||||||
|
#define CFG_TUSB_DEBUG 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Enable Device stack
|
||||||
|
#define CFG_TUD_ENABLED 1
|
||||||
|
|
||||||
|
// Default is max speed that hardware controller could support with on-chip PHY
|
||||||
|
#define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED
|
||||||
|
|
||||||
|
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
|
||||||
|
* Tinyusb use follows macros to declare transferring memory so that they can be put
|
||||||
|
* into those specific section.
|
||||||
|
* e.g
|
||||||
|
* - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") ))
|
||||||
|
* - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4)))
|
||||||
|
*/
|
||||||
|
#ifndef CFG_TUSB_MEM_SECTION
|
||||||
|
#define CFG_TUSB_MEM_SECTION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CFG_TUSB_MEM_ALIGN
|
||||||
|
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// DEVICE CONFIGURATION
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef CFG_TUD_ENDPOINT0_SIZE
|
||||||
|
#define CFG_TUD_ENDPOINT0_SIZE 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------- CLASS -------------//
|
||||||
|
#define CFG_TUD_AUDIO 1
|
||||||
|
#define CFG_TUD_CDC 0
|
||||||
|
#define CFG_TUD_MSC 0
|
||||||
|
#define CFG_TUD_HID 0
|
||||||
|
#define CFG_TUD_MIDI 0
|
||||||
|
#define CFG_TUD_VENDOR 0
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// AUDIO CLASS DRIVER CONFIGURATION
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Have a look into audio_device.h for all configurations
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE 48000
|
||||||
|
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_MIC_FOUR_CH_DESC_LEN
|
||||||
|
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 1
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64
|
||||||
|
|
||||||
|
#define CFG_TUD_AUDIO_ENABLE_EP_IN 1
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 4 // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup
|
||||||
|
#define CFG_TUD_AUDIO_EP_SZ_IN TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX)
|
||||||
|
|
||||||
|
#define CFG_TUD_AUDIO_ENABLE_ENCODING 1
|
||||||
|
#define CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL 1
|
||||||
|
|
||||||
|
#if CFG_TUD_AUDIO_ENABLE_ENCODING
|
||||||
|
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ CFG_TUD_AUDIO_EP_SZ_IN
|
||||||
|
|
||||||
|
#define CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING 1
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX 2 // One I2S stream contains two channels, each stream is saved within one support FIFO - this value is currently fixed, the driver does not support a changing value
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO (CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX / CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX)
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * (CFG_TUD_AUDIO_EP_SZ_IN / CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO) // Example write FIFO every 1ms, so it should be 8 times larger for HS device
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_EP_SZ_IN // Example write FIFO every 1ms, so it should be 8 times larger for HS device
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _TUSB_CONFIG_H_ */
|
@ -0,0 +1,179 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "bsp/board_api.h"
|
||||||
|
#include "tusb.h"
|
||||||
|
|
||||||
|
/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug.
|
||||||
|
* Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC.
|
||||||
|
*
|
||||||
|
* Auto ProductID layout's Bitmap:
|
||||||
|
* [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB]
|
||||||
|
*/
|
||||||
|
#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) )
|
||||||
|
#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \
|
||||||
|
_PID_MAP(MIDI, 3) | _PID_MAP(AUDIO, 4) | _PID_MAP(VENDOR, 5) )
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Device Descriptors
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
tusb_desc_device_t const desc_device =
|
||||||
|
{
|
||||||
|
.bLength = sizeof(tusb_desc_device_t),
|
||||||
|
.bDescriptorType = TUSB_DESC_DEVICE,
|
||||||
|
.bcdUSB = 0x0200,
|
||||||
|
|
||||||
|
// Use Interface Association Descriptor (IAD) for Audio
|
||||||
|
// As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1)
|
||||||
|
.bDeviceClass = TUSB_CLASS_MISC,
|
||||||
|
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
|
||||||
|
.bDeviceProtocol = MISC_PROTOCOL_IAD,
|
||||||
|
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
|
||||||
|
|
||||||
|
.idVendor = 0xCafe,
|
||||||
|
.idProduct = USB_PID,
|
||||||
|
.bcdDevice = 0x0100,
|
||||||
|
|
||||||
|
.iManufacturer = 0x01,
|
||||||
|
.iProduct = 0x02,
|
||||||
|
.iSerialNumber = 0x03,
|
||||||
|
|
||||||
|
.bNumConfigurations = 0x01
|
||||||
|
};
|
||||||
|
|
||||||
|
// Invoked when received GET DEVICE DESCRIPTOR
|
||||||
|
// Application return pointer to descriptor
|
||||||
|
uint8_t const * tud_descriptor_device_cb(void)
|
||||||
|
{
|
||||||
|
return (uint8_t const *) &desc_device;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Configuration Descriptor
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
ITF_NUM_AUDIO_CONTROL = 0,
|
||||||
|
ITF_NUM_AUDIO_STREAMING,
|
||||||
|
ITF_NUM_TOTAL
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_AUDIO * TUD_AUDIO_MIC_FOUR_CH_DESC_LEN)
|
||||||
|
|
||||||
|
#if TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX)
|
||||||
|
// LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number
|
||||||
|
// 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ...
|
||||||
|
#define EPNUM_AUDIO 0x03
|
||||||
|
|
||||||
|
#elif TU_CHECK_MCU(OPT_MCU_NRF5X)
|
||||||
|
// nRF5x ISO can only be endpoint 8
|
||||||
|
#define EPNUM_AUDIO 0x08
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define EPNUM_AUDIO 0x01
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint8_t const desc_configuration[] =
|
||||||
|
{
|
||||||
|
// Config number, interface count, string index, total length, attribute, power in mA
|
||||||
|
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
|
||||||
|
|
||||||
|
// Interface number, string index, EP Out & EP In address, EP size
|
||||||
|
TUD_AUDIO_MIC_FOUR_CH_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_nBytesPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, /*_nBitsUsedPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX*8, /*_epin*/ 0x80 | EPNUM_AUDIO, /*_epsize*/ CFG_TUD_AUDIO_EP_SZ_IN)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Invoked when received GET CONFIGURATION DESCRIPTOR
|
||||||
|
// Application return pointer to descriptor
|
||||||
|
// Descriptor contents must exist long enough for transfer to complete
|
||||||
|
uint8_t const * tud_descriptor_configuration_cb(uint8_t index)
|
||||||
|
{
|
||||||
|
(void) index; // for multiple configurations
|
||||||
|
return desc_configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// String Descriptors
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// String Descriptor Index
|
||||||
|
enum {
|
||||||
|
STRID_LANGID = 0,
|
||||||
|
STRID_MANUFACTURER,
|
||||||
|
STRID_PRODUCT,
|
||||||
|
STRID_SERIAL,
|
||||||
|
};
|
||||||
|
|
||||||
|
// array of pointer to string descriptors
|
||||||
|
char const* string_desc_arr [] = {
|
||||||
|
(const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409)
|
||||||
|
"PaniRCorp", // 1: Manufacturer
|
||||||
|
"MicNode_4_Ch", // 2: Product
|
||||||
|
NULL, // 3: Serials will use unique ID if possible
|
||||||
|
"UAC2", // 4: Audio Interface
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint16_t _desc_str[32 + 1];
|
||||||
|
|
||||||
|
// Invoked when received GET STRING DESCRIPTOR request
|
||||||
|
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
|
||||||
|
uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
|
||||||
|
(void) langid;
|
||||||
|
size_t chr_count;
|
||||||
|
|
||||||
|
switch ( index ) {
|
||||||
|
case STRID_LANGID:
|
||||||
|
memcpy(&_desc_str[1], string_desc_arr[0], 2);
|
||||||
|
chr_count = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STRID_SERIAL:
|
||||||
|
chr_count = board_usb_get_serial(_desc_str + 1, 32);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors.
|
||||||
|
// https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors
|
||||||
|
|
||||||
|
if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL;
|
||||||
|
|
||||||
|
const char *str = string_desc_arr[index];
|
||||||
|
|
||||||
|
// Cap at max char
|
||||||
|
chr_count = strlen(str);
|
||||||
|
size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type
|
||||||
|
if ( chr_count > max_count ) chr_count = max_count;
|
||||||
|
|
||||||
|
// Convert ASCII string into UTF-16
|
||||||
|
for ( size_t i = 0; i < chr_count; i++ ) {
|
||||||
|
_desc_str[1 + i] = str[i];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// first byte is length (including header), second byte is string type
|
||||||
|
_desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2));
|
||||||
|
|
||||||
|
return _desc_str;
|
||||||
|
}
|
@ -42,10 +42,6 @@
|
|||||||
// MACRO CONSTANT TYPEDEF PROTYPES
|
// MACRO CONSTANT TYPEDEF PROTYPES
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
#ifndef AUDIO_SAMPLE_RATE
|
|
||||||
#define AUDIO_SAMPLE_RATE 48000
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Blink pattern
|
/* Blink pattern
|
||||||
* - 250 ms : device not mounted
|
* - 250 ms : device not mounted
|
||||||
* - 1000 ms : device mounted
|
* - 1000 ms : device mounted
|
||||||
@ -90,12 +86,12 @@ int main(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Init values
|
// Init values
|
||||||
sampFreq = AUDIO_SAMPLE_RATE;
|
sampFreq = CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE;
|
||||||
clkValid = 1;
|
clkValid = 1;
|
||||||
|
|
||||||
sampleFreqRng.wNumSubRanges = 1;
|
sampleFreqRng.wNumSubRanges = 1;
|
||||||
sampleFreqRng.subrange[0].bMin = AUDIO_SAMPLE_RATE;
|
sampleFreqRng.subrange[0].bMin = CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE;
|
||||||
sampleFreqRng.subrange[0].bMax = AUDIO_SAMPLE_RATE;
|
sampleFreqRng.subrange[0].bMax = CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE;
|
||||||
sampleFreqRng.subrange[0].bRes = 0;
|
sampleFreqRng.subrange[0].bRes = 0;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
|
@ -106,6 +106,7 @@ extern "C" {
|
|||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
// Have a look into audio_device.h for all configurations
|
// Have a look into audio_device.h for all configurations
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE 48000
|
||||||
|
|
||||||
#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_MIC_ONE_CH_DESC_LEN
|
#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_MIC_ONE_CH_DESC_LEN
|
||||||
#define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 1 // Number of Standard AS Interface Descriptors (4.9.1) defined per audio function - this is required to be able to remember the current alternate settings of these interfaces - We restrict us here to have a constant number for all audio functions (which means this has to be the maximum number of AS interfaces an audio function has and a second audio function with less AS interfaces just wastes a few bytes)
|
#define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 1 // Number of Standard AS Interface Descriptors (4.9.1) defined per audio function - this is required to be able to remember the current alternate settings of these interfaces - We restrict us here to have a constant number for all audio functions (which means this has to be the maximum number of AS interfaces an audio function has and a second audio function with less AS interfaces just wastes a few bytes)
|
||||||
@ -114,9 +115,9 @@ extern "C" {
|
|||||||
#define CFG_TUD_AUDIO_ENABLE_EP_IN 1
|
#define CFG_TUD_AUDIO_ENABLE_EP_IN 1
|
||||||
#define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below
|
#define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below
|
||||||
#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 1 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below - be aware: for different number of channels you need another descriptor!
|
#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 1 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below - be aware: for different number of channels you need another descriptor!
|
||||||
#define CFG_TUD_AUDIO_EP_SZ_IN (48 + 1) * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX // 48 Samples (48 kHz) x 2 Bytes/Sample x CFG_TUD_AUDIO_N_CHANNELS_TX Channels - One extra sample is needed for asynchronous transfer adjustment, see feedback EP
|
#define CFG_TUD_AUDIO_EP_SZ_IN TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX)
|
||||||
#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN // Maximum EP IN size for all AS alternate settings used
|
#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN
|
||||||
#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ CFG_TUD_AUDIO_EP_SZ_IN + 1
|
#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 8 : 1) * CFG_TUD_AUDIO_EP_SZ_IN // Example write FIFO every 1ms, so it should be 8 times larger for HS device
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
34
examples/device/audio_test_freertos/CMakeLists.txt
Normal file
34
examples/device/audio_test_freertos/CMakeLists.txt
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.17)
|
||||||
|
|
||||||
|
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
|
||||||
|
|
||||||
|
# gets PROJECT name for the example (e.g. <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/freertos_hook.c
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
|
||||||
|
)
|
||||||
|
|
||||||
|
# Example include
|
||||||
|
target_include_directories(${PROJECT} PUBLIC
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||||
|
)
|
||||||
|
|
||||||
|
# Configure compilation flags and libraries for the example with FreeRTOS.
|
||||||
|
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
|
||||||
|
family_configure_device_example(${PROJECT} freertos)
|
38
examples/device/audio_test_freertos/Makefile
Normal file
38
examples/device/audio_test_freertos/Makefile
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
include ../../build_system/make/make.mk
|
||||||
|
|
||||||
|
FREERTOS_SRC = lib/FreeRTOS-Kernel
|
||||||
|
FREERTOS_PORTABLE_PATH = $(FREERTOS_SRC)/portable/$(if $(findstring iar,$(TOOLCHAIN)),IAR,GCC)
|
||||||
|
|
||||||
|
INC += \
|
||||||
|
src \
|
||||||
|
src/FreeRTOSConfig \
|
||||||
|
$(TOP)/hw \
|
||||||
|
$(TOP)/$(FREERTOS_SRC)/include \
|
||||||
|
$(TOP)/$(FREERTOS_PORTABLE_SRC) \
|
||||||
|
|
||||||
|
# Example source
|
||||||
|
EXAMPLE_SOURCE = \
|
||||||
|
src/freertos_hook.c \
|
||||||
|
src/main.c \
|
||||||
|
src/usb_descriptors.c
|
||||||
|
|
||||||
|
SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE))
|
||||||
|
|
||||||
|
# FreeRTOS source, all files in port folder
|
||||||
|
SRC_C += \
|
||||||
|
$(FREERTOS_SRC)/list.c \
|
||||||
|
$(FREERTOS_SRC)/queue.c \
|
||||||
|
$(FREERTOS_SRC)/tasks.c \
|
||||||
|
$(FREERTOS_SRC)/timers.c \
|
||||||
|
$(subst $(TOP)/,,$(wildcard $(TOP)/$(FREERTOS_PORTABLE_SRC)/*.c))
|
||||||
|
|
||||||
|
SRC_S += \
|
||||||
|
$(subst $(TOP)/,,$(wildcard $(TOP)/$(FREERTOS_PORTABLE_SRC)/*.s))
|
||||||
|
|
||||||
|
# Suppress FreeRTOS warnings
|
||||||
|
CFLAGS += -Wno-error=cast-qual -Wno-error=redundant-decls
|
||||||
|
|
||||||
|
# FreeRTOS (lto + Os) linker issue
|
||||||
|
LDFLAGS += -Wl,--undefined=vTaskSwitchContext
|
||||||
|
|
||||||
|
include ../../build_system/make/rules.mk
|
19
examples/device/audio_test_freertos/README.md
Normal file
19
examples/device/audio_test_freertos/README.md
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# How to build example for Esp32s3
|
||||||
|
1. Load idf environment variables (eg. using the esp-idf alias `get_idf` if configured)
|
||||||
|
|
||||||
|
2. cd into examples directory
|
||||||
|
```
|
||||||
|
$ cd /tinyusb/examples/device/audio_test_freertos
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Run cmake in project directory specifying the board
|
||||||
|
```
|
||||||
|
$ cmake -DBOARD=espressif_s3_devkitc -B build -G Ninja .
|
||||||
|
$ ninja.exe -C build
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Flash the binary onto the esp32-s3 by copy-paste of the full command output by the esp-idf build system replacing **(PORT)** with eg. /dev/ttyUSB0
|
||||||
|
|
||||||
|
eg.
|
||||||
|
|
||||||
|
> /home/kaspernyhus/.espressif/python_env/idf4.4_py3.8_env/bin/python ../../../../esp-idf/components/esptool_py/esptool/esptool.py -p /dev/ttyUSB0 -b 460800 --before default_reset --after hard_reset --chip esp32s3 write_flash --flash_mode dio --flash_size detect --flash_freq 80m 0x0 _build/espressif_s3_devkitc/bootloader/bootloader.bin 0x8000 _build/espressif_s3_devkitc/partition_table/partition-table.bin 0x10000 _build/espressif_s3_devkitc/audio_test_freertos.bin
|
3
examples/device/audio_test_freertos/sdkconfig.defaults
Normal file
3
examples/device/audio_test_freertos/sdkconfig.defaults
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
CONFIG_IDF_CMAKE=y
|
||||||
|
CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y
|
||||||
|
CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y
|
13
examples/device/audio_test_freertos/skip.txt
Normal file
13
examples/device/audio_test_freertos/skip.txt
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
mcu:CH32V307
|
||||||
|
mcu:CXD56
|
||||||
|
mcu:F1C100S
|
||||||
|
mcu:GD32VF103
|
||||||
|
mcu:MKL25ZXX
|
||||||
|
mcu:MSP430x5xx
|
||||||
|
mcu:RP2040
|
||||||
|
mcu:SAMD11
|
||||||
|
mcu:SAMX7X
|
||||||
|
mcu:VALENTYUSB_EPTRI
|
||||||
|
mcu:RAXXX
|
||||||
|
family:broadcom_32bit
|
||||||
|
family:broadcom_64bit
|
4
examples/device/audio_test_freertos/src/CMakeLists.txt
Normal file
4
examples/device/audio_test_freertos/src/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# This file is for ESP-IDF only
|
||||||
|
idf_component_register(SRCS "main.c" "usb_descriptors.c"
|
||||||
|
INCLUDE_DIRS "."
|
||||||
|
REQUIRES boards tinyusb_src)
|
@ -0,0 +1,190 @@
|
|||||||
|
/*
|
||||||
|
* FreeRTOS Kernel V10.0.0
|
||||||
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software. If you wish to use our Amazon
|
||||||
|
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* http://www.FreeRTOS.org
|
||||||
|
* http://aws.amazon.com/freertos
|
||||||
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef FREERTOS_CONFIG_H
|
||||||
|
#define FREERTOS_CONFIG_H
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Application specific definitions.
|
||||||
|
*
|
||||||
|
* These definitions should be adjusted for your particular hardware and
|
||||||
|
* application requirements.
|
||||||
|
*
|
||||||
|
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
|
||||||
|
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
|
||||||
|
*
|
||||||
|
* See http://www.freertos.org/a00110.html.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
// skip if included from IAR assembler
|
||||||
|
#ifndef __IASMARM__
|
||||||
|
|
||||||
|
// Include MCU header
|
||||||
|
#include "bsp/board_mcu.h"
|
||||||
|
|
||||||
|
#if CFG_TUSB_MCU == OPT_MCU_ESP32S2 || CFG_TUSB_MCU == OPT_MCU_ESP32S3
|
||||||
|
#error "ESP32-Sx should use IDF's FreeRTOSConfig.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// TODO fix later
|
||||||
|
#if CFG_TUSB_MCU == OPT_MCU_MM32F327X
|
||||||
|
extern u32 SystemCoreClock;
|
||||||
|
#else
|
||||||
|
// FIXME cause redundant-decls warnings
|
||||||
|
extern uint32_t SystemCoreClock;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Cortex M23/M33 port configuration. */
|
||||||
|
#define configENABLE_MPU 0
|
||||||
|
#define configENABLE_FPU 1
|
||||||
|
#define configENABLE_TRUSTZONE 0
|
||||||
|
#define configMINIMAL_SECURE_STACK_SIZE ( 1024 )
|
||||||
|
|
||||||
|
#define configUSE_PREEMPTION 1
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||||
|
#define configCPU_CLOCK_HZ SystemCoreClock
|
||||||
|
#define configTICK_RATE_HZ ( 1000 )
|
||||||
|
#define configMAX_PRIORITIES ( 5 )
|
||||||
|
#define configMINIMAL_STACK_SIZE ( 128 )
|
||||||
|
#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 )
|
||||||
|
#define configMAX_TASK_NAME_LEN 16
|
||||||
|
#define configUSE_16_BIT_TICKS 0
|
||||||
|
#define configIDLE_SHOULD_YIELD 1
|
||||||
|
#define configUSE_MUTEXES 1
|
||||||
|
#define configUSE_RECURSIVE_MUTEXES 1
|
||||||
|
#define configUSE_COUNTING_SEMAPHORES 1
|
||||||
|
#define configQUEUE_REGISTRY_SIZE 4
|
||||||
|
#define configUSE_QUEUE_SETS 0
|
||||||
|
#define configUSE_TIME_SLICING 0
|
||||||
|
#define configUSE_NEWLIB_REENTRANT 0
|
||||||
|
#define configENABLE_BACKWARD_COMPATIBILITY 1
|
||||||
|
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
|
||||||
|
|
||||||
|
#define configSUPPORT_STATIC_ALLOCATION 1
|
||||||
|
#define configSUPPORT_DYNAMIC_ALLOCATION 0
|
||||||
|
|
||||||
|
/* Hook function related definitions. */
|
||||||
|
#define configUSE_IDLE_HOOK 0
|
||||||
|
#define configUSE_TICK_HOOK 0
|
||||||
|
#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning
|
||||||
|
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||||
|
#define configCHECK_HANDLER_INSTALLATION 0
|
||||||
|
|
||||||
|
/* Run time and task stats gathering related definitions. */
|
||||||
|
#define configGENERATE_RUN_TIME_STATS 0
|
||||||
|
#define configUSE_TRACE_FACILITY 1 // legacy trace
|
||||||
|
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
|
||||||
|
|
||||||
|
/* Co-routine definitions. */
|
||||||
|
#define configUSE_CO_ROUTINES 0
|
||||||
|
#define configMAX_CO_ROUTINE_PRIORITIES 2
|
||||||
|
|
||||||
|
/* Software timer related definitions. */
|
||||||
|
#define configUSE_TIMERS 1
|
||||||
|
#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2)
|
||||||
|
#define configTIMER_QUEUE_LENGTH 32
|
||||||
|
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
|
||||||
|
|
||||||
|
/* Optional functions - most linkers will remove unused functions anyway. */
|
||||||
|
#define INCLUDE_vTaskPrioritySet 0
|
||||||
|
#define INCLUDE_uxTaskPriorityGet 0
|
||||||
|
#define INCLUDE_vTaskDelete 0
|
||||||
|
#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY
|
||||||
|
#define INCLUDE_xResumeFromISR 0
|
||||||
|
#define INCLUDE_vTaskDelayUntil 1
|
||||||
|
#define INCLUDE_vTaskDelay 1
|
||||||
|
#define INCLUDE_xTaskGetSchedulerState 0
|
||||||
|
#define INCLUDE_xTaskGetCurrentTaskHandle 0
|
||||||
|
#define INCLUDE_uxTaskGetStackHighWaterMark 0
|
||||||
|
#define INCLUDE_xTaskGetIdleTaskHandle 0
|
||||||
|
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
|
||||||
|
#define INCLUDE_pcTaskGetTaskName 0
|
||||||
|
#define INCLUDE_eTaskGetState 0
|
||||||
|
#define INCLUDE_xEventGroupSetBitFromISR 0
|
||||||
|
#define INCLUDE_xTimerPendFunctionCall 0
|
||||||
|
|
||||||
|
#ifdef __RX__
|
||||||
|
/* Renesas RX series */
|
||||||
|
#define vSoftwareInterruptISR INT_Excep_ICU_SWINT
|
||||||
|
#define vTickISR INT_Excep_CMT0_CMI0
|
||||||
|
#define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2)
|
||||||
|
#define configKERNEL_INTERRUPT_PRIORITY 1
|
||||||
|
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 4
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* FreeRTOS hooks to NVIC vectors */
|
||||||
|
#define xPortPendSVHandler PendSV_Handler
|
||||||
|
#define xPortSysTickHandler SysTick_Handler
|
||||||
|
#define vPortSVCHandler SVC_Handler
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Interrupt nesting behavior configuration.
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
#if defined(__NVIC_PRIO_BITS)
|
||||||
|
// For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h
|
||||||
|
#define configPRIO_BITS __NVIC_PRIO_BITS
|
||||||
|
|
||||||
|
#elif defined(__ECLIC_INTCTLBITS)
|
||||||
|
// RISC-V Bumblebee core from nuclei
|
||||||
|
#define configPRIO_BITS __ECLIC_INTCTLBITS
|
||||||
|
|
||||||
|
#elif defined(__IASMARM__)
|
||||||
|
// FIXME: IAR Assembler cannot include mcu header directly to get __NVIC_PRIO_BITS.
|
||||||
|
// Therefore we will hard coded it to minimum value of 2 to get pass ci build.
|
||||||
|
// IAR user must update this to correct value of the target MCU
|
||||||
|
#message "configPRIO_BITS is hard coded to 2 to pass IAR build only. User should update it per MCU"
|
||||||
|
#define configPRIO_BITS 2
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "FreeRTOS configPRIO_BITS to be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The lowest interrupt priority that can be used in a call to a "set priority" function. */
|
||||||
|
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<<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
|
||||||
|
|
||||||
|
#endif /* __FREERTOS_CONFIG__H */
|
115
examples/device/audio_test_freertos/src/freertos_hook.c
Normal file
115
examples/device/audio_test_freertos/src/freertos_hook.c
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// INCLUDE
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "common/tusb_common.h"
|
||||||
|
|
||||||
|
|
||||||
|
void vApplicationMallocFailedHook(void)
|
||||||
|
{
|
||||||
|
taskDISABLE_INTERRUPTS();
|
||||||
|
TU_ASSERT(false, );
|
||||||
|
}
|
||||||
|
|
||||||
|
void vApplicationStackOverflowHook(xTaskHandle pxTask, char *pcTaskName)
|
||||||
|
{
|
||||||
|
(void) pxTask;
|
||||||
|
(void) pcTaskName;
|
||||||
|
|
||||||
|
taskDISABLE_INTERRUPTS();
|
||||||
|
TU_ASSERT(false, );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* configSUPPORT_STATIC_ALLOCATION is set to 1, so the application must provide an
|
||||||
|
* implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
|
||||||
|
* used by the Idle task. */
|
||||||
|
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
|
||||||
|
{
|
||||||
|
/* If the buffers to be provided to the Idle task are declared inside this
|
||||||
|
* function then they must be declared static - otherwise they will be allocated on
|
||||||
|
* the stack and so not exists after this function exits. */
|
||||||
|
static StaticTask_t xIdleTaskTCB;
|
||||||
|
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
|
||||||
|
|
||||||
|
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's
|
||||||
|
state will be stored. */
|
||||||
|
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
|
||||||
|
|
||||||
|
/* Pass out the array that will be used as the Idle task's stack. */
|
||||||
|
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
|
||||||
|
|
||||||
|
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
|
||||||
|
Note that, as the array is necessarily of type StackType_t,
|
||||||
|
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
|
||||||
|
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* configSUPPORT_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
|
||||||
|
* application must provide an implementation of vApplicationGetTimerTaskMemory()
|
||||||
|
* to provide the memory that is used by the Timer service task. */
|
||||||
|
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize )
|
||||||
|
{
|
||||||
|
/* If the buffers to be provided to the Timer task are declared inside this
|
||||||
|
* function then they must be declared static - otherwise they will be allocated on
|
||||||
|
* the stack and so not exists after this function exits. */
|
||||||
|
static StaticTask_t xTimerTaskTCB;
|
||||||
|
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
|
||||||
|
|
||||||
|
/* Pass out a pointer to the StaticTask_t structure in which the Timer
|
||||||
|
task's state will be stored. */
|
||||||
|
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
|
||||||
|
|
||||||
|
/* Pass out the array that will be used as the Timer task's stack. */
|
||||||
|
*ppxTimerTaskStackBuffer = uxTimerTaskStack;
|
||||||
|
|
||||||
|
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
|
||||||
|
Note that, as the array is necessarily of type StackType_t,
|
||||||
|
configTIMER_TASK_STACK_DEPTH is specified in words, not bytes. */
|
||||||
|
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CFG_TUSB_MCU == OPT_MCU_RX63X | CFG_TUSB_MCU == OPT_MCU_RX65X
|
||||||
|
#include "iodefine.h"
|
||||||
|
void vApplicationSetupTimerInterrupt(void)
|
||||||
|
{
|
||||||
|
/* Enable CMT0 */
|
||||||
|
unsigned short oldPRCR = SYSTEM.PRCR.WORD;
|
||||||
|
SYSTEM.PRCR.WORD = (0xA5u<<8) | TU_BIT(1);
|
||||||
|
MSTP(CMT0) = 0;
|
||||||
|
SYSTEM.PRCR.WORD = (0xA5u<<8) | oldPRCR;
|
||||||
|
|
||||||
|
CMT0.CMCNT = 0;
|
||||||
|
CMT0.CMCOR = (unsigned short)(((configPERIPHERAL_CLOCK_HZ/configTICK_RATE_HZ)-1)/128);
|
||||||
|
CMT0.CMCR.WORD = TU_BIT(6) | 2;
|
||||||
|
IR(CMT0, CMI0) = 0;
|
||||||
|
IPR(CMT0, CMI0) = configKERNEL_INTERRUPT_PRIORITY;
|
||||||
|
IEN(CMT0, CMI0) = 1;
|
||||||
|
CMT.CMSTR0.BIT.STR0 = 1;
|
||||||
|
}
|
||||||
|
#endif
|
508
examples/device/audio_test_freertos/src/main.c
Normal file
508
examples/device/audio_test_freertos/src/main.c
Normal file
@ -0,0 +1,508 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Reinhard Panhuber
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* plot_audio_samples.py requires following modules:
|
||||||
|
* $ sudo apt install libportaudio
|
||||||
|
* $ pip3 install sounddevice matplotlib
|
||||||
|
*
|
||||||
|
* Then run
|
||||||
|
* $ python3 plot_audio_samples.py
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "bsp/board_api.h"
|
||||||
|
#include "tusb.h"
|
||||||
|
|
||||||
|
#if TUP_MCU_ESPRESSIF
|
||||||
|
// ESP-IDF need "freertos/" prefix in include path.
|
||||||
|
// CFG_TUSB_OS_INC_PATH should be defined accordingly.
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/semphr.h"
|
||||||
|
#include "freertos/queue.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "freertos/timers.h"
|
||||||
|
|
||||||
|
#define USBD_STACK_SIZE 4096
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
#include "queue.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "timers.h"
|
||||||
|
|
||||||
|
// Increase stack size when debug log is enabled
|
||||||
|
#define USBD_STACK_SIZE (4*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// MACRO CONSTANT TYPEDEF PROTYPES
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
/* Blink pattern
|
||||||
|
* - 250 ms : device not mounted
|
||||||
|
* - 1000 ms : device mounted
|
||||||
|
* - 2500 ms : device is suspended
|
||||||
|
*/
|
||||||
|
enum {
|
||||||
|
BLINK_NOT_MOUNTED = 250,
|
||||||
|
BLINK_MOUNTED = 1000,
|
||||||
|
BLINK_SUSPENDED = 2500,
|
||||||
|
};
|
||||||
|
|
||||||
|
// static task
|
||||||
|
#if configSUPPORT_STATIC_ALLOCATION
|
||||||
|
StackType_t blinky_stack[BLINKY_STACK_SIZE];
|
||||||
|
StaticTask_t blinky_taskdef;
|
||||||
|
|
||||||
|
StackType_t usb_device_stack[USBD_STACK_SIZE];
|
||||||
|
StaticTask_t usb_device_taskdef;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
|
||||||
|
|
||||||
|
// Audio controls
|
||||||
|
// Current states
|
||||||
|
bool mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0
|
||||||
|
uint16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0
|
||||||
|
uint32_t sampFreq;
|
||||||
|
uint8_t clkValid;
|
||||||
|
|
||||||
|
// Range states
|
||||||
|
audio_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX+1]; // Volume range state
|
||||||
|
audio_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state
|
||||||
|
|
||||||
|
// Audio test data
|
||||||
|
uint16_t test_buffer_audio[(CFG_TUD_AUDIO_EP_SZ_IN - 2) / 2];
|
||||||
|
uint16_t startVal = 0;
|
||||||
|
|
||||||
|
void led_blinking_task(void* param);
|
||||||
|
void usb_device_task(void* param);
|
||||||
|
void audio_task(void);
|
||||||
|
|
||||||
|
/*------------- MAIN -------------*/
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
board_init();
|
||||||
|
|
||||||
|
// Init values
|
||||||
|
sampFreq = CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE;
|
||||||
|
clkValid = 1;
|
||||||
|
|
||||||
|
sampleFreqRng.wNumSubRanges = 1;
|
||||||
|
sampleFreqRng.subrange[0].bMin = CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE;
|
||||||
|
sampleFreqRng.subrange[0].bMax = CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE;
|
||||||
|
sampleFreqRng.subrange[0].bRes = 0;
|
||||||
|
|
||||||
|
#if configSUPPORT_STATIC_ALLOCATION
|
||||||
|
// blinky task
|
||||||
|
xTaskCreateStatic(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, blinky_stack, &blinky_taskdef);
|
||||||
|
|
||||||
|
// Create a task for tinyusb device stack
|
||||||
|
xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef);
|
||||||
|
#else
|
||||||
|
xTaskCreate(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, NULL);
|
||||||
|
xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// skip starting scheduler (and return) for ESP32-S2 or ESP32-S3
|
||||||
|
#if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
|
||||||
|
vTaskStartScheduler();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
|
||||||
|
void app_main(void)
|
||||||
|
{
|
||||||
|
main();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// USB Device Driver task
|
||||||
|
// This top level thread process all usb events and invoke callbacks
|
||||||
|
void usb_device_task(void* param)
|
||||||
|
{
|
||||||
|
(void) param;
|
||||||
|
|
||||||
|
// init device stack on configured roothub port
|
||||||
|
// This should be called after scheduler/kernel is started.
|
||||||
|
// Otherwise it could cause kernel issue since USB IRQ handler does use RTOS queue API.
|
||||||
|
tud_init(BOARD_TUD_RHPORT);
|
||||||
|
|
||||||
|
if (board_init_after_tusb) {
|
||||||
|
board_init_after_tusb();
|
||||||
|
}
|
||||||
|
|
||||||
|
// RTOS forever loop
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
// tinyusb device task
|
||||||
|
tud_task();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Device callbacks
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// Invoked when device is mounted
|
||||||
|
void tud_mount_cb(void) {
|
||||||
|
blink_interval_ms = BLINK_MOUNTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when device is unmounted
|
||||||
|
void tud_umount_cb(void) {
|
||||||
|
blink_interval_ms = BLINK_NOT_MOUNTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when usb bus is suspended
|
||||||
|
// remote_wakeup_en : if host allow us to perform remote wakeup
|
||||||
|
// Within 7ms, device must draw an average of current less than 2.5 mA from bus
|
||||||
|
void tud_suspend_cb(bool remote_wakeup_en) {
|
||||||
|
(void) remote_wakeup_en;
|
||||||
|
blink_interval_ms = BLINK_SUSPENDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when usb bus is resumed
|
||||||
|
void tud_resume_cb(void) {
|
||||||
|
blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// AUDIO Task
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
void audio_task(void)
|
||||||
|
{
|
||||||
|
// Yet to be filled - e.g. put meas data into TX FIFOs etc.
|
||||||
|
// asm("nop");
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Application Callback API Implementations
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// Invoked when audio class specific set request received for an EP
|
||||||
|
bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff)
|
||||||
|
{
|
||||||
|
(void) rhport;
|
||||||
|
(void) pBuff;
|
||||||
|
|
||||||
|
// We do not support any set range requests here, only current value requests
|
||||||
|
TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR);
|
||||||
|
|
||||||
|
// Page 91 in UAC2 specification
|
||||||
|
uint8_t channelNum = TU_U16_LOW(p_request->wValue);
|
||||||
|
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
|
||||||
|
uint8_t ep = TU_U16_LOW(p_request->wIndex);
|
||||||
|
|
||||||
|
(void) channelNum; (void) ctrlSel; (void) ep;
|
||||||
|
|
||||||
|
return false; // Yet not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when audio class specific set request received for an interface
|
||||||
|
bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff)
|
||||||
|
{
|
||||||
|
(void) rhport;
|
||||||
|
(void) pBuff;
|
||||||
|
|
||||||
|
// We do not support any set range requests here, only current value requests
|
||||||
|
TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR);
|
||||||
|
|
||||||
|
// Page 91 in UAC2 specification
|
||||||
|
uint8_t channelNum = TU_U16_LOW(p_request->wValue);
|
||||||
|
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
|
||||||
|
uint8_t itf = TU_U16_LOW(p_request->wIndex);
|
||||||
|
|
||||||
|
(void) channelNum; (void) ctrlSel; (void) itf;
|
||||||
|
|
||||||
|
return false; // Yet not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when audio class specific set request received for an entity
|
||||||
|
bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff)
|
||||||
|
{
|
||||||
|
(void) rhport;
|
||||||
|
|
||||||
|
// Page 91 in UAC2 specification
|
||||||
|
uint8_t channelNum = TU_U16_LOW(p_request->wValue);
|
||||||
|
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
|
||||||
|
uint8_t itf = TU_U16_LOW(p_request->wIndex);
|
||||||
|
uint8_t entityID = TU_U16_HIGH(p_request->wIndex);
|
||||||
|
|
||||||
|
(void) itf;
|
||||||
|
|
||||||
|
// We do not support any set range requests here, only current value requests
|
||||||
|
TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR);
|
||||||
|
|
||||||
|
// If request is for our feature unit
|
||||||
|
if ( entityID == 2 )
|
||||||
|
{
|
||||||
|
switch ( ctrlSel )
|
||||||
|
{
|
||||||
|
case AUDIO_FU_CTRL_MUTE:
|
||||||
|
// Request uses format layout 1
|
||||||
|
TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_1_t));
|
||||||
|
|
||||||
|
mute[channelNum] = ((audio_control_cur_1_t*) pBuff)->bCur;
|
||||||
|
|
||||||
|
TU_LOG2(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case AUDIO_FU_CTRL_VOLUME:
|
||||||
|
// Request uses format layout 2
|
||||||
|
TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_2_t));
|
||||||
|
|
||||||
|
volume[channelNum] = (uint16_t) ((audio_control_cur_2_t*) pBuff)->bCur;
|
||||||
|
|
||||||
|
TU_LOG2(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Unknown/Unsupported control
|
||||||
|
default:
|
||||||
|
TU_BREAKPOINT();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false; // Yet not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when audio class specific get request received for an EP
|
||||||
|
bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request)
|
||||||
|
{
|
||||||
|
(void) rhport;
|
||||||
|
|
||||||
|
// Page 91 in UAC2 specification
|
||||||
|
uint8_t channelNum = TU_U16_LOW(p_request->wValue);
|
||||||
|
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
|
||||||
|
uint8_t ep = TU_U16_LOW(p_request->wIndex);
|
||||||
|
|
||||||
|
(void) channelNum; (void) ctrlSel; (void) ep;
|
||||||
|
|
||||||
|
return false; // Yet not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when audio class specific get request received for an interface
|
||||||
|
bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request)
|
||||||
|
{
|
||||||
|
(void) rhport;
|
||||||
|
|
||||||
|
// Page 91 in UAC2 specification
|
||||||
|
uint8_t channelNum = TU_U16_LOW(p_request->wValue);
|
||||||
|
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
|
||||||
|
uint8_t itf = TU_U16_LOW(p_request->wIndex);
|
||||||
|
|
||||||
|
(void) channelNum; (void) ctrlSel; (void) itf;
|
||||||
|
|
||||||
|
return false; // Yet not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when audio class specific get request received for an entity
|
||||||
|
bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request)
|
||||||
|
{
|
||||||
|
(void) rhport;
|
||||||
|
|
||||||
|
// Page 91 in UAC2 specification
|
||||||
|
uint8_t channelNum = TU_U16_LOW(p_request->wValue);
|
||||||
|
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
|
||||||
|
// uint8_t itf = TU_U16_LOW(p_request->wIndex); // Since we have only one audio function implemented, we do not need the itf value
|
||||||
|
uint8_t entityID = TU_U16_HIGH(p_request->wIndex);
|
||||||
|
|
||||||
|
// Input terminal (Microphone input)
|
||||||
|
if (entityID == 1)
|
||||||
|
{
|
||||||
|
switch ( ctrlSel )
|
||||||
|
{
|
||||||
|
case AUDIO_TE_CTRL_CONNECTOR:
|
||||||
|
{
|
||||||
|
// The terminal connector control only has a get request with only the CUR attribute.
|
||||||
|
audio_desc_channel_cluster_t ret;
|
||||||
|
|
||||||
|
// Those are dummy values for now
|
||||||
|
ret.bNrChannels = 1;
|
||||||
|
ret.bmChannelConfig = (audio_channel_config_t) 0;
|
||||||
|
ret.iChannelNames = 0;
|
||||||
|
|
||||||
|
TU_LOG2(" Get terminal connector\r\n");
|
||||||
|
|
||||||
|
return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void*) &ret, sizeof(ret));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Unknown/Unsupported control selector
|
||||||
|
default:
|
||||||
|
TU_BREAKPOINT();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Feature unit
|
||||||
|
if (entityID == 2)
|
||||||
|
{
|
||||||
|
switch ( ctrlSel )
|
||||||
|
{
|
||||||
|
case AUDIO_FU_CTRL_MUTE:
|
||||||
|
// Audio control mute cur parameter block consists of only one byte - we thus can send it right away
|
||||||
|
// There does not exist a range parameter block for mute
|
||||||
|
TU_LOG2(" Get Mute of channel: %u\r\n", channelNum);
|
||||||
|
return tud_control_xfer(rhport, p_request, &mute[channelNum], 1);
|
||||||
|
|
||||||
|
case AUDIO_FU_CTRL_VOLUME:
|
||||||
|
switch ( p_request->bRequest )
|
||||||
|
{
|
||||||
|
case AUDIO_CS_REQ_CUR:
|
||||||
|
TU_LOG2(" Get Volume of channel: %u\r\n", channelNum);
|
||||||
|
return tud_control_xfer(rhport, p_request, &volume[channelNum], sizeof(volume[channelNum]));
|
||||||
|
|
||||||
|
case AUDIO_CS_REQ_RANGE:
|
||||||
|
TU_LOG2(" Get Volume range of channel: %u\r\n", channelNum);
|
||||||
|
|
||||||
|
// Copy values - only for testing - better is version below
|
||||||
|
audio_control_range_2_n_t(1)
|
||||||
|
ret;
|
||||||
|
|
||||||
|
ret.wNumSubRanges = 1;
|
||||||
|
ret.subrange[0].bMin = -90; // -90 dB
|
||||||
|
ret.subrange[0].bMax = 90; // +90 dB
|
||||||
|
ret.subrange[0].bRes = 1; // 1 dB steps
|
||||||
|
|
||||||
|
return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void*) &ret, sizeof(ret));
|
||||||
|
|
||||||
|
// Unknown/Unsupported control
|
||||||
|
default:
|
||||||
|
TU_BREAKPOINT();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Unknown/Unsupported control
|
||||||
|
default:
|
||||||
|
TU_BREAKPOINT();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clock Source unit
|
||||||
|
if ( entityID == 4 )
|
||||||
|
{
|
||||||
|
switch ( ctrlSel )
|
||||||
|
{
|
||||||
|
case AUDIO_CS_CTRL_SAM_FREQ:
|
||||||
|
// channelNum is always zero in this case
|
||||||
|
switch ( p_request->bRequest )
|
||||||
|
{
|
||||||
|
case AUDIO_CS_REQ_CUR:
|
||||||
|
TU_LOG2(" Get Sample Freq.\r\n");
|
||||||
|
return tud_control_xfer(rhport, p_request, &sampFreq, sizeof(sampFreq));
|
||||||
|
|
||||||
|
case AUDIO_CS_REQ_RANGE:
|
||||||
|
TU_LOG2(" Get Sample Freq. range\r\n");
|
||||||
|
return tud_control_xfer(rhport, p_request, &sampleFreqRng, sizeof(sampleFreqRng));
|
||||||
|
|
||||||
|
// Unknown/Unsupported control
|
||||||
|
default:
|
||||||
|
TU_BREAKPOINT();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AUDIO_CS_CTRL_CLK_VALID:
|
||||||
|
// Only cur attribute exists for this request
|
||||||
|
TU_LOG2(" Get Sample Freq. valid\r\n");
|
||||||
|
return tud_control_xfer(rhport, p_request, &clkValid, sizeof(clkValid));
|
||||||
|
|
||||||
|
// Unknown/Unsupported control
|
||||||
|
default:
|
||||||
|
TU_BREAKPOINT();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TU_LOG2(" Unsupported entity: %d\r\n", entityID);
|
||||||
|
return false; // Yet not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tud_audio_tx_done_pre_load_cb(uint8_t rhport, uint8_t itf, uint8_t ep_in, uint8_t cur_alt_setting)
|
||||||
|
{
|
||||||
|
(void) rhport;
|
||||||
|
(void) itf;
|
||||||
|
(void) ep_in;
|
||||||
|
(void) cur_alt_setting;
|
||||||
|
|
||||||
|
tud_audio_write ((uint8_t *)test_buffer_audio, CFG_TUD_AUDIO_EP_SZ_IN - 2);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tud_audio_tx_done_post_load_cb(uint8_t rhport, uint16_t n_bytes_copied, uint8_t itf, uint8_t ep_in, uint8_t cur_alt_setting)
|
||||||
|
{
|
||||||
|
(void) rhport;
|
||||||
|
(void) n_bytes_copied;
|
||||||
|
(void) itf;
|
||||||
|
(void) ep_in;
|
||||||
|
(void) cur_alt_setting;
|
||||||
|
|
||||||
|
for (size_t cnt = 0; cnt < (CFG_TUD_AUDIO_EP_SZ_IN - 2) / 2; cnt++)
|
||||||
|
{
|
||||||
|
test_buffer_audio[cnt] = startVal++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const * p_request)
|
||||||
|
{
|
||||||
|
(void) rhport;
|
||||||
|
(void) p_request;
|
||||||
|
startVal = 0;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// BLINKING TASK
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
void led_blinking_task(void* param) {
|
||||||
|
(void) param;
|
||||||
|
static uint32_t start_ms = 0;
|
||||||
|
static bool led_state = false;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
// Blink every interval ms
|
||||||
|
vTaskDelay(blink_interval_ms / portTICK_PERIOD_MS);
|
||||||
|
start_ms += blink_interval_ms;
|
||||||
|
|
||||||
|
board_led_write(led_state);
|
||||||
|
led_state = 1 - led_state; // toggle
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
import sounddevice as sd
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import numpy as np
|
||||||
|
import platform
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
# If you got "ValueError: No input device matching", that is because your PC name example device
|
||||||
|
# differently from tested list below. Uncomment the next line to see full list and try to pick correct one
|
||||||
|
# print(sd.query_devices())
|
||||||
|
|
||||||
|
fs = 48000 # Sample rate
|
||||||
|
duration = 1000e-3 # Duration of recording
|
||||||
|
|
||||||
|
if platform.system() == 'Windows':
|
||||||
|
# MME is needed since there are more than one MicNode device APIs (at least in Windows)
|
||||||
|
device = 'Microphone (MicNode) MME'
|
||||||
|
elif platform.system() == 'Darwin':
|
||||||
|
device = 'MicNode'
|
||||||
|
else:
|
||||||
|
device ='default'
|
||||||
|
|
||||||
|
myrecording = sd.rec(int(duration * fs), samplerate=fs, channels=1, dtype='int16', device=device)
|
||||||
|
print('Waiting...')
|
||||||
|
sd.wait() # Wait until recording is finished
|
||||||
|
print('Done!')
|
||||||
|
|
||||||
|
time = np.arange(0, duration, 1 / fs) # time vector
|
||||||
|
plt.plot(time, myrecording)
|
||||||
|
plt.xlabel('Time [s]')
|
||||||
|
plt.ylabel('Amplitude')
|
||||||
|
plt.title('MicNode')
|
||||||
|
plt.show()
|
132
examples/device/audio_test_freertos/src/tusb_config.h
Normal file
132
examples/device/audio_test_freertos/src/tusb_config.h
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _TUSB_CONFIG_H_
|
||||||
|
#define _TUSB_CONFIG_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Board Specific Configuration
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// RHPort number used for device can be defined by board.mk, default to port 0
|
||||||
|
#ifndef BOARD_TUD_RHPORT
|
||||||
|
#define BOARD_TUD_RHPORT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// RHPort max operational speed can defined by board.mk
|
||||||
|
#ifndef BOARD_TUD_MAX_SPEED
|
||||||
|
#define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// COMMON CONFIGURATION
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
|
// defined by compiler flags for flexibility
|
||||||
|
#ifndef CFG_TUSB_MCU
|
||||||
|
#error CFG_TUSB_MCU must be defined
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// This examples use FreeRTOS
|
||||||
|
#ifndef CFG_TUSB_OS
|
||||||
|
#define CFG_TUSB_OS OPT_OS_FREERTOS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Espressif IDF requires "freertos/" prefix in include path
|
||||||
|
#if TUP_MCU_ESPRESSIF
|
||||||
|
#define CFG_TUSB_OS_INC_PATH freertos/
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CFG_TUSB_DEBUG
|
||||||
|
#define CFG_TUSB_DEBUG 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Enable Device stack
|
||||||
|
#define CFG_TUD_ENABLED 1
|
||||||
|
|
||||||
|
// Default is max speed that hardware controller could support with on-chip PHY
|
||||||
|
#define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED
|
||||||
|
|
||||||
|
// CFG_TUSB_DEBUG is defined by compiler in DEBUG build
|
||||||
|
// #define CFG_TUSB_DEBUG 0
|
||||||
|
|
||||||
|
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
|
||||||
|
* Tinyusb use follows macros to declare transferring memory so that they can be put
|
||||||
|
* into those specific section.
|
||||||
|
* e.g
|
||||||
|
* - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") ))
|
||||||
|
* - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4)))
|
||||||
|
*/
|
||||||
|
#ifndef CFG_TUSB_MEM_SECTION
|
||||||
|
#define CFG_TUSB_MEM_SECTION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CFG_TUSB_MEM_ALIGN
|
||||||
|
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// DEVICE CONFIGURATION
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef CFG_TUD_ENDPOINT0_SIZE
|
||||||
|
#define CFG_TUD_ENDPOINT0_SIZE 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------- CLASS -------------//
|
||||||
|
#define CFG_TUD_AUDIO 1
|
||||||
|
#define CFG_TUD_CDC 0
|
||||||
|
#define CFG_TUD_MSC 0
|
||||||
|
#define CFG_TUD_HID 0
|
||||||
|
#define CFG_TUD_MIDI 0
|
||||||
|
#define CFG_TUD_VENDOR 0
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// AUDIO CLASS DRIVER CONFIGURATION
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Have a look into audio_device.h for all configurations
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE 48000
|
||||||
|
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_MIC_ONE_CH_DESC_LEN
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 1 // Number of Standard AS Interface Descriptors (4.9.1) defined per audio function - this is required to be able to remember the current alternate settings of these interfaces - We restrict us here to have a constant number for all audio functions (which means this has to be the maximum number of AS interfaces an audio function has and a second audio function with less AS interfaces just wastes a few bytes)
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64 // Size of control request buffer
|
||||||
|
|
||||||
|
#define CFG_TUD_AUDIO_ENABLE_EP_IN 1
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 1 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below - be aware: for different number of channels you need another descriptor!
|
||||||
|
#define CFG_TUD_AUDIO_EP_SZ_IN TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX)
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN
|
||||||
|
#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 8 : 1) * CFG_TUD_AUDIO_EP_SZ_IN // Example write FIFO every 1ms, so it should be 8 times larger for HS device
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _TUSB_CONFIG_H_ */
|
181
examples/device/audio_test_freertos/src/usb_descriptors.c
Normal file
181
examples/device/audio_test_freertos/src/usb_descriptors.c
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "bsp/board_api.h"
|
||||||
|
#include "tusb.h"
|
||||||
|
|
||||||
|
/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug.
|
||||||
|
* Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC.
|
||||||
|
*
|
||||||
|
* Auto ProductID layout's Bitmap:
|
||||||
|
* [MSB] AUDIO | MIDI | HID | MSC | CDC [LSB]
|
||||||
|
*/
|
||||||
|
#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) )
|
||||||
|
#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \
|
||||||
|
_PID_MAP(MIDI, 3) | _PID_MAP(AUDIO, 4) | _PID_MAP(VENDOR, 5) )
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Device Descriptors
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
tusb_desc_device_t const desc_device =
|
||||||
|
{
|
||||||
|
.bLength = sizeof(tusb_desc_device_t),
|
||||||
|
.bDescriptorType = TUSB_DESC_DEVICE,
|
||||||
|
.bcdUSB = 0x0200,
|
||||||
|
|
||||||
|
// Use Interface Association Descriptor (IAD) for Audio
|
||||||
|
// As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1)
|
||||||
|
.bDeviceClass = TUSB_CLASS_MISC,
|
||||||
|
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
|
||||||
|
.bDeviceProtocol = MISC_PROTOCOL_IAD,
|
||||||
|
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
|
||||||
|
|
||||||
|
.idVendor = 0xCafe,
|
||||||
|
.idProduct = USB_PID,
|
||||||
|
.bcdDevice = 0x0100,
|
||||||
|
|
||||||
|
.iManufacturer = 0x01,
|
||||||
|
.iProduct = 0x02,
|
||||||
|
.iSerialNumber = 0x03,
|
||||||
|
|
||||||
|
.bNumConfigurations = 0x01
|
||||||
|
};
|
||||||
|
|
||||||
|
// Invoked when received GET DEVICE DESCRIPTOR
|
||||||
|
// Application return pointer to descriptor
|
||||||
|
uint8_t const * tud_descriptor_device_cb(void)
|
||||||
|
{
|
||||||
|
return (uint8_t const *) &desc_device;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Configuration Descriptor
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
ITF_NUM_AUDIO_CONTROL = 0,
|
||||||
|
ITF_NUM_AUDIO_STREAMING,
|
||||||
|
ITF_NUM_TOTAL
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_AUDIO * TUD_AUDIO_MIC_ONE_CH_DESC_LEN)
|
||||||
|
|
||||||
|
#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX
|
||||||
|
// LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number
|
||||||
|
// 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ...
|
||||||
|
#define EPNUM_AUDIO 0x03
|
||||||
|
|
||||||
|
#elif TU_CHECK_MCU(OPT_MCU_NRF5X)
|
||||||
|
// nRF5x ISO can only be endpoint 8
|
||||||
|
#define EPNUM_AUDIO 0x08
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define EPNUM_AUDIO 0x01
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint8_t const desc_configuration[] =
|
||||||
|
{
|
||||||
|
// Config number, interface count, string index, total length, attribute, power in mA
|
||||||
|
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
|
||||||
|
|
||||||
|
// Interface number, string index, EP Out & EP In address, EP size
|
||||||
|
TUD_AUDIO_MIC_ONE_CH_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_nBytesPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, /*_nBitsUsedPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX*8, /*_epin*/ 0x80 | EPNUM_AUDIO, /*_epsize*/ CFG_TUD_AUDIO_EP_SZ_IN)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Invoked when received GET CONFIGURATION DESCRIPTOR
|
||||||
|
// Application return pointer to descriptor
|
||||||
|
// Descriptor contents must exist long enough for transfer to complete
|
||||||
|
uint8_t const * tud_descriptor_configuration_cb(uint8_t index)
|
||||||
|
{
|
||||||
|
(void) index; // for multiple configurations
|
||||||
|
return desc_configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// String Descriptors
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// String Descriptor Index
|
||||||
|
enum {
|
||||||
|
STRID_LANGID = 0,
|
||||||
|
STRID_MANUFACTURER,
|
||||||
|
STRID_PRODUCT,
|
||||||
|
STRID_SERIAL,
|
||||||
|
};
|
||||||
|
|
||||||
|
// array of pointer to string descriptors
|
||||||
|
char const* string_desc_arr [] =
|
||||||
|
{
|
||||||
|
(const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409)
|
||||||
|
"PaniRCorp", // 1: Manufacturer
|
||||||
|
"MicNode", // 2: Product
|
||||||
|
NULL, // 3: Serials will use unique ID if possible
|
||||||
|
"UAC2", // 4: Audio Interface
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint16_t _desc_str[32 + 1];
|
||||||
|
|
||||||
|
// Invoked when received GET STRING DESCRIPTOR request
|
||||||
|
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
|
||||||
|
uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
|
||||||
|
(void) langid;
|
||||||
|
size_t chr_count;
|
||||||
|
|
||||||
|
switch ( index ) {
|
||||||
|
case STRID_LANGID:
|
||||||
|
memcpy(&_desc_str[1], string_desc_arr[0], 2);
|
||||||
|
chr_count = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STRID_SERIAL:
|
||||||
|
chr_count = board_usb_get_serial(_desc_str + 1, 32);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors.
|
||||||
|
// https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors
|
||||||
|
|
||||||
|
if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL;
|
||||||
|
|
||||||
|
const char *str = string_desc_arr[index];
|
||||||
|
|
||||||
|
// Cap at max char
|
||||||
|
chr_count = strlen(str);
|
||||||
|
size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type
|
||||||
|
if ( chr_count > max_count ) chr_count = max_count;
|
||||||
|
|
||||||
|
// Convert ASCII string into UTF-16
|
||||||
|
for ( size_t i = 0; i < chr_count; i++ ) {
|
||||||
|
_desc_str[1 + i] = str[i];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// first byte is length (including header), second byte is string type
|
||||||
|
_desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2));
|
||||||
|
|
||||||
|
return _desc_str;
|
||||||
|
}
|
@ -9,5 +9,6 @@ mcu:SAMD11
|
|||||||
mcu:SAMX7X
|
mcu:SAMX7X
|
||||||
mcu:VALENTYUSB_EPTRI
|
mcu:VALENTYUSB_EPTRI
|
||||||
mcu:RAXXX
|
mcu:RAXXX
|
||||||
|
mcu:STM32L0
|
||||||
family:broadcom_32bit
|
family:broadcom_32bit
|
||||||
family:broadcom_64bit
|
family:broadcom_64bit
|
||||||
|
@ -74,6 +74,7 @@ target_sources(${PROJECT} PUBLIC
|
|||||||
${LWIP}/src/netif/slipif.c
|
${LWIP}/src/netif/slipif.c
|
||||||
${LWIP}/src/apps/http/httpd.c
|
${LWIP}/src/apps/http/httpd.c
|
||||||
${LWIP}/src/apps/http/fs.c
|
${LWIP}/src/apps/http/fs.c
|
||||||
|
${LWIP}/src/apps/lwiperf/lwiperf.c
|
||||||
)
|
)
|
||||||
|
|
||||||
# due to warnings from other net source, we need to prevent error from some of the warnings options
|
# due to warnings from other net source, we need to prevent error from some of the warnings options
|
||||||
|
@ -63,6 +63,7 @@ SRC_C += \
|
|||||||
lib/lwip/src/netif/slipif.c \
|
lib/lwip/src/netif/slipif.c \
|
||||||
lib/lwip/src/apps/http/httpd.c \
|
lib/lwip/src/apps/http/httpd.c \
|
||||||
lib/lwip/src/apps/http/fs.c \
|
lib/lwip/src/apps/http/fs.c \
|
||||||
|
lib/lwip/src/apps/lwiperf/lwiperf.c \
|
||||||
lib/networking/dhserver.c \
|
lib/networking/dhserver.c \
|
||||||
lib/networking/dnserver.c \
|
lib/networking/dnserver.c \
|
||||||
lib/networking/rndis_reports.c
|
lib/networking/rndis_reports.c
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
mcu:LPC11UXX
|
mcu:LPC11UXX
|
||||||
mcu:LPC13XX
|
mcu:LPC13XX
|
||||||
|
mcu:LPC15XX
|
||||||
mcu:MSP430x5xx
|
mcu:MSP430x5xx
|
||||||
mcu:NUC121
|
mcu:NUC121
|
||||||
mcu:SAMD11
|
mcu:SAMD11
|
||||||
mcu:STM32L0
|
mcu:STM32L0
|
||||||
|
mcu:STM32F0
|
||||||
mcu:KINETIS_KL
|
mcu:KINETIS_KL
|
||||||
family:broadcom_64bit
|
family:broadcom_64bit
|
||||||
family:broadcom_32bit
|
family:broadcom_32bit
|
||||||
|
@ -48,8 +48,8 @@
|
|||||||
#define LWIP_IP_ACCEPT_UDP_PORT(p) ((p) == PP_NTOHS(67))
|
#define LWIP_IP_ACCEPT_UDP_PORT(p) ((p) == PP_NTOHS(67))
|
||||||
|
|
||||||
#define TCP_MSS (1500 /*mtu*/ - 20 /*iphdr*/ - 20 /*tcphhr*/)
|
#define TCP_MSS (1500 /*mtu*/ - 20 /*iphdr*/ - 20 /*tcphhr*/)
|
||||||
#define TCP_SND_BUF (2 * TCP_MSS)
|
#define TCP_SND_BUF (4 * TCP_MSS)
|
||||||
#define TCP_WND (TCP_MSS)
|
#define TCP_WND (4 * TCP_MSS)
|
||||||
|
|
||||||
#define ETHARP_SUPPORT_STATIC_ENTRIES 1
|
#define ETHARP_SUPPORT_STATIC_ENTRIES 1
|
||||||
|
|
||||||
@ -59,7 +59,7 @@
|
|||||||
|
|
||||||
#define LWIP_SINGLE_NETIF 1
|
#define LWIP_SINGLE_NETIF 1
|
||||||
|
|
||||||
#define PBUF_POOL_SIZE 2
|
#define PBUF_POOL_SIZE 4
|
||||||
|
|
||||||
#define HTTPD_USE_CUSTOM_FSDATA 0
|
#define HTTPD_USE_CUSTOM_FSDATA 0
|
||||||
|
|
||||||
|
@ -48,12 +48,17 @@ try changing the first byte of tud_network_mac_address[] below from 0x02 to 0x00
|
|||||||
|
|
||||||
#include "dhserver.h"
|
#include "dhserver.h"
|
||||||
#include "dnserver.h"
|
#include "dnserver.h"
|
||||||
|
#include "httpd.h"
|
||||||
|
#include "lwip/ethip6.h"
|
||||||
#include "lwip/init.h"
|
#include "lwip/init.h"
|
||||||
#include "lwip/timeouts.h"
|
#include "lwip/timeouts.h"
|
||||||
#include "lwip/ethip6.h"
|
|
||||||
#include "httpd.h"
|
|
||||||
|
|
||||||
#define INIT_IP4(a,b,c,d) { PP_HTONL(LWIP_MAKEU32(a,b,c,d)) }
|
#ifdef INCLUDE_IPERF
|
||||||
|
#include "lwip/apps/lwiperf.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define INIT_IP4(a, b, c, d) \
|
||||||
|
{ PP_HTONL(LWIP_MAKEU32(a, b, c, d)) }
|
||||||
|
|
||||||
/* lwip context */
|
/* lwip context */
|
||||||
static struct netif netif_data;
|
static struct netif netif_data;
|
||||||
@ -64,44 +69,40 @@ static struct pbuf *received_frame;
|
|||||||
/* this is used by this code, ./class/net/net_driver.c, and usb_descriptors.c */
|
/* this is used by this code, ./class/net/net_driver.c, and usb_descriptors.c */
|
||||||
/* ideally speaking, this should be generated from the hardware's unique ID (if available) */
|
/* ideally speaking, this should be generated from the hardware's unique ID (if available) */
|
||||||
/* it is suggested that the first byte is 0x02 to indicate a link-local address */
|
/* it is suggested that the first byte is 0x02 to indicate a link-local address */
|
||||||
uint8_t tud_network_mac_address[6] = {0x02,0x02,0x84,0x6A,0x96,0x00};
|
uint8_t tud_network_mac_address[6] = {0x02, 0x02, 0x84, 0x6A, 0x96, 0x00};
|
||||||
|
|
||||||
/* network parameters of this MCU */
|
/* network parameters of this MCU */
|
||||||
static const ip4_addr_t ipaddr = INIT_IP4(192, 168, 7, 1);
|
static const ip4_addr_t ipaddr = INIT_IP4(192, 168, 7, 1);
|
||||||
static const ip4_addr_t netmask = INIT_IP4(255, 255, 255, 0);
|
static const ip4_addr_t netmask = INIT_IP4(255, 255, 255, 0);
|
||||||
static const ip4_addr_t gateway = INIT_IP4(0, 0, 0, 0);
|
static const ip4_addr_t gateway = INIT_IP4(0, 0, 0, 0);
|
||||||
|
|
||||||
/* database IP addresses that can be offered to the host; this must be in RAM to store assigned MAC addresses */
|
/* database IP addresses that can be offered to the host; this must be in RAM to store assigned MAC addresses */
|
||||||
static dhcp_entry_t entries[] =
|
static dhcp_entry_t entries[] = {
|
||||||
{
|
/* mac ip address lease time */
|
||||||
/* mac ip address lease time */
|
{{0}, INIT_IP4(192, 168, 7, 2), 24 * 60 * 60},
|
||||||
{ {0}, INIT_IP4(192, 168, 7, 2), 24 * 60 * 60 },
|
{{0}, INIT_IP4(192, 168, 7, 3), 24 * 60 * 60},
|
||||||
{ {0}, INIT_IP4(192, 168, 7, 3), 24 * 60 * 60 },
|
{{0}, INIT_IP4(192, 168, 7, 4), 24 * 60 * 60},
|
||||||
{ {0}, INIT_IP4(192, 168, 7, 4), 24 * 60 * 60 },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const dhcp_config_t dhcp_config =
|
static const dhcp_config_t dhcp_config = {
|
||||||
{
|
.router = INIT_IP4(0, 0, 0, 0), /* router address (if any) */
|
||||||
.router = INIT_IP4(0, 0, 0, 0), /* router address (if any) */
|
.port = 67, /* listen port */
|
||||||
.port = 67, /* listen port */
|
.dns = INIT_IP4(192, 168, 7, 1), /* dns server (if any) */
|
||||||
.dns = INIT_IP4(192, 168, 7, 1), /* dns server (if any) */
|
"usb", /* dns suffix */
|
||||||
"usb", /* dns suffix */
|
TU_ARRAY_SIZE(entries), /* num entry */
|
||||||
TU_ARRAY_SIZE(entries), /* num entry */
|
entries /* entries */
|
||||||
entries /* entries */
|
|
||||||
};
|
};
|
||||||
static err_t linkoutput_fn(struct netif *netif, struct pbuf *p)
|
|
||||||
{
|
|
||||||
(void)netif;
|
|
||||||
|
|
||||||
for (;;)
|
static err_t linkoutput_fn(struct netif *netif, struct pbuf *p) {
|
||||||
{
|
(void) netif;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
/* if TinyUSB isn't ready, we must signal back to lwip that there is nothing we can do */
|
/* if TinyUSB isn't ready, we must signal back to lwip that there is nothing we can do */
|
||||||
if (!tud_ready())
|
if (!tud_ready())
|
||||||
return ERR_USE;
|
return ERR_USE;
|
||||||
|
|
||||||
/* if the network driver can accept another packet, we make it happen */
|
/* if the network driver can accept another packet, we make it happen */
|
||||||
if (tud_network_can_xmit(p->tot_len))
|
if (tud_network_can_xmit(p->tot_len)) {
|
||||||
{
|
|
||||||
tud_network_xmit(p, 0 /* unused for this example */);
|
tud_network_xmit(p, 0 /* unused for this example */);
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
@ -111,20 +112,17 @@ static err_t linkoutput_fn(struct netif *netif, struct pbuf *p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static err_t ip4_output_fn(struct netif *netif, struct pbuf *p, const ip4_addr_t *addr)
|
static err_t ip4_output_fn(struct netif *netif, struct pbuf *p, const ip4_addr_t *addr) {
|
||||||
{
|
|
||||||
return etharp_output(netif, p, addr);
|
return etharp_output(netif, p, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LWIP_IPV6
|
#if LWIP_IPV6
|
||||||
static err_t ip6_output_fn(struct netif *netif, struct pbuf *p, const ip6_addr_t *addr)
|
static err_t ip6_output_fn(struct netif *netif, struct pbuf *p, const ip6_addr_t *addr) {
|
||||||
{
|
|
||||||
return ethip6_output(netif, p, addr);
|
return ethip6_output(netif, p, addr);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static err_t netif_init_cb(struct netif *netif)
|
static err_t netif_init_cb(struct netif *netif) {
|
||||||
{
|
|
||||||
LWIP_ASSERT("netif != NULL", (netif != NULL));
|
LWIP_ASSERT("netif != NULL", (netif != NULL));
|
||||||
netif->mtu = CFG_TUD_NET_MTU;
|
netif->mtu = CFG_TUD_NET_MTU;
|
||||||
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP;
|
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP;
|
||||||
@ -139,8 +137,7 @@ static err_t netif_init_cb(struct netif *netif)
|
|||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_lwip(void)
|
static void init_lwip(void) {
|
||||||
{
|
|
||||||
struct netif *netif = &netif_data;
|
struct netif *netif = &netif_data;
|
||||||
|
|
||||||
lwip_init();
|
lwip_init();
|
||||||
@ -158,28 +155,23 @@ static void init_lwip(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* handle any DNS requests from dns-server */
|
/* handle any DNS requests from dns-server */
|
||||||
bool dns_query_proc(const char *name, ip4_addr_t *addr)
|
bool dns_query_proc(const char *name, ip4_addr_t *addr) {
|
||||||
{
|
if (0 == strcmp(name, "tiny.usb")) {
|
||||||
if (0 == strcmp(name, "tiny.usb"))
|
|
||||||
{
|
|
||||||
*addr = ipaddr;
|
*addr = ipaddr;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tud_network_recv_cb(const uint8_t *src, uint16_t size)
|
bool tud_network_recv_cb(const uint8_t *src, uint16_t size) {
|
||||||
{
|
|
||||||
/* this shouldn't happen, but if we get another packet before
|
/* this shouldn't happen, but if we get another packet before
|
||||||
parsing the previous, we must signal our inability to accept it */
|
parsing the previous, we must signal our inability to accept it */
|
||||||
if (received_frame) return false;
|
if (received_frame) return false;
|
||||||
|
|
||||||
if (size)
|
if (size) {
|
||||||
{
|
|
||||||
struct pbuf *p = pbuf_alloc(PBUF_RAW, size, PBUF_POOL);
|
struct pbuf *p = pbuf_alloc(PBUF_RAW, size, PBUF_POOL);
|
||||||
|
|
||||||
if (p)
|
if (p) {
|
||||||
{
|
|
||||||
/* pbuf_alloc() has already initialized struct; all we need to do is copy the data */
|
/* pbuf_alloc() has already initialized struct; all we need to do is copy the data */
|
||||||
memcpy(p->payload, src, size);
|
memcpy(p->payload, src, size);
|
||||||
|
|
||||||
@ -191,20 +183,17 @@ bool tud_network_recv_cb(const uint8_t *src, uint16_t size)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg)
|
uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg) {
|
||||||
{
|
struct pbuf *p = (struct pbuf *) ref;
|
||||||
struct pbuf *p = (struct pbuf *)ref;
|
|
||||||
|
|
||||||
(void)arg; /* unused for this example */
|
(void) arg; /* unused for this example */
|
||||||
|
|
||||||
return pbuf_copy_partial(p, dst, p->tot_len, 0);
|
return pbuf_copy_partial(p, dst, p->tot_len, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void service_traffic(void)
|
static void service_traffic(void) {
|
||||||
{
|
|
||||||
/* handle any packet received by tud_network_recv_cb() */
|
/* handle any packet received by tud_network_recv_cb() */
|
||||||
if (received_frame)
|
if (received_frame) {
|
||||||
{
|
|
||||||
ethernet_input(received_frame, &netif_data);
|
ethernet_input(received_frame, &netif_data);
|
||||||
pbuf_free(received_frame);
|
pbuf_free(received_frame);
|
||||||
received_frame = NULL;
|
received_frame = NULL;
|
||||||
@ -214,18 +203,15 @@ static void service_traffic(void)
|
|||||||
sys_check_timeouts();
|
sys_check_timeouts();
|
||||||
}
|
}
|
||||||
|
|
||||||
void tud_network_init_cb(void)
|
void tud_network_init_cb(void) {
|
||||||
{
|
|
||||||
/* if the network is re-initializing and we have a leftover packet, we must do a cleanup */
|
/* if the network is re-initializing and we have a leftover packet, we must do a cleanup */
|
||||||
if (received_frame)
|
if (received_frame) {
|
||||||
{
|
|
||||||
pbuf_free(received_frame);
|
pbuf_free(received_frame);
|
||||||
received_frame = NULL;
|
received_frame = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void) {
|
||||||
{
|
|
||||||
/* initialize TinyUSB */
|
/* initialize TinyUSB */
|
||||||
board_init();
|
board_init();
|
||||||
|
|
||||||
@ -243,8 +229,12 @@ int main(void)
|
|||||||
while (dnserv_init(IP_ADDR_ANY, 53, dns_query_proc) != ERR_OK);
|
while (dnserv_init(IP_ADDR_ANY, 53, dns_query_proc) != ERR_OK);
|
||||||
httpd_init();
|
httpd_init();
|
||||||
|
|
||||||
while (1)
|
#ifdef INCLUDE_IPERF
|
||||||
{
|
// test with: iperf -c 192.168.7.1 -e -i 1 -M 5000 -l 8192 -r
|
||||||
|
lwiperf_start_tcp_server_default(NULL, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while (1) {
|
||||||
tud_task();
|
tud_task();
|
||||||
service_traffic();
|
service_traffic();
|
||||||
}
|
}
|
||||||
@ -253,17 +243,14 @@ int main(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* lwip has provision for using a mutex, when applicable */
|
/* lwip has provision for using a mutex, when applicable */
|
||||||
sys_prot_t sys_arch_protect(void)
|
sys_prot_t sys_arch_protect(void) {
|
||||||
{
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
void sys_arch_unprotect(sys_prot_t pval)
|
void sys_arch_unprotect(sys_prot_t pval) {
|
||||||
{
|
(void) pval;
|
||||||
(void)pval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* lwip needs a millisecond time source, and the TinyUSB board support code has one available */
|
/* lwip needs a millisecond time source, and the TinyUSB board support code has one available */
|
||||||
uint32_t sys_now(void)
|
uint32_t sys_now(void) {
|
||||||
{
|
|
||||||
return board_millis();
|
return board_millis();
|
||||||
}
|
}
|
||||||
|
@ -27,21 +27,23 @@
|
|||||||
#define _TUSB_CONFIG_H_
|
#define _TUSB_CONFIG_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "lwipopts.h"
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Board Specific Configuration
|
// Board Specific Configuration
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
// RHPort number used for device can be defined by board.mk, default to port 0
|
// RHPort number used for device can be defined by board.mk, default to port 0
|
||||||
#ifndef BOARD_TUD_RHPORT
|
#ifndef BOARD_TUD_RHPORT
|
||||||
#define BOARD_TUD_RHPORT 0
|
#define BOARD_TUD_RHPORT 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// RHPort max operational speed can defined by board.mk
|
// RHPort max operational speed can defined by board.mk
|
||||||
#ifndef BOARD_TUD_MAX_SPEED
|
#ifndef BOARD_TUD_MAX_SPEED
|
||||||
#define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED
|
#define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
@ -50,22 +52,22 @@
|
|||||||
|
|
||||||
// defined by compiler flags for flexibility
|
// defined by compiler flags for flexibility
|
||||||
#ifndef CFG_TUSB_MCU
|
#ifndef CFG_TUSB_MCU
|
||||||
#error CFG_TUSB_MCU must be defined
|
#error CFG_TUSB_MCU must be defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CFG_TUSB_OS
|
#ifndef CFG_TUSB_OS
|
||||||
#define CFG_TUSB_OS OPT_OS_NONE
|
#define CFG_TUSB_OS OPT_OS_NONE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CFG_TUSB_DEBUG
|
#ifndef CFG_TUSB_DEBUG
|
||||||
#define CFG_TUSB_DEBUG 0
|
#define CFG_TUSB_DEBUG 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Enable Device stack
|
// Enable Device stack
|
||||||
#define CFG_TUD_ENABLED 1
|
#define CFG_TUD_ENABLED 1
|
||||||
|
|
||||||
// Default is max speed that hardware controller could support with on-chip PHY
|
// Default is max speed that hardware controller could support with on-chip PHY
|
||||||
#define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED
|
#define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED
|
||||||
|
|
||||||
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
|
/* 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
|
* Tinyusb use follows macros to declare transferring memory so that they can be put
|
||||||
@ -75,11 +77,45 @@
|
|||||||
* - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4)))
|
* - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4)))
|
||||||
*/
|
*/
|
||||||
#ifndef CFG_TUSB_MEM_SECTION
|
#ifndef CFG_TUSB_MEM_SECTION
|
||||||
#define CFG_TUSB_MEM_SECTION
|
#define CFG_TUSB_MEM_SECTION
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CFG_TUSB_MEM_ALIGN
|
#ifndef CFG_TUSB_MEM_ALIGN
|
||||||
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
|
#define CFG_TUSB_MEM_ALIGN __attribute__((aligned(4)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Use different configurations to test all net devices (also due to resource limitations)
|
||||||
|
#if TU_CHECK_MCU(OPT_MCU_LPC15XX, OPT_MCU_LPC40XX, OPT_MCU_LPC51UXX, OPT_MCU_LPC54)
|
||||||
|
#define USE_ECM 1
|
||||||
|
#elif TU_CHECK_MCU(OPT_MCU_SAMD21, OPT_MCU_SAML21, OPT_MCU_SAML22)
|
||||||
|
#define USE_ECM 1
|
||||||
|
#elif TU_CHECK_MCU(OPT_MCU_STM32F0, OPT_MCU_STM32F1)
|
||||||
|
#define USE_ECM 1
|
||||||
|
#else
|
||||||
|
#define USE_ECM 0
|
||||||
|
#define INCLUDE_IPERF
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// NCM CLASS CONFIGURATION, SEE "ncm.h" FOR PERFORMANCE TUNING
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Must be >> MTU
|
||||||
|
// Can be set to 2048 without impact
|
||||||
|
#define CFG_TUD_NCM_IN_NTB_MAX_SIZE (2 * TCP_MSS + 100)
|
||||||
|
|
||||||
|
// Must be >> MTU
|
||||||
|
// Can be set to smaller values if wNtbOutMaxDatagrams==1
|
||||||
|
#define CFG_TUD_NCM_OUT_NTB_MAX_SIZE (2 * TCP_MSS + 100)
|
||||||
|
|
||||||
|
// Number of NCM transfer blocks for reception side
|
||||||
|
#ifndef CFG_TUD_NCM_OUT_NTB_N
|
||||||
|
#define CFG_TUD_NCM_OUT_NTB_N 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Number of NCM transfer blocks for transmission side
|
||||||
|
#ifndef CFG_TUD_NCM_IN_NTB_N
|
||||||
|
#define CFG_TUD_NCM_IN_NTB_N 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
@ -87,18 +123,18 @@
|
|||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
#ifndef CFG_TUD_ENDPOINT0_SIZE
|
#ifndef CFG_TUD_ENDPOINT0_SIZE
|
||||||
#define CFG_TUD_ENDPOINT0_SIZE 64
|
#define CFG_TUD_ENDPOINT0_SIZE 64
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//------------- CLASS -------------//
|
//------------- CLASS -------------//
|
||||||
|
|
||||||
// Network class has 2 drivers: ECM/RNDIS and NCM.
|
// Network class has 2 drivers: ECM/RNDIS and NCM.
|
||||||
// Only one of the drivers can be enabled
|
// Only one of the drivers can be enabled
|
||||||
#define CFG_TUD_ECM_RNDIS 1
|
#define CFG_TUD_ECM_RNDIS USE_ECM
|
||||||
#define CFG_TUD_NCM (1-CFG_TUD_ECM_RNDIS)
|
#define CFG_TUD_NCM (1 - CFG_TUD_ECM_RNDIS)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _TUSB_CONFIG_H_ */
|
#endif /* _TUSB_CONFIG_H_ */
|
||||||
|
@ -3,6 +3,7 @@ mcu:NUC121
|
|||||||
mcu:SAMD11
|
mcu:SAMD11
|
||||||
mcu:GD32VF103
|
mcu:GD32VF103
|
||||||
mcu:CH32V307
|
mcu:CH32V307
|
||||||
|
mcu:STM32L0
|
||||||
family:espressif
|
family:espressif
|
||||||
board:curiosity_nano
|
board:curiosity_nano
|
||||||
board:kuiic
|
board:kuiic
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
set(CMAKE_SYSTEM_PROCESSOR arm1176jzf-s CACHE INTERNAL "System Processor")
|
||||||
|
#set(SUFFIX "")
|
||||||
|
|
||||||
|
function(update_board TARGET)
|
||||||
|
target_compile_definitions(${TARGET} PUBLIC
|
||||||
|
BCM_VERSION=2835
|
||||||
|
)
|
||||||
|
endfunction()
|
@ -1,4 +1,4 @@
|
|||||||
CPU_CORE = arm1176
|
CPU_CORE = arm1176jzf-s
|
||||||
CFLAGS += -DBCM_VERSION=2835 \
|
CFLAGS += -DBCM_VERSION=2835 \
|
||||||
-DCFG_TUSB_MCU=OPT_MCU_BCM2835
|
-DCFG_TUSB_MCU=OPT_MCU_BCM2835
|
||||||
|
|
@ -27,6 +27,13 @@
|
|||||||
#include "bsp/board_api.h"
|
#include "bsp/board_api.h"
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
|
|
||||||
|
// Suppress warning caused by mcu driver
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wcast-qual"
|
||||||
|
#pragma GCC diagnostic ignored "-Wredundant-decls"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "broadcom/cpu.h"
|
#include "broadcom/cpu.h"
|
||||||
#include "broadcom/gpio.h"
|
#include "broadcom/gpio.h"
|
||||||
#include "broadcom/interrupts.h"
|
#include "broadcom/interrupts.h"
|
||||||
@ -34,6 +41,10 @@
|
|||||||
#include "broadcom/caches.h"
|
#include "broadcom/caches.h"
|
||||||
#include "broadcom/vcmailbox.h"
|
#include "broadcom/vcmailbox.h"
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
// LED
|
// LED
|
||||||
#define LED_PIN 18
|
#define LED_PIN 18
|
||||||
#define LED_STATE_ON 1
|
#define LED_STATE_ON 1
|
||||||
@ -44,8 +55,7 @@
|
|||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Forward USB interrupt events to TinyUSB IRQ Handler
|
// Forward USB interrupt events to TinyUSB IRQ Handler
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
void USB_IRQHandler(void)
|
void USB_IRQHandler(void) {
|
||||||
{
|
|
||||||
tud_int_handler(0);
|
tud_int_handler(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,8 +66,7 @@ void USB_IRQHandler(void)
|
|||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Board porting API
|
// Board porting API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
void board_init(void)
|
void board_init(void) {
|
||||||
{
|
|
||||||
setup_mmu_flat_map();
|
setup_mmu_flat_map();
|
||||||
init_caches();
|
init_caches();
|
||||||
|
|
||||||
@ -97,24 +106,21 @@ void board_init(void)
|
|||||||
BP_EnableIRQs();
|
BP_EnableIRQs();
|
||||||
}
|
}
|
||||||
|
|
||||||
void board_led_write(bool state)
|
void board_led_write(bool state) {
|
||||||
{
|
gpio_set_value(LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON));
|
||||||
gpio_set_value(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t board_button_read(void)
|
uint32_t board_button_read(void) {
|
||||||
{
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int board_uart_read(uint8_t* buf, int len)
|
int board_uart_read(uint8_t* buf, int len) {
|
||||||
{
|
(void) buf;
|
||||||
(void) buf; (void) len;
|
(void) len;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int board_uart_write(void const * buf, int len)
|
int board_uart_write(void const* buf, int len) {
|
||||||
{
|
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
const char* cbuf = buf;
|
const char* cbuf = buf;
|
||||||
while (!UART1->STAT_b.TX_READY) {}
|
while (!UART1->STAT_b.TX_READY) {}
|
||||||
@ -127,30 +133,27 @@ int board_uart_write(void const * buf, int len)
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
volatile uint32_t system_ticks = 0;
|
volatile uint32_t system_ticks = 0;
|
||||||
|
|
||||||
void TIMER_1_IRQHandler(void)
|
void TIMER_1_IRQHandler(void) {
|
||||||
{
|
|
||||||
system_ticks++;
|
system_ticks++;
|
||||||
SYSTMR->C1 += 977;
|
SYSTMR->C1 += 977;
|
||||||
SYSTMR->CS_b.M1 = 1;
|
SYSTMR->CS_b.M1 = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t board_millis(void)
|
uint32_t board_millis(void) {
|
||||||
{
|
|
||||||
return system_ticks;
|
return system_ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void HardFault_Handler (void)
|
void HardFault_Handler(void) {
|
||||||
{
|
|
||||||
// asm("bkpt");
|
// asm("bkpt");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Required by __libc_init_array in startup code if we are compiling using
|
// Required by __libc_init_array in startup code if we are compiling using
|
||||||
// -nostdlib/-nostartfiles.
|
// -nostdlib/-nostartfiles.
|
||||||
void _init(void)
|
void _init(void) {
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
108
hw/bsp/broadcom_32bit/family.cmake
Normal file
108
hw/bsp/broadcom_32bit/family.cmake
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
include_guard()
|
||||||
|
|
||||||
|
set(SDK_DIR ${TOP}/hw/mcu/broadcom)
|
||||||
|
|
||||||
|
# include board specific
|
||||||
|
include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake)
|
||||||
|
|
||||||
|
# toolchain set up
|
||||||
|
set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake)
|
||||||
|
|
||||||
|
set(FAMILY_MCUS BCM2835 CACHE INTERNAL "")
|
||||||
|
|
||||||
|
|
||||||
|
#------------------------------------
|
||||||
|
# BOARD_TARGET
|
||||||
|
#------------------------------------
|
||||||
|
# only need to be built ONCE for all examples
|
||||||
|
function(add_board_target BOARD_TARGET)
|
||||||
|
if (TARGET ${BOARD_TARGET})
|
||||||
|
return()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (NOT DEFINED LD_FILE_GNU)
|
||||||
|
set(LD_FILE_GNU ${SDK_DIR}/broadcom/link.ld)
|
||||||
|
endif ()
|
||||||
|
set(LD_FILE_Clang ${LD_FILE_GNU})
|
||||||
|
|
||||||
|
set(STARTUP_FILE_GNU ${SDK_DIR}/broadcom/boot.s)
|
||||||
|
set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU})
|
||||||
|
|
||||||
|
add_library(${BOARD_TARGET} STATIC
|
||||||
|
${SDK_DIR}/broadcom/gen/interrupt_handlers.c
|
||||||
|
${SDK_DIR}/broadcom/gpio.c
|
||||||
|
${SDK_DIR}/broadcom/interrupts.c
|
||||||
|
${SDK_DIR}/broadcom/mmu.c
|
||||||
|
${SDK_DIR}/broadcom/caches.c
|
||||||
|
${SDK_DIR}/broadcom/vcmailbox.c
|
||||||
|
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||||
|
)
|
||||||
|
target_compile_options(${BOARD_TARGET} PUBLIC
|
||||||
|
-O0
|
||||||
|
-ffreestanding
|
||||||
|
-mgeneral-regs-only
|
||||||
|
-fno-exceptions
|
||||||
|
-std=c17
|
||||||
|
)
|
||||||
|
target_include_directories(${BOARD_TARGET} PUBLIC
|
||||||
|
${SDK_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
update_board(${BOARD_TARGET})
|
||||||
|
|
||||||
|
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||||
|
target_link_options(${BOARD_TARGET} PUBLIC
|
||||||
|
"LINKER:--script=${LD_FILE_GNU}"
|
||||||
|
"LINKER:--entry=_start"
|
||||||
|
--specs=nosys.specs
|
||||||
|
-nostartfiles
|
||||||
|
)
|
||||||
|
elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||||
|
target_link_options(${BOARD_TARGET} PUBLIC
|
||||||
|
"LINKER:--script=${LD_FILE_Clang}"
|
||||||
|
"LINKER:--entry=_start"
|
||||||
|
)
|
||||||
|
elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR")
|
||||||
|
target_link_options(${BOARD_TARGET} PUBLIC
|
||||||
|
"LINKER:--config=${LD_FILE_IAR}"
|
||||||
|
)
|
||||||
|
endif ()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
|
||||||
|
#------------------------------------
|
||||||
|
# Functions
|
||||||
|
#------------------------------------
|
||||||
|
function(family_configure_example TARGET RTOS)
|
||||||
|
family_configure_common(${TARGET} ${RTOS})
|
||||||
|
|
||||||
|
# Board target
|
||||||
|
add_board_target(board_${BOARD})
|
||||||
|
|
||||||
|
#---------- Port Specific ----------
|
||||||
|
# These files are built for each example since it depends on example's tusb_config.h
|
||||||
|
target_sources(${TARGET} PUBLIC
|
||||||
|
# BSP
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
||||||
|
)
|
||||||
|
target_include_directories(${TARGET} PUBLIC
|
||||||
|
# family, hw, board
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add TinyUSB target and port source
|
||||||
|
family_add_tinyusb(${TARGET} OPT_MCU_BCM2835 ${RTOS})
|
||||||
|
target_sources(${TARGET}-tinyusb PUBLIC
|
||||||
|
${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c
|
||||||
|
)
|
||||||
|
target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD})
|
||||||
|
|
||||||
|
# Link dependencies
|
||||||
|
target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb)
|
||||||
|
|
||||||
|
# Flashing
|
||||||
|
family_flash_jlink(${TARGET})
|
||||||
|
endfunction()
|
@ -1,5 +1,4 @@
|
|||||||
MCU_DIR = hw/mcu/broadcom
|
MCU_DIR = hw/mcu/broadcom
|
||||||
DEPS_SUBMODULES += $(MCU_DIR)
|
|
||||||
|
|
||||||
include $(TOP)/$(BOARD_PATH)/board.mk
|
include $(TOP)/$(BOARD_PATH)/board.mk
|
||||||
|
|
||||||
@ -27,15 +26,13 @@ SRC_C += \
|
|||||||
$(MCU_DIR)/broadcom/caches.c \
|
$(MCU_DIR)/broadcom/caches.c \
|
||||||
$(MCU_DIR)/broadcom/vcmailbox.c
|
$(MCU_DIR)/broadcom/vcmailbox.c
|
||||||
|
|
||||||
SKIP_NANOLIB = 1
|
|
||||||
|
|
||||||
LD_FILE = $(MCU_DIR)/broadcom/link$(SUFFIX).ld
|
LD_FILE = $(MCU_DIR)/broadcom/link$(SUFFIX).ld
|
||||||
|
|
||||||
INC += \
|
INC += \
|
||||||
$(TOP)/$(BOARD_PATH) \
|
$(TOP)/$(BOARD_PATH) \
|
||||||
$(TOP)/$(MCU_DIR)
|
$(TOP)/$(MCU_DIR)
|
||||||
|
|
||||||
SRC_S += $(MCU_DIR)/broadcom/boot$(SUFFIX).S
|
SRC_S += $(MCU_DIR)/broadcom/boot$(SUFFIX).s
|
||||||
|
|
||||||
$(BUILD)/kernel$(SUFFIX).img: $(BUILD)/$(PROJECT).elf
|
$(BUILD)/kernel$(SUFFIX).img: $(BUILD)/$(PROJECT).elf
|
||||||
$(OBJCOPY) -O binary $^ $@
|
$(OBJCOPY) -O binary $^ $@
|
||||||
|
5
hw/bsp/broadcom_64bit/boards/raspberrypi_cm4/board.cmake
Normal file
5
hw/bsp/broadcom_64bit/boards/raspberrypi_cm4/board.cmake
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
set(CMAKE_SYSTEM_PROCESSOR cortex-a72 CACHE INTERNAL "System Processor")
|
||||||
|
set(BCM_VERSION 2711)
|
||||||
|
|
||||||
|
function(update_board TARGET)
|
||||||
|
endfunction()
|
@ -0,0 +1,5 @@
|
|||||||
|
set(CMAKE_SYSTEM_PROCESSOR cortex-a53 CACHE INTERNAL "System Processor")
|
||||||
|
set(BCM_VERSION 2837)
|
||||||
|
|
||||||
|
function(update_board TARGET)
|
||||||
|
endfunction()
|
@ -27,6 +27,13 @@
|
|||||||
#include "bsp/board_api.h"
|
#include "bsp/board_api.h"
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
|
|
||||||
|
// Suppress warning caused by mcu driver
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wcast-qual"
|
||||||
|
#pragma GCC diagnostic ignored "-Wredundant-decls"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "broadcom/cpu.h"
|
#include "broadcom/cpu.h"
|
||||||
#include "broadcom/gpio.h"
|
#include "broadcom/gpio.h"
|
||||||
#include "broadcom/interrupts.h"
|
#include "broadcom/interrupts.h"
|
||||||
@ -34,6 +41,10 @@
|
|||||||
#include "broadcom/caches.h"
|
#include "broadcom/caches.h"
|
||||||
#include "broadcom/vcmailbox.h"
|
#include "broadcom/vcmailbox.h"
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
// LED
|
// LED
|
||||||
#define LED_PIN 18
|
#define LED_PIN 18
|
||||||
#define LED_STATE_ON 1
|
#define LED_STATE_ON 1
|
||||||
@ -44,8 +55,7 @@
|
|||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Forward USB interrupt events to TinyUSB IRQ Handler
|
// Forward USB interrupt events to TinyUSB IRQ Handler
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
void USB_IRQHandler(void)
|
void USB_IRQHandler(void) {
|
||||||
{
|
|
||||||
tud_int_handler(0);
|
tud_int_handler(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,8 +66,7 @@ void USB_IRQHandler(void)
|
|||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Board porting API
|
// Board porting API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
void board_init(void)
|
void board_init(void) {
|
||||||
{
|
|
||||||
setup_mmu_flat_map();
|
setup_mmu_flat_map();
|
||||||
init_caches();
|
init_caches();
|
||||||
|
|
||||||
@ -97,24 +106,21 @@ void board_init(void)
|
|||||||
BP_EnableIRQs();
|
BP_EnableIRQs();
|
||||||
}
|
}
|
||||||
|
|
||||||
void board_led_write(bool state)
|
void board_led_write(bool state) {
|
||||||
{
|
gpio_set_value(LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON));
|
||||||
gpio_set_value(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t board_button_read(void)
|
uint32_t board_button_read(void) {
|
||||||
{
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int board_uart_read(uint8_t* buf, int len)
|
int board_uart_read(uint8_t* buf, int len) {
|
||||||
{
|
(void) buf;
|
||||||
(void) buf; (void) len;
|
(void) len;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int board_uart_write(void const * buf, int len)
|
int board_uart_write(void const* buf, int len) {
|
||||||
{
|
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
const char* cbuf = buf;
|
const char* cbuf = buf;
|
||||||
while (!UART1->STAT_b.TX_READY) {}
|
while (!UART1->STAT_b.TX_READY) {}
|
||||||
@ -127,30 +133,27 @@ int board_uart_write(void const * buf, int len)
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
volatile uint32_t system_ticks = 0;
|
volatile uint32_t system_ticks = 0;
|
||||||
|
|
||||||
void TIMER_1_IRQHandler(void)
|
void TIMER_1_IRQHandler(void) {
|
||||||
{
|
|
||||||
system_ticks++;
|
system_ticks++;
|
||||||
SYSTMR->C1 += 977;
|
SYSTMR->C1 += 977;
|
||||||
SYSTMR->CS_b.M1 = 1;
|
SYSTMR->CS_b.M1 = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t board_millis(void)
|
uint32_t board_millis(void) {
|
||||||
{
|
|
||||||
return system_ticks;
|
return system_ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void HardFault_Handler (void)
|
void HardFault_Handler(void) {
|
||||||
{
|
|
||||||
// asm("bkpt");
|
// asm("bkpt");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Required by __libc_init_array in startup code if we are compiling using
|
// Required by __libc_init_array in startup code if we are compiling using
|
||||||
// -nostdlib/-nostartfiles.
|
// -nostdlib/-nostartfiles.
|
||||||
void _init(void)
|
void _init(void) {
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
115
hw/bsp/broadcom_64bit/family.cmake
Normal file
115
hw/bsp/broadcom_64bit/family.cmake
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
include_guard()
|
||||||
|
|
||||||
|
set(SDK_DIR ${TOP}/hw/mcu/broadcom)
|
||||||
|
set(CMSIS_5 ${TOP}/lib/CMSIS_5)
|
||||||
|
|
||||||
|
# include board specific
|
||||||
|
include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake)
|
||||||
|
|
||||||
|
# toolchain set up
|
||||||
|
set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/aarch64_${TOOLCHAIN}.cmake)
|
||||||
|
|
||||||
|
set(FAMILY_MCUS BCM2711 BCM2835 CACHE INTERNAL "")
|
||||||
|
|
||||||
|
|
||||||
|
#------------------------------------
|
||||||
|
# BOARD_TARGET
|
||||||
|
#------------------------------------
|
||||||
|
# only need to be built ONCE for all examples
|
||||||
|
function(add_board_target BOARD_TARGET)
|
||||||
|
if (TARGET ${BOARD_TARGET})
|
||||||
|
return()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (NOT DEFINED LD_FILE_GNU)
|
||||||
|
set(LD_FILE_GNU ${SDK_DIR}/broadcom/link8.ld)
|
||||||
|
endif ()
|
||||||
|
set(LD_FILE_Clang ${LD_FILE_GNU})
|
||||||
|
|
||||||
|
set(STARTUP_FILE_GNU ${SDK_DIR}/broadcom/boot8.s)
|
||||||
|
set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU})
|
||||||
|
|
||||||
|
add_library(${BOARD_TARGET} STATIC
|
||||||
|
${SDK_DIR}/broadcom/gen/interrupt_handlers.c
|
||||||
|
${SDK_DIR}/broadcom/gpio.c
|
||||||
|
${SDK_DIR}/broadcom/interrupts.c
|
||||||
|
${SDK_DIR}/broadcom/mmu.c
|
||||||
|
${SDK_DIR}/broadcom/caches.c
|
||||||
|
${SDK_DIR}/broadcom/vcmailbox.c
|
||||||
|
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||||
|
)
|
||||||
|
target_compile_options(${BOARD_TARGET} PUBLIC
|
||||||
|
-O0
|
||||||
|
-ffreestanding
|
||||||
|
-mgeneral-regs-only
|
||||||
|
-fno-exceptions
|
||||||
|
-std=c17
|
||||||
|
)
|
||||||
|
target_compile_definitions(${BOARD_TARGET} PUBLIC
|
||||||
|
BCM_VERSION=${BCM_VERSION}
|
||||||
|
)
|
||||||
|
target_include_directories(${BOARD_TARGET} PUBLIC
|
||||||
|
${SDK_DIR}
|
||||||
|
${CMSIS_5}/CMSIS/Core_A/Include
|
||||||
|
)
|
||||||
|
|
||||||
|
update_board(${BOARD_TARGET})
|
||||||
|
|
||||||
|
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||||
|
# target_compile_options(${BOARD_TARGET} PUBLIC
|
||||||
|
# )
|
||||||
|
target_link_options(${BOARD_TARGET} PUBLIC
|
||||||
|
"LINKER:--script=${LD_FILE_GNU}"
|
||||||
|
"LINKER:--entry=_start"
|
||||||
|
--specs=nosys.specs
|
||||||
|
-nostartfiles
|
||||||
|
)
|
||||||
|
elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||||
|
target_link_options(${BOARD_TARGET} PUBLIC
|
||||||
|
"LINKER:--script=${LD_FILE_Clang}"
|
||||||
|
"LINKER:--entry=_start"
|
||||||
|
)
|
||||||
|
elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR")
|
||||||
|
target_link_options(${BOARD_TARGET} PUBLIC
|
||||||
|
"LINKER:--config=${LD_FILE_IAR}"
|
||||||
|
)
|
||||||
|
endif ()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
|
||||||
|
#------------------------------------
|
||||||
|
# Functions
|
||||||
|
#------------------------------------
|
||||||
|
function(family_configure_example TARGET RTOS)
|
||||||
|
family_configure_common(${TARGET} ${RTOS})
|
||||||
|
|
||||||
|
# Board target
|
||||||
|
add_board_target(board_${BOARD})
|
||||||
|
|
||||||
|
#---------- Port Specific ----------
|
||||||
|
# These files are built for each example since it depends on example's tusb_config.h
|
||||||
|
target_sources(${TARGET} PUBLIC
|
||||||
|
# BSP
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
||||||
|
)
|
||||||
|
target_include_directories(${TARGET} PUBLIC
|
||||||
|
# family, hw, board
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add TinyUSB target and port source
|
||||||
|
family_add_tinyusb(${TARGET} OPT_MCU_BCM${BCM_VERSION} ${RTOS})
|
||||||
|
target_sources(${TARGET}-tinyusb PUBLIC
|
||||||
|
${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c
|
||||||
|
)
|
||||||
|
target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD})
|
||||||
|
|
||||||
|
# Link dependencies
|
||||||
|
target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb)
|
||||||
|
|
||||||
|
# Flashing
|
||||||
|
family_flash_jlink(${TARGET})
|
||||||
|
endfunction()
|
@ -1,6 +1,4 @@
|
|||||||
MCU_DIR = hw/mcu/broadcom
|
MCU_DIR = hw/mcu/broadcom
|
||||||
DEPS_SUBMODULES += $(MCU_DIR)
|
|
||||||
|
|
||||||
include $(TOP)/$(BOARD_PATH)/board.mk
|
include $(TOP)/$(BOARD_PATH)/board.mk
|
||||||
|
|
||||||
CFLAGS += \
|
CFLAGS += \
|
||||||
@ -9,6 +7,7 @@ CFLAGS += \
|
|||||||
-ffreestanding \
|
-ffreestanding \
|
||||||
-nostdlib \
|
-nostdlib \
|
||||||
-nostartfiles \
|
-nostartfiles \
|
||||||
|
--specs=nosys.specs \
|
||||||
-mgeneral-regs-only \
|
-mgeneral-regs-only \
|
||||||
-std=c17
|
-std=c17
|
||||||
|
|
||||||
@ -26,8 +25,6 @@ SRC_C += \
|
|||||||
$(MCU_DIR)/broadcom/caches.c \
|
$(MCU_DIR)/broadcom/caches.c \
|
||||||
$(MCU_DIR)/broadcom/vcmailbox.c
|
$(MCU_DIR)/broadcom/vcmailbox.c
|
||||||
|
|
||||||
SKIP_NANOLIB = 1
|
|
||||||
|
|
||||||
LD_FILE = $(MCU_DIR)/broadcom/link8.ld
|
LD_FILE = $(MCU_DIR)/broadcom/link8.ld
|
||||||
|
|
||||||
INC += \
|
INC += \
|
||||||
@ -35,7 +32,7 @@ INC += \
|
|||||||
$(TOP)/$(MCU_DIR) \
|
$(TOP)/$(MCU_DIR) \
|
||||||
$(TOP)/lib/CMSIS_5/CMSIS/Core_A/Include
|
$(TOP)/lib/CMSIS_5/CMSIS/Core_A/Include
|
||||||
|
|
||||||
SRC_S += $(MCU_DIR)/broadcom/boot8.S
|
SRC_S += $(MCU_DIR)/broadcom/boot8.s
|
||||||
|
|
||||||
$(BUILD)/kernel8.img: $(BUILD)/$(PROJECT).elf
|
$(BUILD)/kernel8.img: $(BUILD)/$(PROJECT).elf
|
||||||
$(OBJCOPY) -O binary $^ $@
|
$(OBJCOPY) -O binary $^ $@
|
||||||
|
@ -1 +0,0 @@
|
|||||||
// Nothing valuable here
|
|
@ -1,52 +0,0 @@
|
|||||||
MCU_DIR = hw/mcu/allwinner/f1c100s
|
|
||||||
DEPS_SUBMODULES += hw/mcu/allwinner
|
|
||||||
DEFINES += -D__ARM32_ARCH__=5 -D__ARM926EJS__
|
|
||||||
|
|
||||||
CFLAGS += \
|
|
||||||
-ffreestanding \
|
|
||||||
-std=gnu99 \
|
|
||||||
-march=armv5te \
|
|
||||||
-mtune=arm926ej-s \
|
|
||||||
-mfloat-abi=soft \
|
|
||||||
-marm \
|
|
||||||
-mno-thumb-interwork \
|
|
||||||
-Wno-unused-parameter \
|
|
||||||
-Wno-float-equal \
|
|
||||||
-DCFG_TUSB_MCU=OPT_MCU_F1C100S \
|
|
||||||
-Wno-error=cast-align \
|
|
||||||
-Wno-error=address-of-packed-member \
|
|
||||||
$(DEFINES)
|
|
||||||
|
|
||||||
LD_FILE = hw/mcu/allwinner/f1c100s/f1c100s.ld
|
|
||||||
# TODO may skip nanolib
|
|
||||||
LDFLAGS += -nostdlib -lgcc -specs=nosys.specs -specs=nano.specs
|
|
||||||
|
|
||||||
SRC_C += \
|
|
||||||
src/portable/sunxi/dcd_sunxi_musb.c \
|
|
||||||
$(MCU_DIR)/machine/sys-uart.c \
|
|
||||||
$(MCU_DIR)/machine/exception.c \
|
|
||||||
$(MCU_DIR)/machine/sys-clock.c \
|
|
||||||
$(MCU_DIR)/machine/sys-copyself.c \
|
|
||||||
$(MCU_DIR)/machine/sys-dram.c \
|
|
||||||
$(MCU_DIR)/machine/sys-mmu.c \
|
|
||||||
$(MCU_DIR)/machine/sys-spi-flash.c \
|
|
||||||
$(MCU_DIR)/machine/f1c100s-intc.c \
|
|
||||||
$(MCU_DIR)/lib/malloc.c \
|
|
||||||
$(MCU_DIR)/lib/printf.c
|
|
||||||
|
|
||||||
SRC_S += \
|
|
||||||
$(MCU_DIR)/machine/start.S \
|
|
||||||
$(MCU_DIR)/lib/memcpy.S \
|
|
||||||
$(MCU_DIR)/lib/memset.S
|
|
||||||
|
|
||||||
INC += \
|
|
||||||
$(TOP)/$(MCU_DIR)/include \
|
|
||||||
$(TOP)/$(BOARD_PATH)
|
|
||||||
|
|
||||||
# flash target using xfel
|
|
||||||
flash: flash-xfel
|
|
||||||
|
|
||||||
exec: $(BUILD)/$(PROJECT).bin
|
|
||||||
xfel ddr
|
|
||||||
xfel write 0x80000000 $<
|
|
||||||
xfel exec 0x80000000
|
|
3
hw/bsp/f1c100s/boards/f1c100s/board.cmake
Normal file
3
hw/bsp/f1c100s/boards/f1c100s/board.cmake
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
function(update_board TARGET)
|
||||||
|
# nothing to do
|
||||||
|
endfunction()
|
6
hw/bsp/f1c100s/boards/f1c100s/board.h
Normal file
6
hw/bsp/f1c100s/boards/f1c100s/board.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef BOARD_H
|
||||||
|
#define BOARD_H
|
||||||
|
|
||||||
|
// Nothing valuable here
|
||||||
|
|
||||||
|
#endif
|
1
hw/bsp/f1c100s/boards/f1c100s/board.mk
Normal file
1
hw/bsp/f1c100s/boards/f1c100s/board.mk
Normal file
@ -0,0 +1 @@
|
|||||||
|
# nothing to do
|
@ -39,10 +39,9 @@ extern void sys_uart_putc(char c);
|
|||||||
|
|
||||||
static void timer_init(void);
|
static void timer_init(void);
|
||||||
|
|
||||||
void board_init(void)
|
void board_init(void) {
|
||||||
{
|
|
||||||
arch_local_irq_disable();
|
arch_local_irq_disable();
|
||||||
do_init_mem_pool();
|
do_init_mem_pool();
|
||||||
f1c100s_intc_init();
|
f1c100s_intc_init();
|
||||||
timer_init();
|
timer_init();
|
||||||
printf("Timer INIT done\n");
|
printf("Timer INIT done\n");
|
||||||
@ -50,42 +49,38 @@ void board_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// No LED, no button
|
// No LED, no button
|
||||||
void board_led_write(bool state)
|
void board_led_write(bool state) {
|
||||||
{
|
(void) state;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t board_button_read(void)
|
uint32_t board_button_read(void) {
|
||||||
{
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int board_uart_read(uint8_t* buf, int len)
|
int board_uart_read(uint8_t* buf, int len) {
|
||||||
{
|
(void) buf;
|
||||||
|
(void) len;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int board_uart_write(void const * buf, int len)
|
int board_uart_write(void const* buf, int len) {
|
||||||
{
|
|
||||||
int txsize = len;
|
int txsize = len;
|
||||||
while (txsize--) {
|
while (txsize--) {
|
||||||
sys_uart_putc(*(uint8_t const*)buf);
|
sys_uart_putc(*(uint8_t const*) buf);
|
||||||
buf++;
|
buf++;
|
||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
volatile uint32_t system_ticks = 0;
|
volatile uint32_t system_ticks = 0;
|
||||||
|
|
||||||
uint32_t board_millis(void)
|
uint32_t board_millis(void) {
|
||||||
{
|
|
||||||
return system_ticks;
|
return system_ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void timer_handler(void)
|
static void timer_handler(void) {
|
||||||
{
|
volatile uint32_t* temp_addr = (uint32_t*) (0x01C20C00 + 0x04);
|
||||||
volatile uint32_t *temp_addr = (uint32_t *)(0x01C20C00 + 0x04);
|
|
||||||
|
|
||||||
/* clear timer */
|
/* clear timer */
|
||||||
*temp_addr |= 0x01;
|
*temp_addr |= 0x01;
|
||||||
@ -95,36 +90,37 @@ static void timer_handler(void)
|
|||||||
|
|
||||||
static void timer_init(void) {
|
static void timer_init(void) {
|
||||||
uint32_t temp;
|
uint32_t temp;
|
||||||
volatile uint32_t *temp_addr;
|
volatile uint32_t* temp_addr;
|
||||||
|
|
||||||
/* reload value */
|
/* reload value */
|
||||||
temp = 12000000 / 1000;
|
temp = 12000000 / 1000;
|
||||||
temp_addr = (uint32_t *)(0x01C20C00 + 0x14);
|
temp_addr = (uint32_t*) (0x01C20C00 + 0x14);
|
||||||
*temp_addr = temp;
|
*temp_addr = temp;
|
||||||
|
|
||||||
/* continuous | /2 | 24Mhz | reload*/
|
/* continuous | /2 | 24Mhz | reload*/
|
||||||
temp = (0x00 << 7) | (0x01 << 4) | (0x01 << 2) | (0x00 << 1);
|
temp = (0x00 << 7) | (0x01 << 4) | (0x01 << 2) | (0x00 << 1);
|
||||||
temp_addr = (uint32_t *)(0x01C20C00 + 0x10);
|
temp_addr = (uint32_t*) (0x01C20C00 + 0x10);
|
||||||
*temp_addr &= 0xffffff00;
|
*temp_addr &= 0xffffff00;
|
||||||
*temp_addr |= temp;
|
*temp_addr |= temp;
|
||||||
|
|
||||||
/* open timer irq */
|
/* open timer irq */
|
||||||
temp = 0x01 << 0;
|
temp = 0x01 << 0;
|
||||||
temp_addr = (uint32_t *)(0x01C20C00);
|
temp_addr = (uint32_t*) (0x01C20C00);
|
||||||
*temp_addr |= temp;
|
*temp_addr |= temp;
|
||||||
|
|
||||||
/* set init value */
|
/* set init value */
|
||||||
temp_addr = (uint32_t *)(0x01C20C00 + 0x18);
|
temp_addr = (uint32_t*) (0x01C20C00 + 0x18);
|
||||||
*temp_addr = 0;
|
*temp_addr = 0;
|
||||||
|
|
||||||
/* begin run timer */
|
/* begin run timer */
|
||||||
temp = 0x01 << 0;
|
temp = 0x01 << 0;
|
||||||
temp_addr = (uint32_t *)(0x01C20C00 + 0x10);
|
temp_addr = (uint32_t*) (0x01C20C00 + 0x10);
|
||||||
*temp_addr |= temp;
|
*temp_addr |= temp;
|
||||||
|
|
||||||
f1c100s_intc_set_isr(F1C100S_IRQ_TIMER0, timer_handler);
|
f1c100s_intc_set_isr(F1C100S_IRQ_TIMER0, timer_handler);
|
||||||
f1c100s_intc_enable_irq(F1C100S_IRQ_TIMER0);
|
f1c100s_intc_enable_irq(F1C100S_IRQ_TIMER0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
static void timer_init(void) { }
|
static void timer_init(void) { }
|
||||||
#endif
|
#endif
|
114
hw/bsp/f1c100s/family.cmake
Normal file
114
hw/bsp/f1c100s/family.cmake
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
include_guard()
|
||||||
|
|
||||||
|
set(SDK_DIR ${TOP}/hw/mcu/allwinner/f1c100s)
|
||||||
|
|
||||||
|
include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake)
|
||||||
|
|
||||||
|
# toolchain set up
|
||||||
|
set(CMAKE_SYSTEM_PROCESSOR arm926ej-s CACHE INTERNAL "System Processor")
|
||||||
|
set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake)
|
||||||
|
|
||||||
|
set(FAMILY_MCUS F1C100S CACHE INTERNAL "")
|
||||||
|
|
||||||
|
#------------------------------------
|
||||||
|
# BOARD_TARGET
|
||||||
|
#------------------------------------
|
||||||
|
# only need to be built ONCE for all examples
|
||||||
|
function(add_board_target BOARD_TARGET)
|
||||||
|
if (TARGET ${BOARD_TARGET})
|
||||||
|
return()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# LD_FILE and STARTUP_FILE can be defined in board.cmake
|
||||||
|
if (NOT DEFINED LD_FILE_GNU)
|
||||||
|
set(LD_FILE_GNU ${SDK_DIR}/f1c100s.ld)
|
||||||
|
endif ()
|
||||||
|
set(LD_FILE_Clang ${LD_FILE_GNU})
|
||||||
|
|
||||||
|
if (NOT DEFINED STARTUP_FILE_GNU)
|
||||||
|
set(STARTUP_FILE_GNU ${SDK_DIR}/machine/start.S)
|
||||||
|
endif ()
|
||||||
|
set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU})
|
||||||
|
|
||||||
|
add_library(${BOARD_TARGET} STATIC
|
||||||
|
${SDK_DIR}/lib/malloc.c
|
||||||
|
${SDK_DIR}/lib/printf.c
|
||||||
|
${SDK_DIR}/lib/memcpy.S
|
||||||
|
${SDK_DIR}/lib/memset.S
|
||||||
|
${SDK_DIR}/machine/sys-uart.c
|
||||||
|
${SDK_DIR}/machine/exception.c
|
||||||
|
${SDK_DIR}/machine/sys-clock.c
|
||||||
|
${SDK_DIR}/machine/sys-copyself.c
|
||||||
|
${SDK_DIR}/machine/sys-dram.c
|
||||||
|
${SDK_DIR}/machine/sys-mmu.c
|
||||||
|
${SDK_DIR}/machine/sys-spi-flash.c
|
||||||
|
${SDK_DIR}/machine/f1c100s-intc.c
|
||||||
|
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_definitions(${BOARD_TARGET} PUBLIC
|
||||||
|
__ARM32_ARCH__=5
|
||||||
|
)
|
||||||
|
target_include_directories(${BOARD_TARGET} PUBLIC
|
||||||
|
${SDK_DIR}/include
|
||||||
|
)
|
||||||
|
|
||||||
|
update_board(${BOARD_TARGET})
|
||||||
|
|
||||||
|
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||||
|
target_link_options(${BOARD_TARGET} PUBLIC
|
||||||
|
"LINKER:--script=${LD_FILE_GNU}"
|
||||||
|
-lgcc
|
||||||
|
--specs=nosys.specs --specs=nano.specs
|
||||||
|
"LINKER:--defsym=__bss_end__=__bss_end"
|
||||||
|
"LINKER:--defsym=__bss_start__=__bss_start"
|
||||||
|
"LINKER:--defsym=end=__bss_end"
|
||||||
|
)
|
||||||
|
elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||||
|
target_link_options(${BOARD_TARGET} PUBLIC
|
||||||
|
"LINKER:--script=${LD_FILE_GNU}"
|
||||||
|
)
|
||||||
|
elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR")
|
||||||
|
target_link_options(${BOARD_TARGET} PUBLIC
|
||||||
|
"LINKER:--config=${LD_FILE_IAR}"
|
||||||
|
)
|
||||||
|
endif ()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
|
||||||
|
#------------------------------------
|
||||||
|
# Functions
|
||||||
|
#------------------------------------
|
||||||
|
function(family_configure_example TARGET RTOS)
|
||||||
|
family_configure_common(${TARGET} ${RTOS})
|
||||||
|
|
||||||
|
# Board target
|
||||||
|
add_board_target(board_${BOARD})
|
||||||
|
|
||||||
|
#---------- Port Specific ----------
|
||||||
|
# These files are built for each example since it depends on example's tusb_config.h
|
||||||
|
target_sources(${TARGET} PUBLIC
|
||||||
|
# BSP
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
||||||
|
)
|
||||||
|
target_include_directories(${TARGET} PUBLIC
|
||||||
|
# family, hw, board
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add TinyUSB target and port source
|
||||||
|
family_add_tinyusb(${TARGET} OPT_MCU_F1C100S ${RTOS})
|
||||||
|
target_sources(${TARGET}-tinyusb PRIVATE
|
||||||
|
${TOP}/src/portable/sunxi/dcd_sunxi_musb.c
|
||||||
|
)
|
||||||
|
target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD})
|
||||||
|
|
||||||
|
# Link dependencies
|
||||||
|
target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb)
|
||||||
|
|
||||||
|
# Flashing
|
||||||
|
family_flash_jlink(${TARGET})
|
||||||
|
endfunction()
|
58
hw/bsp/f1c100s/family.mk
Normal file
58
hw/bsp/f1c100s/family.mk
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
SDK_DIR = hw/mcu/allwinner/f1c100s
|
||||||
|
|
||||||
|
include $(TOP)/$(BOARD_PATH)/board.mk
|
||||||
|
CPU_CORE ?= arm926ej-s
|
||||||
|
|
||||||
|
#CFLAGS += \
|
||||||
|
# -march=armv5te \
|
||||||
|
# -mtune=arm926ej-s \
|
||||||
|
# -mfloat-abi=soft \
|
||||||
|
# -marm \
|
||||||
|
|
||||||
|
CFLAGS += \
|
||||||
|
-ffreestanding \
|
||||||
|
-std=gnu99 \
|
||||||
|
-mno-thumb-interwork \
|
||||||
|
-D__ARM32_ARCH__=5 \
|
||||||
|
-D__ARM926EJS__ \
|
||||||
|
-Wno-float-equal \
|
||||||
|
-Wno-unused-parameter \
|
||||||
|
-DCFG_TUSB_MCU=OPT_MCU_F1C100S \
|
||||||
|
-Wno-error=array-bounds \
|
||||||
|
|
||||||
|
LD_FILE = ${SDK_DIR}/f1c100s.ld
|
||||||
|
|
||||||
|
# TODO may skip nanolib
|
||||||
|
LDFLAGS += \
|
||||||
|
-nostdlib -lgcc \
|
||||||
|
--specs=nosys.specs --specs=nano.specs \
|
||||||
|
|
||||||
|
SRC_C += \
|
||||||
|
src/portable/sunxi/dcd_sunxi_musb.c \
|
||||||
|
${SDK_DIR}/machine/sys-uart.c \
|
||||||
|
${SDK_DIR}/machine/exception.c \
|
||||||
|
${SDK_DIR}/machine/sys-clock.c \
|
||||||
|
${SDK_DIR}/machine/sys-copyself.c \
|
||||||
|
${SDK_DIR}/machine/sys-dram.c \
|
||||||
|
${SDK_DIR}/machine/sys-mmu.c \
|
||||||
|
${SDK_DIR}/machine/sys-spi-flash.c \
|
||||||
|
${SDK_DIR}/machine/f1c100s-intc.c \
|
||||||
|
${SDK_DIR}/lib/malloc.c \
|
||||||
|
${SDK_DIR}/lib/printf.c
|
||||||
|
|
||||||
|
SRC_S += \
|
||||||
|
${SDK_DIR}/machine/start.S \
|
||||||
|
${SDK_DIR}/lib/memcpy.S \
|
||||||
|
${SDK_DIR}/lib/memset.S
|
||||||
|
|
||||||
|
INC += \
|
||||||
|
$(TOP)/${SDK_DIR}/include \
|
||||||
|
$(TOP)/$(BOARD_PATH)
|
||||||
|
|
||||||
|
# flash target using xfel
|
||||||
|
flash: flash-xfel
|
||||||
|
|
||||||
|
exec: $(BUILD)/$(PROJECT).bin
|
||||||
|
xfel ddr
|
||||||
|
xfel write 0x80000000 $<
|
||||||
|
xfel exec 0x80000000
|
@ -415,17 +415,17 @@ endfunction()
|
|||||||
|
|
||||||
|
|
||||||
# Add flash openocd target
|
# Add flash openocd target
|
||||||
function(family_flash_openocd TARGET CLI_OPTIONS)
|
function(family_flash_openocd TARGET)
|
||||||
if (NOT DEFINED OPENOCD)
|
if (NOT DEFINED OPENOCD)
|
||||||
set(OPENOCD openocd)
|
set(OPENOCD openocd)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
separate_arguments(CLI_OPTIONS_LIST UNIX_COMMAND ${CLI_OPTIONS})
|
separate_arguments(OPENOCD_OPTION_LIST UNIX_COMMAND ${OPENOCD_OPTION})
|
||||||
|
|
||||||
# note skip verify since it has issue with rp2040
|
# note skip verify since it has issue with rp2040
|
||||||
add_custom_target(${TARGET}-openocd
|
add_custom_target(${TARGET}-openocd
|
||||||
DEPENDS ${TARGET}
|
DEPENDS ${TARGET}
|
||||||
COMMAND ${OPENOCD} ${CLI_OPTIONS_LIST} -c "program $<TARGET_FILE:${TARGET}> reset exit"
|
COMMAND ${OPENOCD} ${OPENOCD_OPTION_LIST} -c "program $<TARGET_FILE:${TARGET}> reset exit"
|
||||||
VERBATIM
|
VERBATIM
|
||||||
)
|
)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
169
hw/bsp/kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h
Normal file
169
hw/bsp/kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
/*
|
||||||
|
* FreeRTOS Kernel V10.0.0
|
||||||
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software. If you wish to use our Amazon
|
||||||
|
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* http://www.FreeRTOS.org
|
||||||
|
* http://aws.amazon.com/freertos
|
||||||
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef FREERTOS_CONFIG_H
|
||||||
|
#define FREERTOS_CONFIG_H
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Application specific definitions.
|
||||||
|
*
|
||||||
|
* These definitions should be adjusted for your particular hardware and
|
||||||
|
* application requirements.
|
||||||
|
*
|
||||||
|
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
|
||||||
|
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
|
||||||
|
*
|
||||||
|
* See http://www.freertos.org/a00110.html.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
// skip if included from IAR assembler
|
||||||
|
#ifndef __IASMARM__
|
||||||
|
#include "fsl_device_registers.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Cortex M23/M33 port configuration. */
|
||||||
|
#define configENABLE_MPU 0
|
||||||
|
#if defined(__ARM_FP) && __ARM_FP >= 4
|
||||||
|
#define configENABLE_FPU 1
|
||||||
|
#else
|
||||||
|
#define configENABLE_FPU 0
|
||||||
|
#endif
|
||||||
|
#define configENABLE_TRUSTZONE 0
|
||||||
|
#define configMINIMAL_SECURE_STACK_SIZE (1024)
|
||||||
|
|
||||||
|
#define configUSE_PREEMPTION 1
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||||
|
#define configCPU_CLOCK_HZ SystemCoreClock
|
||||||
|
#define configTICK_RATE_HZ ( 1000 )
|
||||||
|
#define configMAX_PRIORITIES ( 5 )
|
||||||
|
#define configMINIMAL_STACK_SIZE ( 128 )
|
||||||
|
#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 )
|
||||||
|
#define configMAX_TASK_NAME_LEN 16
|
||||||
|
#define configUSE_16_BIT_TICKS 0
|
||||||
|
#define configIDLE_SHOULD_YIELD 1
|
||||||
|
#define configUSE_MUTEXES 1
|
||||||
|
#define configUSE_RECURSIVE_MUTEXES 1
|
||||||
|
#define configUSE_COUNTING_SEMAPHORES 1
|
||||||
|
#define configQUEUE_REGISTRY_SIZE 2
|
||||||
|
#define configUSE_QUEUE_SETS 0
|
||||||
|
#define configUSE_TIME_SLICING 0
|
||||||
|
#define configUSE_NEWLIB_REENTRANT 0
|
||||||
|
#define configENABLE_BACKWARD_COMPATIBILITY 1
|
||||||
|
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
|
||||||
|
|
||||||
|
#define configSUPPORT_STATIC_ALLOCATION 1
|
||||||
|
#define configSUPPORT_DYNAMIC_ALLOCATION 0
|
||||||
|
|
||||||
|
/* Hook function related definitions. */
|
||||||
|
#define configUSE_IDLE_HOOK 0
|
||||||
|
#define configUSE_TICK_HOOK 0
|
||||||
|
#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning
|
||||||
|
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||||
|
|
||||||
|
/* Run time and task stats gathering related definitions. */
|
||||||
|
#define configGENERATE_RUN_TIME_STATS 0
|
||||||
|
#define configRECORD_STACK_HIGH_ADDRESS 1
|
||||||
|
#define configUSE_TRACE_FACILITY 1 // legacy trace
|
||||||
|
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
|
||||||
|
|
||||||
|
/* Co-routine definitions. */
|
||||||
|
#define configUSE_CO_ROUTINES 0
|
||||||
|
#define configMAX_CO_ROUTINE_PRIORITIES 2
|
||||||
|
|
||||||
|
/* Software timer related definitions. */
|
||||||
|
#define configUSE_TIMERS 1
|
||||||
|
#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2)
|
||||||
|
#define configTIMER_QUEUE_LENGTH 32
|
||||||
|
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
|
||||||
|
|
||||||
|
/* Optional functions - most linkers will remove unused functions anyway. */
|
||||||
|
#define INCLUDE_vTaskPrioritySet 0
|
||||||
|
#define INCLUDE_uxTaskPriorityGet 0
|
||||||
|
#define INCLUDE_vTaskDelete 0
|
||||||
|
#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY
|
||||||
|
#define INCLUDE_xResumeFromISR 0
|
||||||
|
#define INCLUDE_vTaskDelayUntil 1
|
||||||
|
#define INCLUDE_vTaskDelay 1
|
||||||
|
#define INCLUDE_xTaskGetSchedulerState 0
|
||||||
|
#define INCLUDE_xTaskGetCurrentTaskHandle 1
|
||||||
|
#define INCLUDE_uxTaskGetStackHighWaterMark 0
|
||||||
|
#define INCLUDE_xTaskGetIdleTaskHandle 0
|
||||||
|
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
|
||||||
|
#define INCLUDE_pcTaskGetTaskName 0
|
||||||
|
#define INCLUDE_eTaskGetState 0
|
||||||
|
#define INCLUDE_xEventGroupSetBitFromISR 0
|
||||||
|
#define INCLUDE_xTimerPendFunctionCall 0
|
||||||
|
|
||||||
|
/* Define to trap errors during development. */
|
||||||
|
// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7
|
||||||
|
#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__)
|
||||||
|
#define configASSERT(_exp) \
|
||||||
|
do {\
|
||||||
|
if ( !(_exp) ) { \
|
||||||
|
volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \
|
||||||
|
if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \
|
||||||
|
taskDISABLE_INTERRUPTS(); \
|
||||||
|
__asm("BKPT #0\n"); \
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
} while(0)
|
||||||
|
#else
|
||||||
|
#define configASSERT( x )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* FreeRTOS hooks to NVIC vectors */
|
||||||
|
#define xPortPendSVHandler PendSV_Handler
|
||||||
|
#define xPortSysTickHandler SysTick_Handler
|
||||||
|
#define vPortSVCHandler SVC_Handler
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Interrupt nesting behavior configuration.
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header
|
||||||
|
#define configPRIO_BITS 2
|
||||||
|
|
||||||
|
/* The lowest interrupt priority that can be used in a call to a "set priority" function. */
|
||||||
|
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<<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 /* __FREERTOS_CONFIG__H */
|
15
hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/board.cmake
Normal file
15
hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/board.cmake
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
set(MCU_VARIANT K32L2A41A)
|
||||||
|
|
||||||
|
set(JLINK_DEVICE K32L2A41xxxxA)
|
||||||
|
set(PYOCD_TARGET K32L2A)
|
||||||
|
|
||||||
|
set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/K32L2A41xxxxA_flash.ld)
|
||||||
|
|
||||||
|
function(update_board TARGET)
|
||||||
|
target_sources(${TARGET} PUBLIC
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clock_config.c
|
||||||
|
)
|
||||||
|
target_compile_definitions(${TARGET} PUBLIC
|
||||||
|
CPU_K32L2A41VLH1A
|
||||||
|
)
|
||||||
|
endfunction()
|
@ -30,6 +30,8 @@
|
|||||||
|
|
||||||
#include "fsl_device_registers.h"
|
#include "fsl_device_registers.h"
|
||||||
|
|
||||||
|
#define USB_CLOCK_SOURCE kCLOCK_IpSrcFircAsync
|
||||||
|
|
||||||
// LED
|
// LED
|
||||||
// The Red LED is on PTE29.
|
// The Red LED is on PTE29.
|
||||||
// The Green LED is on PTC4.
|
// The Green LED is on PTC4.
|
||||||
@ -54,5 +56,37 @@
|
|||||||
#define UART_PIN_PORT PORTB
|
#define UART_PIN_PORT PORTB
|
||||||
#define UART_PIN_RX 16u
|
#define UART_PIN_RX 16u
|
||||||
#define UART_PIN_TX 17u
|
#define UART_PIN_TX 17u
|
||||||
|
#define UART_CLOCK_SOURCE_HZ CLOCK_GetFreq(kCLOCK_ScgFircClk)
|
||||||
|
|
||||||
|
static inline void BOARD_InitBootPins(void) {
|
||||||
|
/*
|
||||||
|
Enable LPUART0 clock and configure port pins.
|
||||||
|
FIR clock is being used so the USB examples work.
|
||||||
|
*/
|
||||||
|
PCC_LPUART0 = 0U; /* Clock must be off to set PCS */
|
||||||
|
PCC_LPUART0 = PCC_CLKCFG_PCS(
|
||||||
|
3U); /* Select the clock. 1:OSCCLK/Bus Clock, 2:Slow IRC, 3: Fast IRC, 6: System PLL */
|
||||||
|
PCC_LPUART0 |= PCC_CLKCFG_CGC(1U); /* Enable LPUART */
|
||||||
|
|
||||||
|
/* PORTB16 (pin 62) is configured as LPUART0_RX */
|
||||||
|
gpio_pin_config_t const lpuart_config_rx = {kGPIO_DigitalInput, 0};
|
||||||
|
GPIO_PinInit(UART_PIN_GPIO, UART_PIN_RX, &lpuart_config_rx);
|
||||||
|
const port_pin_config_t UART_CFG = {
|
||||||
|
kPORT_PullUp,
|
||||||
|
kPORT_FastSlewRate,
|
||||||
|
kPORT_PassiveFilterDisable,
|
||||||
|
kPORT_OpenDrainDisable,
|
||||||
|
kPORT_LowDriveStrength,
|
||||||
|
kPORT_MuxAsGpio,
|
||||||
|
kPORT_UnlockRegister
|
||||||
|
};
|
||||||
|
PORT_SetPinConfig(UART_PIN_PORT, UART_PIN_RX, &UART_CFG);
|
||||||
|
PORT_SetPinMux(UART_PIN_PORT, UART_PIN_RX, kPORT_MuxAlt3);
|
||||||
|
|
||||||
|
/* PORTB17 (pin 63) is configured as LPUART0_TX */
|
||||||
|
gpio_pin_config_t const lpuart_config_tx = {kGPIO_DigitalOutput, 0};
|
||||||
|
GPIO_PinInit(UART_PIN_GPIO, UART_PIN_TX, &lpuart_config_tx);
|
||||||
|
PORT_SetPinMux(UART_PIN_PORT, UART_PIN_TX, kPORT_MuxAlt3);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* BOARD_H_ */
|
#endif /* BOARD_H_ */
|
||||||
|
@ -53,7 +53,7 @@ processor_version: 9.0.0
|
|||||||
* Variables
|
* Variables
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
/* System clock frequency. */
|
/* System clock frequency. */
|
||||||
extern uint32_t SystemCoreClock;
|
//extern uint32_t SystemCoreClock;
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Code
|
* Code
|
||||||
|
15
hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.cmake
Normal file
15
hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.cmake
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
set(MCU_VARIANT K32L2B31A)
|
||||||
|
|
||||||
|
set(JLINK_DEVICE K32L2B31xxxxA)
|
||||||
|
set(PYOCD_TARGET K32L2B)
|
||||||
|
|
||||||
|
set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/K32L2B31xxxxA_flash.ld)
|
||||||
|
|
||||||
|
function(update_board TARGET)
|
||||||
|
target_sources(${TARGET} PUBLIC
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clock_config.c
|
||||||
|
)
|
||||||
|
target_compile_definitions(${TARGET} PUBLIC
|
||||||
|
CPU_K32L2B31VLH0A
|
||||||
|
)
|
||||||
|
endfunction()
|
@ -30,6 +30,8 @@
|
|||||||
|
|
||||||
#include "fsl_device_registers.h"
|
#include "fsl_device_registers.h"
|
||||||
|
|
||||||
|
#define USB_CLOCK_SOURCE kCLOCK_UsbSrcIrc48M
|
||||||
|
|
||||||
// LED
|
// LED
|
||||||
#define LED_PIN_CLOCK kCLOCK_PortD
|
#define LED_PIN_CLOCK kCLOCK_PortD
|
||||||
#define LED_GPIO GPIOD
|
#define LED_GPIO GPIOD
|
||||||
@ -52,5 +54,25 @@
|
|||||||
#define UART_PIN_TX 2u
|
#define UART_PIN_TX 2u
|
||||||
#define SOPT5_LPUART0RXSRC_LPUART_RX 0x00u /*!<@brief LPUART0 Receive Data Source Select: LPUART_RX pin */
|
#define SOPT5_LPUART0RXSRC_LPUART_RX 0x00u /*!<@brief LPUART0 Receive Data Source Select: LPUART_RX pin */
|
||||||
#define SOPT5_LPUART0TXSRC_LPUART_TX 0x00u /*!<@brief LPUART0 Transmit Data Source Select: LPUART0_TX pin */
|
#define SOPT5_LPUART0TXSRC_LPUART_TX 0x00u /*!<@brief LPUART0 Transmit Data Source Select: LPUART0_TX pin */
|
||||||
|
#define UART_CLOCK_SOURCE_HZ CLOCK_GetFreq(kCLOCK_McgIrc48MClk)
|
||||||
|
|
||||||
|
static inline void BOARD_InitBootPins(void) {
|
||||||
|
/* PORTA1 (pin 23) is configured as LPUART0_RX */
|
||||||
|
PORT_SetPinMux(PORTA, 1U, kPORT_MuxAlt2);
|
||||||
|
/* PORTA2 (pin 24) is configured as LPUART0_TX */
|
||||||
|
PORT_SetPinMux(PORTA, 2U, kPORT_MuxAlt2);
|
||||||
|
|
||||||
|
SIM->SOPT5 = ((SIM->SOPT5 &
|
||||||
|
/* Mask bits to zero which are setting */
|
||||||
|
(~(SIM_SOPT5_LPUART0TXSRC_MASK | SIM_SOPT5_LPUART0RXSRC_MASK)))
|
||||||
|
/* LPUART0 Transmit Data Source Select: LPUART0_TX pin. */
|
||||||
|
| SIM_SOPT5_LPUART0TXSRC(SOPT5_LPUART0TXSRC_LPUART_TX)
|
||||||
|
/* LPUART0 Receive Data Source Select: LPUART_RX pin. */
|
||||||
|
| SIM_SOPT5_LPUART0RXSRC(SOPT5_LPUART0RXSRC_LPUART_RX));
|
||||||
|
|
||||||
|
BOARD_BootClockRUN();
|
||||||
|
SystemCoreClockUpdate();
|
||||||
|
CLOCK_SetLpuart0Clock(1);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* BOARD_H_ */
|
#endif /* BOARD_H_ */
|
||||||
|
@ -48,7 +48,7 @@ board: FRDM-K32L2B
|
|||||||
* Variables
|
* Variables
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
/* System clock frequency. */
|
/* System clock frequency. */
|
||||||
extern uint32_t SystemCoreClock;
|
//extern uint32_t SystemCoreClock;
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
************************ BOARD_InitBootClocks function ************************
|
************************ BOARD_InitBootClocks function ************************
|
||||||
|
@ -1,140 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018, hathach (tinyusb.org)
|
|
||||||
* Copyright (c) 2020, Koji Kitayama
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* This file is part of the TinyUSB stack.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "bsp/board_api.h"
|
|
||||||
#include "board.h"
|
|
||||||
#include "fsl_gpio.h"
|
|
||||||
#include "fsl_port.h"
|
|
||||||
#include "fsl_clock.h"
|
|
||||||
#include "fsl_lpuart.h"
|
|
||||||
|
|
||||||
#include "clock_config.h"
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
// Forward USB interrupt events to TinyUSB IRQ Handler
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
void USB0_IRQHandler(void)
|
|
||||||
{
|
|
||||||
tud_int_handler(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void board_init(void)
|
|
||||||
{
|
|
||||||
/* Enable port clocks for UART/LED/Button pins */
|
|
||||||
CLOCK_EnableClock(UART_PIN_CLOCK);
|
|
||||||
CLOCK_EnableClock(LED_PIN_CLOCK);
|
|
||||||
CLOCK_EnableClock(BUTTON_PIN_CLOCK);
|
|
||||||
|
|
||||||
gpio_pin_config_t led_config = { kGPIO_DigitalOutput, 0 };
|
|
||||||
GPIO_PinInit(LED_GPIO, LED_PIN, &led_config);
|
|
||||||
PORT_SetPinMux(LED_PORT, LED_PIN, kPORT_MuxAsGpio);
|
|
||||||
|
|
||||||
gpio_pin_config_t button_config = { kGPIO_DigitalInput, 0 };
|
|
||||||
GPIO_PinInit(BUTTON_GPIO, BUTTON_PIN, &button_config);
|
|
||||||
const port_pin_config_t BUTTON_CFG = {
|
|
||||||
kPORT_PullUp,
|
|
||||||
kPORT_FastSlewRate,
|
|
||||||
kPORT_PassiveFilterDisable,
|
|
||||||
kPORT_LowDriveStrength,
|
|
||||||
kPORT_MuxAsGpio
|
|
||||||
};
|
|
||||||
PORT_SetPinConfig(BUTTON_PORT, BUTTON_PIN, &BUTTON_CFG);
|
|
||||||
|
|
||||||
/* PORTA1 (pin 23) is configured as LPUART0_RX */
|
|
||||||
PORT_SetPinMux(PORTA, 1U, kPORT_MuxAlt2);
|
|
||||||
/* PORTA2 (pin 24) is configured as LPUART0_TX */
|
|
||||||
PORT_SetPinMux(PORTA, 2U, kPORT_MuxAlt2);
|
|
||||||
|
|
||||||
SIM->SOPT5 = ((SIM->SOPT5 &
|
|
||||||
/* Mask bits to zero which are setting */
|
|
||||||
(~(SIM_SOPT5_LPUART0TXSRC_MASK | SIM_SOPT5_LPUART0RXSRC_MASK)))
|
|
||||||
/* LPUART0 Transmit Data Source Select: LPUART0_TX pin. */
|
|
||||||
| SIM_SOPT5_LPUART0TXSRC(SOPT5_LPUART0TXSRC_LPUART_TX)
|
|
||||||
/* LPUART0 Receive Data Source Select: LPUART_RX pin. */
|
|
||||||
| SIM_SOPT5_LPUART0RXSRC(SOPT5_LPUART0RXSRC_LPUART_RX));
|
|
||||||
|
|
||||||
BOARD_BootClockRUN();
|
|
||||||
SystemCoreClockUpdate();
|
|
||||||
CLOCK_SetLpuart0Clock(1);
|
|
||||||
|
|
||||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
|
||||||
// 1ms tick timer
|
|
||||||
SysTick_Config(SystemCoreClock / 1000);
|
|
||||||
#elif CFG_TUSB_OS == OPT_OS_FREERTOS
|
|
||||||
// If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher )
|
|
||||||
NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
lpuart_config_t uart_config;
|
|
||||||
LPUART_GetDefaultConfig(&uart_config);
|
|
||||||
uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE;
|
|
||||||
uart_config.enableTx = true;
|
|
||||||
uart_config.enableRx = true;
|
|
||||||
LPUART_Init(UART_PORT, &uart_config, CLOCK_GetFreq(kCLOCK_McgIrc48MClk));
|
|
||||||
|
|
||||||
// USB
|
|
||||||
CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcIrc48M, 48000000U);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
// Board porting API
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
|
|
||||||
void board_led_write(bool state)
|
|
||||||
{
|
|
||||||
GPIO_PinWrite(LED_GPIO, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON));
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t board_button_read(void)
|
|
||||||
{
|
|
||||||
return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_GPIO, BUTTON_PIN);
|
|
||||||
}
|
|
||||||
|
|
||||||
int board_uart_read(uint8_t* buf, int len)
|
|
||||||
{
|
|
||||||
LPUART_ReadBlocking(UART_PORT, buf, len);
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
int board_uart_write(void const * buf, int len)
|
|
||||||
{
|
|
||||||
LPUART_WriteBlocking(UART_PORT, (uint8_t const*) buf, len);
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
|
||||||
volatile uint32_t system_ticks = 0;
|
|
||||||
void SysTick_Handler(void)
|
|
||||||
{
|
|
||||||
system_ticks++;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t board_millis(void)
|
|
||||||
{
|
|
||||||
return system_ticks;
|
|
||||||
}
|
|
||||||
#endif
|
|
15
hw/bsp/kinetis_k32l2/boards/kuiic/board.cmake
Normal file
15
hw/bsp/kinetis_k32l2/boards/kuiic/board.cmake
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
set(MCU_VARIANT K32L2B31A)
|
||||||
|
|
||||||
|
set(JLINK_DEVICE K32L2B31xxxxA)
|
||||||
|
set(PYOCD_TARGET K32L2B)
|
||||||
|
|
||||||
|
set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/kuiic.ld)
|
||||||
|
|
||||||
|
function(update_board TARGET)
|
||||||
|
target_sources(${TARGET} PUBLIC
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clock_config.c
|
||||||
|
)
|
||||||
|
target_compile_definitions(${TARGET} PUBLIC
|
||||||
|
CPU_K32L2B31VLH0A
|
||||||
|
)
|
||||||
|
endfunction()
|
@ -30,6 +30,8 @@
|
|||||||
|
|
||||||
#include "fsl_device_registers.h"
|
#include "fsl_device_registers.h"
|
||||||
|
|
||||||
|
#define USB_CLOCK_SOURCE kCLOCK_UsbSrcIrc48M
|
||||||
|
|
||||||
// LED
|
// LED
|
||||||
#define LED_PIN_CLOCK kCLOCK_PortA
|
#define LED_PIN_CLOCK kCLOCK_PortA
|
||||||
#define LED_GPIO GPIOA
|
#define LED_GPIO GPIOA
|
||||||
@ -42,4 +44,22 @@
|
|||||||
#define UART_PIN_RX 3u
|
#define UART_PIN_RX 3u
|
||||||
#define UART_PIN_TX 0u
|
#define UART_PIN_TX 0u
|
||||||
|
|
||||||
|
#define UART_CLOCK_SOURCE_HZ CLOCK_GetFreq(kCLOCK_McgIrc48MClk)
|
||||||
|
|
||||||
|
static inline void BOARD_InitBootPins(void) {
|
||||||
|
/* PORTC3 is configured as LPUART0_RX */
|
||||||
|
PORT_SetPinMux(PORTC, 3U, kPORT_MuxAlt3);
|
||||||
|
/* PORTA2 (pin 24) is configured as LPUART0_TX */
|
||||||
|
PORT_SetPinMux(PORTE, 0U, kPORT_MuxAlt3);
|
||||||
|
|
||||||
|
SIM->SOPT5 = ((SIM->SOPT5 &
|
||||||
|
/* Mask bits to zero which are setting */
|
||||||
|
(~(SIM_SOPT5_LPUART1TXSRC_MASK | SIM_SOPT5_LPUART1RXSRC_MASK)))
|
||||||
|
/* LPUART0 Transmit Data Source Select: LPUART0_TX pin. */
|
||||||
|
| SIM_SOPT5_LPUART1TXSRC(SOPT5_LPUART1TXSRC_LPUART_TX)
|
||||||
|
/* LPUART0 Receive Data Source Select: LPUART_RX pin. */
|
||||||
|
| SIM_SOPT5_LPUART1RXSRC(SOPT5_LPUART1RXSRC_LPUART_RX));
|
||||||
|
CLOCK_SetLpuart1Clock(1);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* BOARD_H_ */
|
#endif /* BOARD_H_ */
|
||||||
|
@ -6,7 +6,7 @@ CFLAGS += -DCPU_K32L2B31VLH0A
|
|||||||
CFLAGS += -Wno-error=unused-parameter -Wno-error=redundant-decls
|
CFLAGS += -Wno-error=unused-parameter -Wno-error=redundant-decls
|
||||||
|
|
||||||
# All source paths should be relative to the top level.
|
# All source paths should be relative to the top level.
|
||||||
LD_FILE = $(BOARD_PATH)/K32L2B31xxxxA_flash.ld
|
LD_FILE = $(BOARD_PATH)/kuiic.ld
|
||||||
|
|
||||||
# For flash-jlink target
|
# For flash-jlink target
|
||||||
JLINK_DEVICE = K32L2B31xxxxA
|
JLINK_DEVICE = K32L2B31xxxxA
|
||||||
|
39
hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.c
Normal file
39
hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.c
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#include "clock_config.h"
|
||||||
|
#include "fsl_clock.h"
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Variables
|
||||||
|
******************************************************************************/
|
||||||
|
/* System clock frequency. */
|
||||||
|
// extern uint32_t SystemCoreClock;
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Variables for BOARD_BootClockRUN configuration
|
||||||
|
******************************************************************************/
|
||||||
|
const mcglite_config_t mcgliteConfig_BOARD_BootClockRUN = {
|
||||||
|
.outSrc = kMCGLITE_ClkSrcHirc, /* MCGOUTCLK source is HIRC */
|
||||||
|
.irclkEnableMode = kMCGLITE_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */
|
||||||
|
.ircs = kMCGLITE_Lirc8M, /* Slow internal reference (LIRC) 8 MHz clock selected */
|
||||||
|
.fcrdiv = kMCGLITE_LircDivBy1, /* Low-frequency Internal Reference Clock Divider: divided by 1 */
|
||||||
|
.lircDiv2 = kMCGLITE_LircDivBy1, /* Second Low-frequency Internal Reference Clock Divider: divided by 1 */
|
||||||
|
.hircEnableInNotHircMode = true, /* HIRC source is enabled */
|
||||||
|
};
|
||||||
|
const sim_clock_config_t simConfig_BOARD_BootClockRUN = {
|
||||||
|
.er32kSrc = SIM_OSC32KSEL_LPO_CLK, /* OSC32KSEL select: LPO clock */
|
||||||
|
.clkdiv1 = 0x10000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV4: /2 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Code for BOARD_BootClockRUN configuration
|
||||||
|
******************************************************************************/
|
||||||
|
void BOARD_BootClockRUN(void)
|
||||||
|
{
|
||||||
|
/* Set the system clock dividers in SIM to safe value. */
|
||||||
|
CLOCK_SetSimSafeDivs();
|
||||||
|
/* Set MCG to HIRC mode. */
|
||||||
|
CLOCK_SetMcgliteConfig(&mcgliteConfig_BOARD_BootClockRUN);
|
||||||
|
/* Set the clock configuration in SIM module. */
|
||||||
|
CLOCK_SetSimConfig(&simConfig_BOARD_BootClockRUN);
|
||||||
|
/* Set SystemCoreClock variable. */
|
||||||
|
SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK;
|
||||||
|
}
|
14
hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.h
Normal file
14
hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef CLOCK_CONFIG_H
|
||||||
|
#define CLOCK_CONFIG_H
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Definitions
|
||||||
|
******************************************************************************/
|
||||||
|
#define SIM_OSC32KSEL_LPO_CLK 3U /*!< OSC32KSEL select: LPO clock */
|
||||||
|
#define SOPT5_LPUART1RXSRC_LPUART_RX 0x00u /*!<@brief LPUART1 Receive Data Source Select: LPUART_RX pin */
|
||||||
|
#define SOPT5_LPUART1TXSRC_LPUART_TX 0x00u /*!<@brief LPUART1 Transmit Data Source Select: LPUART_TX pin */
|
||||||
|
#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */
|
||||||
|
|
||||||
|
void BOARD_BootClockRUN(void);
|
||||||
|
|
||||||
|
#endif
|
@ -1,203 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018, hathach (tinyusb.org)
|
|
||||||
* Copyright (c) 2020, Koji Kitayama
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* This file is part of the TinyUSB stack.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "bsp/board_api.h"
|
|
||||||
#include "board.h"
|
|
||||||
#include "fsl_smc.h"
|
|
||||||
#include "fsl_gpio.h"
|
|
||||||
#include "fsl_port.h"
|
|
||||||
#include "fsl_clock.h"
|
|
||||||
#include "fsl_lpuart.h"
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* Definitions
|
|
||||||
******************************************************************************/
|
|
||||||
#define SIM_OSC32KSEL_LPO_CLK 3U /*!< OSC32KSEL select: LPO clock */
|
|
||||||
#define SOPT5_LPUART1RXSRC_LPUART_RX 0x00u /*!<@brief LPUART1 Receive Data Source Select: LPUART_RX pin */
|
|
||||||
#define SOPT5_LPUART1TXSRC_LPUART_TX 0x00u /*!<@brief LPUART1 Transmit Data Source Select: LPUART_TX pin */
|
|
||||||
#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* Variables
|
|
||||||
******************************************************************************/
|
|
||||||
/* System clock frequency. */
|
|
||||||
// extern uint32_t SystemCoreClock;
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* Variables for BOARD_BootClockRUN configuration
|
|
||||||
******************************************************************************/
|
|
||||||
const mcglite_config_t mcgliteConfig_BOARD_BootClockRUN = {
|
|
||||||
.outSrc = kMCGLITE_ClkSrcHirc, /* MCGOUTCLK source is HIRC */
|
|
||||||
.irclkEnableMode = kMCGLITE_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */
|
|
||||||
.ircs = kMCGLITE_Lirc8M, /* Slow internal reference (LIRC) 8 MHz clock selected */
|
|
||||||
.fcrdiv = kMCGLITE_LircDivBy1, /* Low-frequency Internal Reference Clock Divider: divided by 1 */
|
|
||||||
.lircDiv2 = kMCGLITE_LircDivBy1, /* Second Low-frequency Internal Reference Clock Divider: divided by 1 */
|
|
||||||
.hircEnableInNotHircMode = true, /* HIRC source is enabled */
|
|
||||||
};
|
|
||||||
const sim_clock_config_t simConfig_BOARD_BootClockRUN = {
|
|
||||||
.er32kSrc = SIM_OSC32KSEL_LPO_CLK, /* OSC32KSEL select: LPO clock */
|
|
||||||
.clkdiv1 = 0x10000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV4: /2 */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* Code for BOARD_BootClockRUN configuration
|
|
||||||
******************************************************************************/
|
|
||||||
void BOARD_BootClockRUN(void)
|
|
||||||
{
|
|
||||||
/* Set the system clock dividers in SIM to safe value. */
|
|
||||||
CLOCK_SetSimSafeDivs();
|
|
||||||
/* Set MCG to HIRC mode. */
|
|
||||||
CLOCK_SetMcgliteConfig(&mcgliteConfig_BOARD_BootClockRUN);
|
|
||||||
/* Set the clock configuration in SIM module. */
|
|
||||||
CLOCK_SetSimConfig(&simConfig_BOARD_BootClockRUN);
|
|
||||||
/* Set SystemCoreClock variable. */
|
|
||||||
SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
// Forward USB interrupt events to TinyUSB IRQ Handler
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
void USB0_IRQHandler(void)
|
|
||||||
{
|
|
||||||
tud_int_handler(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void board_init(void)
|
|
||||||
{
|
|
||||||
/* Enable port clocks for GPIO pins */
|
|
||||||
CLOCK_EnableClock(kCLOCK_PortA);
|
|
||||||
CLOCK_EnableClock(kCLOCK_PortB);
|
|
||||||
CLOCK_EnableClock(kCLOCK_PortC);
|
|
||||||
CLOCK_EnableClock(kCLOCK_PortD);
|
|
||||||
CLOCK_EnableClock(kCLOCK_PortE);
|
|
||||||
|
|
||||||
|
|
||||||
gpio_pin_config_t led_config = { kGPIO_DigitalOutput, 1 };
|
|
||||||
GPIO_PinInit(GPIOA, 1U, &led_config);
|
|
||||||
PORT_SetPinMux(PORTA, 1U, kPORT_MuxAsGpio);
|
|
||||||
led_config.outputLogic = 0;
|
|
||||||
GPIO_PinInit(GPIOA, 2U, &led_config);
|
|
||||||
PORT_SetPinMux(PORTA, 2U, kPORT_MuxAsGpio);
|
|
||||||
|
|
||||||
#ifdef BUTTON_PIN
|
|
||||||
gpio_pin_config_t button_config = { kGPIO_DigitalInput, 0 };
|
|
||||||
GPIO_PinInit(BUTTON_GPIO, BUTTON_PIN, &button_config);
|
|
||||||
const port_pin_config_t BUTTON_CFG = {
|
|
||||||
kPORT_PullUp,
|
|
||||||
kPORT_FastSlewRate,
|
|
||||||
kPORT_PassiveFilterDisable,
|
|
||||||
kPORT_LowDriveStrength,
|
|
||||||
kPORT_MuxAsGpio
|
|
||||||
};
|
|
||||||
PORT_SetPinConfig(BUTTON_PORT, BUTTON_PIN, &BUTTON_CFG);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* PORTC3 is configured as LPUART0_RX */
|
|
||||||
PORT_SetPinMux(PORTC, 3U, kPORT_MuxAlt3);
|
|
||||||
/* PORTA2 (pin 24) is configured as LPUART0_TX */
|
|
||||||
PORT_SetPinMux(PORTE, 0U, kPORT_MuxAlt3);
|
|
||||||
|
|
||||||
SIM->SOPT5 = ((SIM->SOPT5 &
|
|
||||||
/* Mask bits to zero which are setting */
|
|
||||||
(~(SIM_SOPT5_LPUART1TXSRC_MASK | SIM_SOPT5_LPUART1RXSRC_MASK)))
|
|
||||||
/* LPUART0 Transmit Data Source Select: LPUART0_TX pin. */
|
|
||||||
| SIM_SOPT5_LPUART1TXSRC(SOPT5_LPUART1TXSRC_LPUART_TX)
|
|
||||||
/* LPUART0 Receive Data Source Select: LPUART_RX pin. */
|
|
||||||
| SIM_SOPT5_LPUART1RXSRC(SOPT5_LPUART1RXSRC_LPUART_RX));
|
|
||||||
|
|
||||||
BOARD_BootClockRUN();
|
|
||||||
SystemCoreClockUpdate();
|
|
||||||
CLOCK_SetLpuart1Clock(1);
|
|
||||||
|
|
||||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
|
||||||
// 1ms tick timer
|
|
||||||
SysTick_Config(SystemCoreClock / 1000);
|
|
||||||
#elif CFG_TUSB_OS == OPT_OS_FREERTOS
|
|
||||||
// If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher )
|
|
||||||
NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
lpuart_config_t uart_config;
|
|
||||||
LPUART_GetDefaultConfig(&uart_config);
|
|
||||||
uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE;
|
|
||||||
uart_config.enableTx = true;
|
|
||||||
uart_config.enableRx = true;
|
|
||||||
LPUART_Init(UART_PORT, &uart_config, CLOCK_GetFreq(kCLOCK_McgIrc48MClk));
|
|
||||||
|
|
||||||
// USB
|
|
||||||
CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcIrc48M, 48000000U);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
// Board porting API
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
|
|
||||||
void board_led_write(bool state)
|
|
||||||
{
|
|
||||||
if (state) {
|
|
||||||
LED_GPIO->PDDR |= GPIO_FIT_REG((1UL << LED_PIN));
|
|
||||||
} else {
|
|
||||||
LED_GPIO->PDDR &= GPIO_FIT_REG(~(1UL << LED_PIN));
|
|
||||||
}
|
|
||||||
// GPIO_PinWrite(GPIOA, 1, state ? LED_STATE_ON : (1-LED_STATE_ON) );
|
|
||||||
// GPIO_PinWrite(GPIOA, 2, state ? (1-LED_STATE_ON) : LED_STATE_ON );
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t board_button_read(void)
|
|
||||||
{
|
|
||||||
#ifdef BUTTON_PIN
|
|
||||||
return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_GPIO, BUTTON_PIN);
|
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int board_uart_read(uint8_t* buf, int len)
|
|
||||||
{
|
|
||||||
LPUART_ReadBlocking(UART_PORT, buf, len);
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
int board_uart_write(void const * buf, int len)
|
|
||||||
{
|
|
||||||
LPUART_WriteBlocking(UART_PORT, (uint8_t const*) buf, len);
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
|
||||||
volatile uint32_t system_ticks = 0;
|
|
||||||
void SysTick_Handler(void)
|
|
||||||
{
|
|
||||||
system_ticks++;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t board_millis(void)
|
|
||||||
{
|
|
||||||
return system_ticks;
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -25,77 +25,57 @@
|
|||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "bsp/board_api.h"
|
|
||||||
#include "board.h"
|
|
||||||
#include "fsl_gpio.h"
|
#include "fsl_gpio.h"
|
||||||
#include "fsl_port.h"
|
#include "fsl_port.h"
|
||||||
#include "fsl_clock.h"
|
#include "fsl_clock.h"
|
||||||
#include "fsl_lpuart.h"
|
#include "fsl_lpuart.h"
|
||||||
|
|
||||||
#include "clock_config.h"
|
#include "clock_config.h"
|
||||||
|
#include "bsp/board_api.h"
|
||||||
|
#include "board.h"
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Forward USB interrupt events to TinyUSB IRQ Handler
|
// Forward USB interrupt events to TinyUSB IRQ Handler
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
void USB0_IRQHandler(void)
|
void USB0_IRQHandler(void) {
|
||||||
{
|
|
||||||
tud_int_handler(0);
|
tud_int_handler(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void board_init(void)
|
void board_init(void) {
|
||||||
{
|
/* Enable port clocks for GPIO pins */
|
||||||
/* Enable port clocks for UART/LED/Button pins */
|
CLOCK_EnableClock(kCLOCK_PortA);
|
||||||
CLOCK_EnableClock(UART_PIN_CLOCK);
|
CLOCK_EnableClock(kCLOCK_PortB);
|
||||||
CLOCK_EnableClock(LED_PIN_CLOCK);
|
CLOCK_EnableClock(kCLOCK_PortC);
|
||||||
CLOCK_EnableClock(BUTTON_PIN_CLOCK);
|
CLOCK_EnableClock(kCLOCK_PortD);
|
||||||
|
CLOCK_EnableClock(kCLOCK_PortE);
|
||||||
|
|
||||||
gpio_pin_config_t led_config = { kGPIO_DigitalOutput, 0 };
|
BOARD_InitBootPins();
|
||||||
|
BOARD_BootClockRUN();
|
||||||
|
SystemCoreClockUpdate();
|
||||||
|
|
||||||
|
gpio_pin_config_t led_config = {kGPIO_DigitalOutput, 0};
|
||||||
GPIO_PinInit(LED_GPIO, LED_PIN, &led_config);
|
GPIO_PinInit(LED_GPIO, LED_PIN, &led_config);
|
||||||
PORT_SetPinMux(LED_PORT, LED_PIN, kPORT_MuxAsGpio);
|
PORT_SetPinMux(LED_PORT, LED_PIN, kPORT_MuxAsGpio);
|
||||||
|
|
||||||
gpio_pin_config_t button_config = { kGPIO_DigitalInput, 0 };
|
#ifdef BUTTON_PIN
|
||||||
|
gpio_pin_config_t button_config = {kGPIO_DigitalInput, 0};
|
||||||
GPIO_PinInit(BUTTON_GPIO, BUTTON_PIN, &button_config);
|
GPIO_PinInit(BUTTON_GPIO, BUTTON_PIN, &button_config);
|
||||||
const port_pin_config_t BUTTON_CFG = {
|
const port_pin_config_t BUTTON_CFG = {
|
||||||
kPORT_PullUp,
|
kPORT_PullUp,
|
||||||
kPORT_FastSlewRate,
|
kPORT_FastSlewRate,
|
||||||
kPORT_PassiveFilterDisable,
|
kPORT_PassiveFilterDisable,
|
||||||
kPORT_OpenDrainDisable,
|
#if defined(FSL_FEATURE_PORT_HAS_OPEN_DRAIN) && FSL_FEATURE_PORT_HAS_OPEN_DRAIN
|
||||||
kPORT_LowDriveStrength,
|
kPORT_OpenDrainDisable,
|
||||||
kPORT_MuxAsGpio,
|
#endif
|
||||||
kPORT_UnlockRegister
|
kPORT_LowDriveStrength,
|
||||||
|
kPORT_MuxAsGpio,
|
||||||
|
#if defined(FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK) && FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK
|
||||||
|
kPORT_UnlockRegister
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
PORT_SetPinConfig(BUTTON_PORT, BUTTON_PIN, &BUTTON_CFG);
|
PORT_SetPinConfig(BUTTON_PORT, BUTTON_PIN, &BUTTON_CFG);
|
||||||
|
#endif
|
||||||
/*
|
|
||||||
Enable LPUART0 clock and configure port pins.
|
|
||||||
FIR clock is being used so the USB examples work.
|
|
||||||
*/
|
|
||||||
PCC_LPUART0 = 0U; /* Clock must be off to set PCS */
|
|
||||||
PCC_LPUART0 = PCC_CLKCFG_PCS( 3U ); /* Select the clock. 1:OSCCLK/Bus Clock, 2:Slow IRC, 3: Fast IRC, 6: System PLL */
|
|
||||||
PCC_LPUART0 |= PCC_CLKCFG_CGC( 1U ); /* Enable LPUART */
|
|
||||||
|
|
||||||
/* PORTB16 (pin 62) is configured as LPUART0_RX */
|
|
||||||
gpio_pin_config_t const lpuart_config_rx = { kGPIO_DigitalInput, 0 };
|
|
||||||
GPIO_PinInit(UART_PIN_GPIO, UART_PIN_RX, &lpuart_config_rx);
|
|
||||||
const port_pin_config_t UART_CFG = {
|
|
||||||
kPORT_PullUp,
|
|
||||||
kPORT_FastSlewRate,
|
|
||||||
kPORT_PassiveFilterDisable,
|
|
||||||
kPORT_OpenDrainDisable,
|
|
||||||
kPORT_LowDriveStrength,
|
|
||||||
kPORT_MuxAsGpio,
|
|
||||||
kPORT_UnlockRegister
|
|
||||||
};
|
|
||||||
PORT_SetPinConfig(UART_PIN_PORT, UART_PIN_RX, &UART_CFG);
|
|
||||||
PORT_SetPinMux( UART_PIN_PORT, UART_PIN_RX, kPORT_MuxAlt3);
|
|
||||||
|
|
||||||
/* PORTB17 (pin 63) is configured as LPUART0_TX */
|
|
||||||
gpio_pin_config_t const lpuart_config_tx = { kGPIO_DigitalOutput, 0 };
|
|
||||||
GPIO_PinInit( UART_PIN_GPIO, UART_PIN_TX, &lpuart_config_tx);
|
|
||||||
PORT_SetPinMux( UART_PIN_PORT, UART_PIN_TX, kPORT_MuxAlt3);
|
|
||||||
|
|
||||||
BOARD_BootClockRUN();
|
|
||||||
SystemCoreClockUpdate();
|
|
||||||
|
|
||||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
// 1ms tick timer
|
// 1ms tick timer
|
||||||
@ -110,28 +90,29 @@ void board_init(void)
|
|||||||
uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE;
|
uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE;
|
||||||
uart_config.enableTx = true;
|
uart_config.enableTx = true;
|
||||||
uart_config.enableRx = true;
|
uart_config.enableRx = true;
|
||||||
LPUART_Init(UART_PORT, &uart_config, CLOCK_GetFreq(kCLOCK_ScgFircClk));
|
LPUART_Init(UART_PORT, &uart_config, UART_CLOCK_SOURCE_HZ);
|
||||||
|
|
||||||
// USB
|
// USB
|
||||||
CLOCK_EnableUsbfs0Clock(kCLOCK_IpSrcFircAsync, 48000000U);
|
CLOCK_EnableUsbfs0Clock(USB_CLOCK_SOURCE, 48000000U);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Board porting API
|
// Board porting API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
void board_led_write(bool state)
|
void board_led_write(bool state) {
|
||||||
{
|
GPIO_PinWrite(LED_GPIO, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON));
|
||||||
GPIO_PinWrite(LED_GPIO, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t board_button_read(void)
|
uint32_t board_button_read(void) {
|
||||||
{
|
#ifdef BUTTON_PIN
|
||||||
return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_GPIO, BUTTON_PIN);
|
return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_GPIO, BUTTON_PIN);
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int board_uart_read(uint8_t* buf, int len)
|
int board_uart_read(uint8_t* buf, int len) {
|
||||||
{
|
|
||||||
#if 0 /*
|
#if 0 /*
|
||||||
Use this version if want the LED to blink during BOARD=board_test,
|
Use this version if want the LED to blink during BOARD=board_test,
|
||||||
without having to hit a key.
|
without having to hit a key.
|
||||||
@ -151,21 +132,39 @@ int board_uart_read(uint8_t* buf, int len)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int board_uart_write(void const * buf, int len)
|
int board_uart_write(void const* buf, int len) {
|
||||||
{
|
|
||||||
LPUART_WriteBlocking(UART_PORT, (uint8_t const*) buf, len);
|
LPUART_WriteBlocking(UART_PORT, (uint8_t const*) buf, len);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
volatile uint32_t system_ticks = 0;
|
volatile uint32_t system_ticks = 0;
|
||||||
void SysTick_Handler(void)
|
|
||||||
{
|
void SysTick_Handler(void) {
|
||||||
system_ticks++;
|
system_ticks++;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t board_millis(void)
|
uint32_t board_millis(void) {
|
||||||
{
|
|
||||||
return system_ticks;
|
return system_ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __ICCARM__
|
||||||
|
// Implement _start() since we use linker flag '-nostartfiles'.
|
||||||
|
// Requires defined __STARTUP_CLEAR_BSS,
|
||||||
|
extern int main(void);
|
||||||
|
|
||||||
|
TU_ATTR_UNUSED void _start(void) {
|
||||||
|
// called by startup code
|
||||||
|
main();
|
||||||
|
while (1) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
void _exit (int __status) {
|
||||||
|
while (1) {}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
112
hw/bsp/kinetis_k32l2/family.cmake
Normal file
112
hw/bsp/kinetis_k32l2/family.cmake
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
include_guard()
|
||||||
|
|
||||||
|
set(SDK_DIR ${TOP}/hw/mcu/nxp/mcux-sdk)
|
||||||
|
set(CMSIS_DIR ${TOP}/lib/CMSIS_5)
|
||||||
|
|
||||||
|
# include board specific
|
||||||
|
include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake)
|
||||||
|
|
||||||
|
# toolchain set up
|
||||||
|
set(CMAKE_SYSTEM_PROCESSOR cortex-m0plus CACHE INTERNAL "System Processor")
|
||||||
|
set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake)
|
||||||
|
|
||||||
|
set(FAMILY_MCUS KINETIS_K32L CACHE INTERNAL "")
|
||||||
|
|
||||||
|
|
||||||
|
#------------------------------------
|
||||||
|
# BOARD_TARGET
|
||||||
|
#------------------------------------
|
||||||
|
# only need to be built ONCE for all examples
|
||||||
|
function(add_board_target BOARD_TARGET)
|
||||||
|
if (TARGET ${BOARD_TARGET})
|
||||||
|
return()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# LD_FILE and STARTUP_FILE can be defined in board.cmake
|
||||||
|
set(LD_FILE_Clang ${LD_FILE_GNU})
|
||||||
|
set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_VARIANT}.S)
|
||||||
|
set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU})
|
||||||
|
|
||||||
|
add_library(${BOARD_TARGET} STATIC
|
||||||
|
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||||
|
${SDK_DIR}/drivers/gpio/fsl_gpio.c
|
||||||
|
${SDK_DIR}/drivers/lpuart/fsl_lpuart.c
|
||||||
|
${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c
|
||||||
|
${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_VARIANT}.c
|
||||||
|
)
|
||||||
|
target_compile_definitions(${BOARD_TARGET} PUBLIC
|
||||||
|
__STARTUP_CLEAR_BSS
|
||||||
|
)
|
||||||
|
target_include_directories(${BOARD_TARGET} PUBLIC
|
||||||
|
${CMSIS_DIR}/CMSIS/Core/Include
|
||||||
|
${SDK_DIR}/devices/${MCU_VARIANT}
|
||||||
|
${SDK_DIR}/devices/${MCU_VARIANT}/drivers
|
||||||
|
${SDK_DIR}/drivers/common
|
||||||
|
${SDK_DIR}/drivers/gpio
|
||||||
|
${SDK_DIR}/drivers/lpuart
|
||||||
|
${SDK_DIR}/drivers/port
|
||||||
|
${SDK_DIR}/drivers/smc
|
||||||
|
)
|
||||||
|
|
||||||
|
update_board(${BOARD_TARGET})
|
||||||
|
|
||||||
|
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||||
|
target_link_options(${BOARD_TARGET} PUBLIC
|
||||||
|
"LINKER:--script=${LD_FILE_GNU}"
|
||||||
|
--specs=nosys.specs --specs=nano.specs
|
||||||
|
-nostartfiles
|
||||||
|
)
|
||||||
|
elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||||
|
target_link_options(${BOARD_TARGET} PUBLIC
|
||||||
|
"LINKER:--script=${LD_FILE_GNU}"
|
||||||
|
)
|
||||||
|
elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR")
|
||||||
|
target_link_options(${BOARD_TARGET} PUBLIC
|
||||||
|
"LINKER:--config=${LD_FILE_IAR}"
|
||||||
|
)
|
||||||
|
endif ()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
|
||||||
|
#------------------------------------
|
||||||
|
# Functions
|
||||||
|
#------------------------------------
|
||||||
|
function(family_configure_example TARGET RTOS)
|
||||||
|
family_configure_common(${TARGET} ${RTOS})
|
||||||
|
|
||||||
|
# Board target
|
||||||
|
add_board_target(board_${BOARD})
|
||||||
|
|
||||||
|
#---------- Port Specific ----------
|
||||||
|
# These files are built for each example since it depends on example's tusb_config.h
|
||||||
|
target_sources(${TARGET} PUBLIC
|
||||||
|
# BSP
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
||||||
|
)
|
||||||
|
target_include_directories(${TARGET} PUBLIC
|
||||||
|
# family, hw, board
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add TinyUSB target and port source
|
||||||
|
family_add_tinyusb(${TARGET} OPT_MCU_KINETIS_K32L ${RTOS})
|
||||||
|
target_sources(${TARGET}-tinyusb PUBLIC
|
||||||
|
${TOP}/src/portable/nxp/khci/dcd_khci.c
|
||||||
|
${TOP}/src/portable/nxp/khci/hcd_khci.c
|
||||||
|
)
|
||||||
|
target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD})
|
||||||
|
|
||||||
|
# Link dependencies
|
||||||
|
target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb)
|
||||||
|
|
||||||
|
# Flashing
|
||||||
|
family_flash_jlink(${TARGET})
|
||||||
|
|
||||||
|
if (DEFINED TEENSY_MCU)
|
||||||
|
family_add_bin_hex(${TARGET})
|
||||||
|
family_flash_teensy(${TARGET})
|
||||||
|
endif ()
|
||||||
|
endfunction()
|
@ -1,6 +1,5 @@
|
|||||||
UF2_FAMILY_ID = 0x7f83e793
|
UF2_FAMILY_ID = 0x7f83e793
|
||||||
SDK_DIR = hw/mcu/nxp/mcux-sdk
|
SDK_DIR = hw/mcu/nxp/mcux-sdk
|
||||||
DEPS_SUBMODULES += $(SDK_DIR) lib/CMSIS_5
|
|
||||||
MCU_DIR = $(SDK_DIR)/devices/$(MCU)
|
MCU_DIR = $(SDK_DIR)/devices/$(MCU)
|
||||||
|
|
||||||
include $(TOP)/$(BOARD_PATH)/board.mk
|
include $(TOP)/$(BOARD_PATH)/board.mk
|
||||||
@ -9,7 +8,9 @@ CPU_CORE ?= cortex-m0plus
|
|||||||
CFLAGS += \
|
CFLAGS += \
|
||||||
-DCFG_TUSB_MCU=OPT_MCU_KINETIS_K32L
|
-DCFG_TUSB_MCU=OPT_MCU_KINETIS_K32L
|
||||||
|
|
||||||
LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs
|
LDFLAGS_GCC += \
|
||||||
|
-nostartfiles \
|
||||||
|
-specs=nosys.specs -specs=nano.specs
|
||||||
|
|
||||||
SRC_C += \
|
SRC_C += \
|
||||||
src/portable/nxp/khci/dcd_khci.c \
|
src/portable/nxp/khci/dcd_khci.c \
|
||||||
@ -25,10 +26,10 @@ INC += \
|
|||||||
$(TOP)/$(MCU_DIR) \
|
$(TOP)/$(MCU_DIR) \
|
||||||
$(TOP)/$(MCU_DIR)/project_template \
|
$(TOP)/$(MCU_DIR)/project_template \
|
||||||
$(TOP)/$(MCU_DIR)/drivers \
|
$(TOP)/$(MCU_DIR)/drivers \
|
||||||
$(TOP)/$(SDK_DIR)/drivers/smc \
|
|
||||||
$(TOP)/$(SDK_DIR)/drivers/common \
|
$(TOP)/$(SDK_DIR)/drivers/common \
|
||||||
$(TOP)/$(SDK_DIR)/drivers/gpio \
|
$(TOP)/$(SDK_DIR)/drivers/gpio \
|
||||||
$(TOP)/$(SDK_DIR)/drivers/port \
|
|
||||||
$(TOP)/$(SDK_DIR)/drivers/lpuart \
|
$(TOP)/$(SDK_DIR)/drivers/lpuart \
|
||||||
|
$(TOP)/$(SDK_DIR)/drivers/port \
|
||||||
|
$(TOP)/$(SDK_DIR)/drivers/smc \
|
||||||
|
|
||||||
SRC_S += $(MCU_DIR)/gcc/startup_$(MCU).S
|
SRC_S += $(MCU_DIR)/gcc/startup_$(MCU).S
|
||||||
|
178
hw/bsp/lpc11/FreeRTOSConfig/FreeRTOSConfig.h
Normal file
178
hw/bsp/lpc11/FreeRTOSConfig/FreeRTOSConfig.h
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
/*
|
||||||
|
* FreeRTOS Kernel V10.0.0
|
||||||
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software. If you wish to use our Amazon
|
||||||
|
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* http://www.FreeRTOS.org
|
||||||
|
* http://aws.amazon.com/freertos
|
||||||
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef FREERTOS_CONFIG_H
|
||||||
|
#define FREERTOS_CONFIG_H
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Application specific definitions.
|
||||||
|
*
|
||||||
|
* These definitions should be adjusted for your particular hardware and
|
||||||
|
* application requirements.
|
||||||
|
*
|
||||||
|
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
|
||||||
|
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
|
||||||
|
*
|
||||||
|
* See http://www.freertos.org/a00110.html.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
// skip if included from IAR assembler
|
||||||
|
#ifndef __IASMARM__
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "chip.h"
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Cortex M23/M33 port configuration. */
|
||||||
|
#define configENABLE_MPU 0
|
||||||
|
#if defined(__ARM_FP) && __ARM_FP >= 4
|
||||||
|
#define configENABLE_FPU 1
|
||||||
|
#else
|
||||||
|
#define configENABLE_FPU 0
|
||||||
|
#endif
|
||||||
|
#define configENABLE_TRUSTZONE 0
|
||||||
|
#define configMINIMAL_SECURE_STACK_SIZE (1024)
|
||||||
|
|
||||||
|
#define configUSE_PREEMPTION 1
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||||
|
#define configCPU_CLOCK_HZ SystemCoreClock
|
||||||
|
#define configTICK_RATE_HZ ( 1000 )
|
||||||
|
#define configMAX_PRIORITIES ( 5 )
|
||||||
|
#define configMINIMAL_STACK_SIZE ( 128 )
|
||||||
|
#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 )
|
||||||
|
#define configMAX_TASK_NAME_LEN 16
|
||||||
|
#define configUSE_16_BIT_TICKS 0
|
||||||
|
#define configIDLE_SHOULD_YIELD 1
|
||||||
|
#define configUSE_MUTEXES 1
|
||||||
|
#define configUSE_RECURSIVE_MUTEXES 1
|
||||||
|
#define configUSE_COUNTING_SEMAPHORES 1
|
||||||
|
#define configQUEUE_REGISTRY_SIZE 2
|
||||||
|
#define configUSE_QUEUE_SETS 0
|
||||||
|
#define configUSE_TIME_SLICING 0
|
||||||
|
#define configUSE_NEWLIB_REENTRANT 0
|
||||||
|
#define configENABLE_BACKWARD_COMPATIBILITY 1
|
||||||
|
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
|
||||||
|
|
||||||
|
#define configSUPPORT_STATIC_ALLOCATION 1
|
||||||
|
#define configSUPPORT_DYNAMIC_ALLOCATION 0
|
||||||
|
|
||||||
|
/* Hook function related definitions. */
|
||||||
|
#define configUSE_IDLE_HOOK 0
|
||||||
|
#define configUSE_TICK_HOOK 0
|
||||||
|
#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning
|
||||||
|
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||||
|
|
||||||
|
/* Run time and task stats gathering related definitions. */
|
||||||
|
#define configGENERATE_RUN_TIME_STATS 0
|
||||||
|
#define configRECORD_STACK_HIGH_ADDRESS 1
|
||||||
|
#define configUSE_TRACE_FACILITY 1 // legacy trace
|
||||||
|
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
|
||||||
|
|
||||||
|
/* Co-routine definitions. */
|
||||||
|
#define configUSE_CO_ROUTINES 0
|
||||||
|
#define configMAX_CO_ROUTINE_PRIORITIES 2
|
||||||
|
|
||||||
|
/* Software timer related definitions. */
|
||||||
|
#define configUSE_TIMERS 1
|
||||||
|
#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2)
|
||||||
|
#define configTIMER_QUEUE_LENGTH 32
|
||||||
|
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
|
||||||
|
|
||||||
|
/* Optional functions - most linkers will remove unused functions anyway. */
|
||||||
|
#define INCLUDE_vTaskPrioritySet 0
|
||||||
|
#define INCLUDE_uxTaskPriorityGet 0
|
||||||
|
#define INCLUDE_vTaskDelete 0
|
||||||
|
#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY
|
||||||
|
#define INCLUDE_xResumeFromISR 0
|
||||||
|
#define INCLUDE_vTaskDelayUntil 1
|
||||||
|
#define INCLUDE_vTaskDelay 1
|
||||||
|
#define INCLUDE_xTaskGetSchedulerState 0
|
||||||
|
#define INCLUDE_xTaskGetCurrentTaskHandle 1
|
||||||
|
#define INCLUDE_uxTaskGetStackHighWaterMark 0
|
||||||
|
#define INCLUDE_xTaskGetIdleTaskHandle 0
|
||||||
|
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
|
||||||
|
#define INCLUDE_pcTaskGetTaskName 0
|
||||||
|
#define INCLUDE_eTaskGetState 0
|
||||||
|
#define INCLUDE_xEventGroupSetBitFromISR 0
|
||||||
|
#define INCLUDE_xTimerPendFunctionCall 0
|
||||||
|
|
||||||
|
/* Define to trap errors during development. */
|
||||||
|
// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7
|
||||||
|
#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__)
|
||||||
|
#define configASSERT(_exp) \
|
||||||
|
do {\
|
||||||
|
if ( !(_exp) ) { \
|
||||||
|
volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \
|
||||||
|
if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \
|
||||||
|
taskDISABLE_INTERRUPTS(); \
|
||||||
|
__asm("BKPT #0\n"); \
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
} while(0)
|
||||||
|
#else
|
||||||
|
#define configASSERT( x )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* FreeRTOS hooks to NVIC vectors */
|
||||||
|
#define xPortPendSVHandler PendSV_Handler
|
||||||
|
#define xPortSysTickHandler SysTick_Handler
|
||||||
|
#define vPortSVCHandler SVC_Handler
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Interrupt nesting behavior configuration.
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header
|
||||||
|
#define configPRIO_BITS 2
|
||||||
|
|
||||||
|
/* The lowest interrupt priority that can be used in a call to a "set priority" function. */
|
||||||
|
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<<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 /* __FREERTOS_CONFIG__H */
|
19
hw/bsp/lpc11/boards/lpcxpresso11u37/board.cmake
Normal file
19
hw/bsp/lpc11/boards/lpcxpresso11u37/board.cmake
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
set(LPC_FAMILY 11xx)
|
||||||
|
set(JLINK_DEVICE LPC11U37/401)
|
||||||
|
set(PYOCD_TARGET lpc11u37)
|
||||||
|
|
||||||
|
set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/lpc11u37.ld)
|
||||||
|
|
||||||
|
function(update_board TARGET)
|
||||||
|
target_compile_definitions(${TARGET} PUBLIC
|
||||||
|
CFG_EXAMPLE_MSC_READONLY
|
||||||
|
CFG_EXAMPLE_VIDEO_READONLY
|
||||||
|
)
|
||||||
|
target_sources(${TARGET} PRIVATE
|
||||||
|
${SDK_DIR}/src/gpio_${LPC_FAMILY}_1.c
|
||||||
|
${SDK_DIR}/src/sysctl_${LPC_FAMILY}.c
|
||||||
|
)
|
||||||
|
target_compile_options(${TARGET} PRIVATE
|
||||||
|
-Wno-error=unused-parameter
|
||||||
|
)
|
||||||
|
endfunction()
|
98
hw/bsp/lpc11/boards/lpcxpresso11u37/board.h
Normal file
98
hw/bsp/lpc11/boards/lpcxpresso11u37/board.h
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
#ifndef BOARD_H
|
||||||
|
#define BOARD_H
|
||||||
|
|
||||||
|
#define LED_PORT 1
|
||||||
|
#define LED_PIN 24
|
||||||
|
#define LED_STATE_ON 0
|
||||||
|
|
||||||
|
// Wake up Switch
|
||||||
|
#define BUTTON_PORT 0
|
||||||
|
#define BUTTON_PIN 16
|
||||||
|
#define BUTTON_STATE_ACTIVE 0
|
||||||
|
|
||||||
|
/* System oscillator rate and RTC oscillator rate */
|
||||||
|
const uint32_t OscRateIn = 12000000;
|
||||||
|
const uint32_t ExtRateIn = 0;
|
||||||
|
|
||||||
|
/* Pin muxing table, only items that need changing from their default pin
|
||||||
|
state are in this table. Not every pin is mapped. */
|
||||||
|
/* IOCON pin definitions for pin muxing */
|
||||||
|
typedef struct {
|
||||||
|
uint32_t port : 8; /* Pin port */
|
||||||
|
uint32_t pin : 8; /* Pin number */
|
||||||
|
uint32_t modefunc : 16; /* Function and mode */
|
||||||
|
} PINMUX_GRP_T;
|
||||||
|
|
||||||
|
static const PINMUX_GRP_T pinmuxing[] = {
|
||||||
|
{0, 3, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, // USB VBUS
|
||||||
|
{0, 6, (IOCON_FUNC1 | IOCON_MODE_INACT)}, /* PIO0_6 used for USB_CONNECT */
|
||||||
|
|
||||||
|
{0, 18, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, // UART0 RX
|
||||||
|
{0, 19, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, // UART0 TX
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Setup system clocking */
|
||||||
|
static inline void Chip_SetupXtalClocking(void) {
|
||||||
|
volatile int i;
|
||||||
|
|
||||||
|
/* Powerup main oscillator */
|
||||||
|
Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_SYSOSC_PD);
|
||||||
|
|
||||||
|
/* Wait 200us for OSC to be stablized, no status
|
||||||
|
indication, dummy wait. */
|
||||||
|
for (i = 0; i < 0x100; i++) {}
|
||||||
|
|
||||||
|
/* Set system PLL input to main oscillator */
|
||||||
|
Chip_Clock_SetSystemPLLSource(SYSCTL_PLLCLKSRC_MAINOSC);
|
||||||
|
|
||||||
|
/* Power down PLL to change the PLL divider ratio */
|
||||||
|
Chip_SYSCTL_PowerDown(SYSCTL_POWERDOWN_SYSPLL_PD);
|
||||||
|
|
||||||
|
/* Setup PLL for main oscillator rate (FCLKIN = 12MHz) * 4 = 48MHz
|
||||||
|
MSEL = 3 (this is pre-decremented), PSEL = 1 (for P = 2)
|
||||||
|
FCLKOUT = FCLKIN * (MSEL + 1) = 12MHz * 4 = 48MHz
|
||||||
|
FCCO = FCLKOUT * 2 * P = 48MHz * 2 * 2 = 192MHz (within FCCO range) */
|
||||||
|
Chip_Clock_SetupSystemPLL(3, 1);
|
||||||
|
|
||||||
|
/* Powerup system PLL */
|
||||||
|
Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_SYSPLL_PD);
|
||||||
|
|
||||||
|
/* Wait for PLL to lock */
|
||||||
|
while (!Chip_Clock_IsSystemPLLLocked()) {}
|
||||||
|
|
||||||
|
/* Set system clock divider to 1 */
|
||||||
|
Chip_Clock_SetSysClockDiv(1);
|
||||||
|
|
||||||
|
/* Setup FLASH access to 3 clocks */
|
||||||
|
Chip_FMC_SetFLASHAccess(FLASHTIM_50MHZ_CPU);
|
||||||
|
|
||||||
|
/* Set main clock source to the system PLL. This will drive 48MHz
|
||||||
|
for the main clock and 48MHz for the system clock */
|
||||||
|
Chip_Clock_SetMainClockSource(SYSCTL_MAINCLKSRC_PLLOUT);
|
||||||
|
|
||||||
|
/* Set USB PLL input to main oscillator */
|
||||||
|
Chip_Clock_SetUSBPLLSource(SYSCTL_PLLCLKSRC_MAINOSC);
|
||||||
|
/* Setup USB PLL (FCLKIN = 12MHz) * 4 = 48MHz
|
||||||
|
MSEL = 3 (this is pre-decremented), PSEL = 1 (for P = 2)
|
||||||
|
FCLKOUT = FCLKIN * (MSEL + 1) = 12MHz * 4 = 48MHz
|
||||||
|
FCCO = FCLKOUT * 2 * P = 48MHz * 2 * 2 = 192MHz (within FCCO range) */
|
||||||
|
Chip_Clock_SetupUSBPLL(3, 1);
|
||||||
|
|
||||||
|
/* Powerup USB PLL */
|
||||||
|
Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_USBPLL_PD);
|
||||||
|
|
||||||
|
/* Wait for PLL to lock */
|
||||||
|
while (!Chip_Clock_IsUSBPLLLocked()) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void Chip_USB_Init(void) {
|
||||||
|
/* enable USB main clock */
|
||||||
|
Chip_Clock_SetUSBClockSource(SYSCTL_USBCLKSRC_PLLOUT, 1);
|
||||||
|
/* Enable AHB clock to the USB block and USB RAM. */
|
||||||
|
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_USB);
|
||||||
|
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_USBRAM);
|
||||||
|
/* power UP USB Phy */
|
||||||
|
Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_USBPAD_PD);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -1,208 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* This file is part of the TinyUSB stack.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "chip.h"
|
|
||||||
#include "bsp/board_api.h"
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
// Forward USB interrupt events to TinyUSB IRQ Handler
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
void USB_IRQHandler(void)
|
|
||||||
{
|
|
||||||
tud_int_handler(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------- ----+
|
|
||||||
// MACRO TYPEDEF CONSTANT ENUM
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
#define LED_PORT 1
|
|
||||||
#define LED_PIN 24
|
|
||||||
#define LED_STATE_ON 0
|
|
||||||
|
|
||||||
// Wake up Switch
|
|
||||||
#define BUTTON_PORT 0
|
|
||||||
#define BUTTON_PIN 16
|
|
||||||
#define BUTTON_STATE_ACTIVE 0
|
|
||||||
|
|
||||||
/* System oscillator rate and RTC oscillator rate */
|
|
||||||
const uint32_t OscRateIn = 12000000;
|
|
||||||
const uint32_t ExtRateIn = 0;
|
|
||||||
|
|
||||||
/* Pin muxing table, only items that need changing from their default pin
|
|
||||||
state are in this table. Not every pin is mapped. */
|
|
||||||
/* IOCON pin definitions for pin muxing */
|
|
||||||
typedef struct {
|
|
||||||
uint32_t port : 8; /* Pin port */
|
|
||||||
uint32_t pin : 8; /* Pin number */
|
|
||||||
uint32_t modefunc : 16; /* Function and mode */
|
|
||||||
} PINMUX_GRP_T;
|
|
||||||
|
|
||||||
static const PINMUX_GRP_T pinmuxing[] =
|
|
||||||
{
|
|
||||||
{0, 3, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, // USB VBUS
|
|
||||||
{0, 6, (IOCON_FUNC1 | IOCON_MODE_INACT)}, /* PIO0_6 used for USB_CONNECT */
|
|
||||||
|
|
||||||
{0, 18, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, // UART0 RX
|
|
||||||
{0, 19, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, // UART0 TX
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Setup system clocking */
|
|
||||||
static void SystemSetupClocking(void)
|
|
||||||
{
|
|
||||||
volatile int i;
|
|
||||||
|
|
||||||
/* Powerup main oscillator */
|
|
||||||
Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_SYSOSC_PD);
|
|
||||||
|
|
||||||
/* Wait 200us for OSC to be stablized, no status
|
|
||||||
indication, dummy wait. */
|
|
||||||
for (i = 0; i < 0x100; i++) {}
|
|
||||||
|
|
||||||
/* Set system PLL input to main oscillator */
|
|
||||||
Chip_Clock_SetSystemPLLSource(SYSCTL_PLLCLKSRC_MAINOSC);
|
|
||||||
|
|
||||||
/* Power down PLL to change the PLL divider ratio */
|
|
||||||
Chip_SYSCTL_PowerDown(SYSCTL_POWERDOWN_SYSPLL_PD);
|
|
||||||
|
|
||||||
/* Setup PLL for main oscillator rate (FCLKIN = 12MHz) * 4 = 48MHz
|
|
||||||
MSEL = 3 (this is pre-decremented), PSEL = 1 (for P = 2)
|
|
||||||
FCLKOUT = FCLKIN * (MSEL + 1) = 12MHz * 4 = 48MHz
|
|
||||||
FCCO = FCLKOUT * 2 * P = 48MHz * 2 * 2 = 192MHz (within FCCO range) */
|
|
||||||
Chip_Clock_SetupSystemPLL(3, 1);
|
|
||||||
|
|
||||||
/* Powerup system PLL */
|
|
||||||
Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_SYSPLL_PD);
|
|
||||||
|
|
||||||
/* Wait for PLL to lock */
|
|
||||||
while (!Chip_Clock_IsSystemPLLLocked()) {}
|
|
||||||
|
|
||||||
/* Set system clock divider to 1 */
|
|
||||||
Chip_Clock_SetSysClockDiv(1);
|
|
||||||
|
|
||||||
/* Setup FLASH access to 3 clocks */
|
|
||||||
Chip_FMC_SetFLASHAccess(FLASHTIM_50MHZ_CPU);
|
|
||||||
|
|
||||||
/* Set main clock source to the system PLL. This will drive 48MHz
|
|
||||||
for the main clock and 48MHz for the system clock */
|
|
||||||
Chip_Clock_SetMainClockSource(SYSCTL_MAINCLKSRC_PLLOUT);
|
|
||||||
|
|
||||||
/* Set USB PLL input to main oscillator */
|
|
||||||
Chip_Clock_SetUSBPLLSource(SYSCTL_PLLCLKSRC_MAINOSC);
|
|
||||||
/* Setup USB PLL (FCLKIN = 12MHz) * 4 = 48MHz
|
|
||||||
MSEL = 3 (this is pre-decremented), PSEL = 1 (for P = 2)
|
|
||||||
FCLKOUT = FCLKIN * (MSEL + 1) = 12MHz * 4 = 48MHz
|
|
||||||
FCCO = FCLKOUT * 2 * P = 48MHz * 2 * 2 = 192MHz (within FCCO range) */
|
|
||||||
Chip_Clock_SetupUSBPLL(3, 1);
|
|
||||||
|
|
||||||
/* Powerup USB PLL */
|
|
||||||
Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_USBPLL_PD);
|
|
||||||
|
|
||||||
/* Wait for PLL to lock */
|
|
||||||
while (!Chip_Clock_IsUSBPLLLocked()) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invoked by startup code
|
|
||||||
void SystemInit(void)
|
|
||||||
{
|
|
||||||
SystemSetupClocking();
|
|
||||||
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_RAM1);
|
|
||||||
|
|
||||||
/* Enable IOCON clock */
|
|
||||||
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_IOCON);
|
|
||||||
for (uint32_t i = 0; i < (sizeof(pinmuxing) / sizeof(PINMUX_GRP_T)); i++)
|
|
||||||
{
|
|
||||||
Chip_IOCON_PinMuxSet(LPC_IOCON, pinmuxing[i].port, pinmuxing[i].pin, pinmuxing[i].modefunc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void board_init(void)
|
|
||||||
{
|
|
||||||
SystemCoreClockUpdate();
|
|
||||||
|
|
||||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
|
||||||
// 1ms tick timer
|
|
||||||
SysTick_Config(SystemCoreClock / 1000);
|
|
||||||
#elif CFG_TUSB_OS == OPT_OS_FREERTOS
|
|
||||||
// If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher )
|
|
||||||
NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Chip_GPIO_Init(LPC_GPIO);
|
|
||||||
|
|
||||||
// LED
|
|
||||||
Chip_GPIO_SetPinDIROutput(LPC_GPIO, LED_PORT, LED_PIN);
|
|
||||||
|
|
||||||
// Button
|
|
||||||
Chip_GPIO_SetPinDIRInput(LPC_GPIO, BUTTON_PORT, BUTTON_PIN);
|
|
||||||
|
|
||||||
// USB: Setup PLL clock, and power
|
|
||||||
/* enable USB main clock */
|
|
||||||
Chip_Clock_SetUSBClockSource(SYSCTL_USBCLKSRC_PLLOUT, 1);
|
|
||||||
/* Enable AHB clock to the USB block and USB RAM. */
|
|
||||||
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_USB);
|
|
||||||
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_USBRAM);
|
|
||||||
/* power UP USB Phy */
|
|
||||||
Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_USBPAD_PD);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
// Board porting API
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
|
|
||||||
void board_led_write(bool state)
|
|
||||||
{
|
|
||||||
Chip_GPIO_SetPinState(LPC_GPIO, LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON));
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t board_button_read(void)
|
|
||||||
{
|
|
||||||
return BUTTON_STATE_ACTIVE == Chip_GPIO_GetPinState(LPC_GPIO, BUTTON_PORT, BUTTON_PIN);
|
|
||||||
}
|
|
||||||
|
|
||||||
int board_uart_read(uint8_t* buf, int len)
|
|
||||||
{
|
|
||||||
(void) buf; (void) len;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int board_uart_write(void const * buf, int len)
|
|
||||||
{
|
|
||||||
(void) buf; (void) len;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
|
||||||
volatile uint32_t system_ticks = 0;
|
|
||||||
void SysTick_Handler (void)
|
|
||||||
{
|
|
||||||
system_ticks++;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t board_millis(void)
|
|
||||||
{
|
|
||||||
return system_ticks;
|
|
||||||
}
|
|
||||||
#endif
|
|
12
hw/bsp/lpc11/boards/lpcxpresso11u68/board.cmake
Normal file
12
hw/bsp/lpc11/boards/lpcxpresso11u68/board.cmake
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
set(LPC_FAMILY 11u6x)
|
||||||
|
set(JLINK_DEVICE LPC11U68)
|
||||||
|
set(PYOCD_TARGET LPC11U68)
|
||||||
|
|
||||||
|
set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/lpc11u68.ld)
|
||||||
|
|
||||||
|
function(update_board TARGET)
|
||||||
|
target_sources(${TARGET} PUBLIC
|
||||||
|
${SDK_DIR}/src/gpio_${LPC_FAMILY}.c
|
||||||
|
${SDK_DIR}/src/syscon_${LPC_FAMILY}.c
|
||||||
|
)
|
||||||
|
endfunction()
|
27
hw/bsp/lpc11/boards/lpcxpresso11u68/board.h
Normal file
27
hw/bsp/lpc11/boards/lpcxpresso11u68/board.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#ifndef BOARD_H
|
||||||
|
#define BOARD_H
|
||||||
|
|
||||||
|
#define LED_PORT 2
|
||||||
|
#define LED_PIN 17
|
||||||
|
#define LED_STATE_ON 0
|
||||||
|
|
||||||
|
// Wake up Switch
|
||||||
|
#define BUTTON_PORT 0
|
||||||
|
#define BUTTON_PIN 16
|
||||||
|
#define BUTTON_STATE_ACTIVE 0
|
||||||
|
|
||||||
|
/* System oscillator rate and RTC oscillator rate */
|
||||||
|
const uint32_t OscRateIn = 12000000;
|
||||||
|
const uint32_t RTCOscRateIn = 32768;
|
||||||
|
|
||||||
|
/* Pin muxing table, only items that need changing from their default pin
|
||||||
|
state are in this table. Not every pin is mapped. */
|
||||||
|
static const PINMUX_GRP_T pinmuxing[] = {
|
||||||
|
{0, 3, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, // USB VBUS
|
||||||
|
{0, 18, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, // UART0 RX
|
||||||
|
{0, 19, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, // UART0 TX
|
||||||
|
{2, 0, (IOCON_FUNC1 | IOCON_MODE_INACT)}, // XTALIN
|
||||||
|
{2, 1, (IOCON_FUNC1 | IOCON_MODE_INACT)}, // XTALOUT
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -5,7 +5,6 @@ CFLAGS += \
|
|||||||
-DCORE_M0PLUS \
|
-DCORE_M0PLUS \
|
||||||
-D__VTOR_PRESENT=0 \
|
-D__VTOR_PRESENT=0 \
|
||||||
-DCFG_TUSB_MEM_SECTION='__attribute__((section(".data.$$RAM3")))' \
|
-DCFG_TUSB_MEM_SECTION='__attribute__((section(".data.$$RAM3")))' \
|
||||||
-DCFG_TUSB_MEM_ALIGN='__attribute__((aligned(64)))'
|
|
||||||
|
|
||||||
# All source paths should be relative to the top level.
|
# All source paths should be relative to the top level.
|
||||||
LD_FILE = $(BOARD_PATH)/lpc11u68.ld
|
LD_FILE = $(BOARD_PATH)/lpc11u68.ld
|
||||||
|
@ -24,55 +24,42 @@
|
|||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "chip.h"
|
#include "chip.h"
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "bsp/board_api.h"
|
#include "bsp/board_api.h"
|
||||||
|
#include "board.h"
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Forward USB interrupt events to TinyUSB IRQ Handler
|
// Forward USB interrupt events to TinyUSB IRQ Handler
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
void USB_IRQHandler(void)
|
void USB_IRQHandler(void) {
|
||||||
{
|
|
||||||
tud_int_handler(0);
|
tud_int_handler(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// MACRO TYPEDEF CONSTANT ENUM
|
// MACRO TYPEDEF CONSTANT ENUM
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
#define LED_PORT 2
|
|
||||||
#define LED_PIN 17
|
|
||||||
#define LED_STATE_ON 0
|
|
||||||
|
|
||||||
// Wake up Switch
|
|
||||||
#define BUTTON_PORT 0
|
|
||||||
#define BUTTON_PIN 16
|
|
||||||
#define BUTTON_STATE_ACTIVE 0
|
|
||||||
|
|
||||||
/* System oscillator rate and RTC oscillator rate */
|
|
||||||
const uint32_t OscRateIn = 12000000;
|
|
||||||
const uint32_t RTCOscRateIn = 32768;
|
|
||||||
|
|
||||||
/* Pin muxing table, only items that need changing from their default pin
|
|
||||||
state are in this table. Not every pin is mapped. */
|
|
||||||
static const PINMUX_GRP_T pinmuxing[] =
|
|
||||||
{
|
|
||||||
{0, 3, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, // USB VBUS
|
|
||||||
{0, 18, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, // UART0 RX
|
|
||||||
{0, 19, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)}, // UART0 TX
|
|
||||||
{2, 0, (IOCON_FUNC1 | IOCON_MODE_INACT)}, // XTALIN
|
|
||||||
{2, 1, (IOCON_FUNC1 | IOCON_MODE_INACT)}, // XTALOUT
|
|
||||||
};
|
|
||||||
|
|
||||||
// Invoked by startup code
|
// Invoked by startup code
|
||||||
void SystemInit(void)
|
void SystemInit(void) {
|
||||||
{
|
|
||||||
/* Enable IOCON clock */
|
/* Enable IOCON clock */
|
||||||
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_IOCON);
|
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_IOCON);
|
||||||
Chip_IOCON_SetPinMuxing(LPC_IOCON, pinmuxing, sizeof(pinmuxing) / sizeof(PINMUX_GRP_T));
|
for (uint32_t i = 0; i < (sizeof(pinmuxing) / sizeof(PINMUX_GRP_T)); i++) {
|
||||||
|
Chip_IOCON_PinMuxSet(LPC_IOCON, pinmuxing[i].port, pinmuxing[i].pin, pinmuxing[i].modefunc);
|
||||||
|
}
|
||||||
Chip_SetupXtalClocking();
|
Chip_SetupXtalClocking();
|
||||||
}
|
}
|
||||||
|
|
||||||
void board_init(void)
|
void board_init(void) {
|
||||||
{
|
|
||||||
SystemCoreClockUpdate();
|
SystemCoreClockUpdate();
|
||||||
|
|
||||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
@ -99,37 +86,35 @@ void board_init(void)
|
|||||||
// Board porting API
|
// Board porting API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
void board_led_write(bool state)
|
void board_led_write(bool state) {
|
||||||
{
|
Chip_GPIO_SetPinState(LPC_GPIO, LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON));
|
||||||
Chip_GPIO_SetPinState(LPC_GPIO, LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t board_button_read(void)
|
uint32_t board_button_read(void) {
|
||||||
{
|
|
||||||
return BUTTON_STATE_ACTIVE == Chip_GPIO_GetPinState(LPC_GPIO, BUTTON_PORT, BUTTON_PIN);
|
return BUTTON_STATE_ACTIVE == Chip_GPIO_GetPinState(LPC_GPIO, BUTTON_PORT, BUTTON_PIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
int board_uart_read(uint8_t* buf, int len)
|
int board_uart_read(uint8_t* buf, int len) {
|
||||||
{
|
(void) buf;
|
||||||
(void) buf; (void) len;
|
(void) len;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int board_uart_write(void const * buf, int len)
|
int board_uart_write(void const* buf, int len) {
|
||||||
{
|
(void) buf;
|
||||||
(void) buf; (void) len;
|
(void) len;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
volatile uint32_t system_ticks = 0;
|
volatile uint32_t system_ticks = 0;
|
||||||
void SysTick_Handler (void)
|
|
||||||
{
|
void SysTick_Handler(void) {
|
||||||
system_ticks++;
|
system_ticks++;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t board_millis(void)
|
uint32_t board_millis(void) {
|
||||||
{
|
|
||||||
return system_ticks;
|
return system_ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
104
hw/bsp/lpc11/family.cmake
Normal file
104
hw/bsp/lpc11/family.cmake
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
include_guard()
|
||||||
|
|
||||||
|
# include board specific
|
||||||
|
include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake)
|
||||||
|
|
||||||
|
set(CMSIS_DIR ${TOP}/lib/CMSIS_5)
|
||||||
|
if (LPC_FAMILY STREQUAL 11xx)
|
||||||
|
set(SDK_DIR ${TOP}/hw/mcu/nxp/lpcopen/lpc11uxx/lpc_chip_11uxx)
|
||||||
|
else()
|
||||||
|
set(SDK_DIR ${TOP}/hw/mcu/nxp/lpcopen/lpc${LPC_FAMILY}/lpc_chip_${LPC_FAMILY})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# toolchain set up
|
||||||
|
set(CMAKE_SYSTEM_PROCESSOR cortex-m0plus CACHE INTERNAL "System Processor")
|
||||||
|
set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake)
|
||||||
|
|
||||||
|
set(FAMILY_MCUS LPC11UXX CACHE INTERNAL "")
|
||||||
|
|
||||||
|
|
||||||
|
#------------------------------------
|
||||||
|
# BOARD_TARGET
|
||||||
|
#------------------------------------
|
||||||
|
# only need to be built ONCE for all examples
|
||||||
|
function(add_board_target BOARD_TARGET)
|
||||||
|
if (TARGET ${BOARD_TARGET})
|
||||||
|
return()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
add_library(${BOARD_TARGET} STATIC
|
||||||
|
${SDK_DIR}/../gcc/cr_startup_lpc${LPC_FAMILY}.c
|
||||||
|
${SDK_DIR}/src/chip_${LPC_FAMILY}.c
|
||||||
|
${SDK_DIR}/src/clock_${LPC_FAMILY}.c
|
||||||
|
${SDK_DIR}/src/iocon_${LPC_FAMILY}.c
|
||||||
|
${SDK_DIR}/src/sysinit_${LPC_FAMILY}.c
|
||||||
|
)
|
||||||
|
target_compile_definitions(${BOARD_TARGET} PUBLIC
|
||||||
|
__USE_LPCOPEN
|
||||||
|
__VTOR_PRESENT=0
|
||||||
|
CORE_M0
|
||||||
|
CORE_M0PLUS
|
||||||
|
CFG_TUSB_MEM_ALIGN=TU_ATTR_ALIGNED\(64\)
|
||||||
|
)
|
||||||
|
target_include_directories(${BOARD_TARGET} PUBLIC
|
||||||
|
${SDK_DIR}/inc
|
||||||
|
${CMSIS_DIR}/CMSIS/Core/Include
|
||||||
|
)
|
||||||
|
|
||||||
|
update_board(${BOARD_TARGET})
|
||||||
|
|
||||||
|
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||||
|
target_compile_options(${BOARD_TARGET} PUBLIC -nostdlib)
|
||||||
|
target_link_options(${BOARD_TARGET} PUBLIC
|
||||||
|
"LINKER:--script=${LD_FILE_GNU}"
|
||||||
|
--specs=nosys.specs --specs=nano.specs
|
||||||
|
)
|
||||||
|
elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||||
|
target_link_options(${BOARD_TARGET} PUBLIC
|
||||||
|
"LINKER:--script=${LD_FILE_GNU}"
|
||||||
|
)
|
||||||
|
elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR")
|
||||||
|
target_link_options(${BOARD_TARGET} PUBLIC
|
||||||
|
"LINKER:--config=${LD_FILE_IAR}"
|
||||||
|
)
|
||||||
|
endif ()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
|
||||||
|
#------------------------------------
|
||||||
|
# Functions
|
||||||
|
#------------------------------------
|
||||||
|
function(family_configure_example TARGET RTOS)
|
||||||
|
family_configure_common(${TARGET} ${RTOS})
|
||||||
|
|
||||||
|
# Board target
|
||||||
|
add_board_target(board_${BOARD})
|
||||||
|
|
||||||
|
#---------- Port Specific ----------
|
||||||
|
# These files are built for each example since it depends on example's tusb_config.h
|
||||||
|
target_sources(${TARGET} PUBLIC
|
||||||
|
# BSP
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
||||||
|
)
|
||||||
|
target_include_directories(${TARGET} PUBLIC
|
||||||
|
# family, hw, board
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../
|
||||||
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add TinyUSB target and port source
|
||||||
|
family_add_tinyusb(${TARGET} OPT_MCU_LPC11UXX ${RTOS})
|
||||||
|
target_sources(${TARGET}-tinyusb PUBLIC
|
||||||
|
${TOP}/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c
|
||||||
|
)
|
||||||
|
target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD})
|
||||||
|
|
||||||
|
# Link dependencies
|
||||||
|
target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb)
|
||||||
|
|
||||||
|
# Flashing
|
||||||
|
family_flash_jlink(${TARGET})
|
||||||
|
#family_flash_nxplink(${TARGET})
|
||||||
|
endfunction()
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user