Przeglądaj źródła

Merge remote-tracking branch 'hathach/master'

tfx2001 3 lat temu
rodzic
commit
0533f79b41
100 zmienionych plików z 2330 dodań i 435 usunięć
  1. 1 0
      .codespell/exclude-file.txt
  2. 8 0
      .codespell/ignore-words.txt
  3. 10 0
      .codespellrc
  4. 9 1
      .github/ISSUE_TEMPLATE/bug_report.yml
  5. 0 14
      .github/ISSUE_TEMPLATE/feature_request.md
  6. 49 0
      .github/ISSUE_TEMPLATE/feature_request.yml
  7. 20 6
      .github/workflows/build_aarch64.yml
  8. 108 30
      .github/workflows/build_arm.yml
  9. 23 8
      .github/workflows/build_esp.yml
  10. 25 9
      .github/workflows/build_msp430.yml
  11. 24 9
      .github/workflows/build_renesas.yml
  12. 24 9
      .github/workflows/build_riscv.yml
  13. 48 0
      .github/workflows/pre-commit.yml
  14. 94 0
      .github/workflows/test_hardware.yml
  15. 3 1
      .github/workflows/trigger.yml
  16. 4 4
      README.rst
  17. 1 1
      docs/contributing/index.rst
  18. 2 2
      docs/contributing/porting.rst
  19. 68 11
      docs/info/changelog.rst
  20. 9 10
      docs/reference/getting_started.rst
  21. 10 1
      docs/reference/supported.rst
  22. 0 3
      examples/device/audio_4_channel_mic/CMakeLists.txt
  23. 0 3
      examples/device/audio_test/CMakeLists.txt
  24. 0 3
      examples/device/board_test/CMakeLists.txt
  25. 8 1
      examples/device/board_test/src/main.c
  26. 0 3
      examples/device/cdc_dual_ports/CMakeLists.txt
  27. 0 3
      examples/device/cdc_msc/CMakeLists.txt
  28. 1 1
      examples/device/cdc_msc/src/main.c
  29. 1 1
      examples/device/cdc_msc_freertos/CMakeLists.txt
  30. 9 2
      examples/device/cdc_msc_freertos/Makefile
  31. 1 1
      examples/device/cdc_msc_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h
  32. 16 8
      examples/device/cdc_msc_freertos/src/main.c
  33. 0 3
      examples/device/dfu/CMakeLists.txt
  34. 0 3
      examples/device/dfu_runtime/CMakeLists.txt
  35. 1 1
      examples/device/dfu_runtime/src/main.c
  36. 0 3
      examples/device/dynamic_configuration/CMakeLists.txt
  37. 0 3
      examples/device/hid_boot_interface/CMakeLists.txt
  38. 4 4
      examples/device/hid_boot_interface/src/main.c
  39. 0 3
      examples/device/hid_composite/CMakeLists.txt
  40. 1 1
      examples/device/hid_composite/src/main.c
  41. 9 2
      examples/device/hid_composite_freertos/Makefile
  42. 4 3
      examples/device/hid_composite_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h
  43. 17 9
      examples/device/hid_composite_freertos/src/main.c
  44. 0 3
      examples/device/hid_generic_inout/CMakeLists.txt
  45. 2 2
      examples/device/hid_generic_inout/hid_test.py
  46. 0 3
      examples/device/hid_multiple_interface/CMakeLists.txt
  47. 0 3
      examples/device/midi_test/CMakeLists.txt
  48. 0 3
      examples/device/msc_dual_lun/CMakeLists.txt
  49. 0 3
      examples/device/net_lwip_webserver/CMakeLists.txt
  50. 0 3
      examples/device/uac2_headset/CMakeLists.txt
  51. 2 1
      examples/device/uac2_headset/skip.txt
  52. 0 3
      examples/device/usbtmc/CMakeLists.txt
  53. 59 11
      examples/device/usbtmc/src/usb_descriptors.c
  54. 19 16
      examples/device/usbtmc/visaQuery.py
  55. 6 3
      examples/device/video_capture/CMakeLists.txt
  56. 7 0
      examples/device/video_capture/Makefile
  57. 285 0
      examples/device/video_capture/src/images.h
  58. 27 2
      examples/device/video_capture/src/main.c
  59. 14 4
      examples/device/video_capture/src/usb_descriptors.c
  60. 62 7
      examples/device/video_capture/src/usb_descriptors.h
  61. 0 3
      examples/device/webusb_serial/CMakeLists.txt
  62. 4 2
      examples/device/webusb_serial/src/main.c
  63. 4 7
      examples/dual/host_hid_to_device_cdc/CMakeLists.txt
  64. 0 31
      examples/example.cmake
  65. 2 0
      examples/host/CMakeLists.txt
  66. 11 5
      examples/host/bare_api/CMakeLists.txt
  67. 0 3
      examples/host/bare_api/Makefile
  68. 6 0
      examples/host/bare_api/src/tusb_config.h
  69. 12 5
      examples/host/cdc_msc_hid/CMakeLists.txt
  70. 6 4
      examples/host/cdc_msc_hid/Makefile
  71. 113 0
      examples/host/cdc_msc_hid/src/cdc_app.c
  72. 1 1
      examples/host/cdc_msc_hid/src/hid_app.c
  73. 3 34
      examples/host/cdc_msc_hid/src/main.c
  74. 5 40
      examples/host/cdc_msc_hid/src/msc_app.c
  75. 17 0
      examples/host/cdc_msc_hid/src/tusb_config.h
  76. 11 5
      examples/host/hid_controller/CMakeLists.txt
  77. 0 3
      examples/host/hid_controller/Makefile
  78. 0 1
      examples/host/hid_controller/src/hid_app.c
  79. 6 0
      examples/host/hid_controller/src/tusb_config.h
  80. 45 0
      examples/host/msc_file_explorer/CMakeLists.txt
  81. 38 0
      examples/host/msc_file_explorer/Makefile
  82. 11 0
      examples/host/msc_file_explorer/only.txt
  83. 95 0
      examples/host/msc_file_explorer/src/main.c
  84. 640 0
      examples/host/msc_file_explorer/src/msc_app.c
  85. 114 0
      examples/host/msc_file_explorer/src/tusb_config.h
  86. 2 1
      examples/make.mk
  87. 1 1
      hw/bsp/ansi_escape.h
  88. 11 2
      hw/bsp/board.c
  89. 4 10
      hw/bsp/board.h
  90. 3 0
      hw/bsp/board_mcu.h
  91. 1 3
      hw/bsp/ea4357/ea4357.c
  92. 1 1
      hw/bsp/esp32s2/components/led_strip/src/led_strip_rmt_ws2812.c
  93. 1 1
      hw/bsp/esp32s3/components/led_strip/src/led_strip_rmt_ws2812.c
  94. 44 2
      hw/bsp/family_support.cmake
  95. 2 2
      hw/bsp/gd32vf103/family.c
  96. 1 1
      hw/bsp/gd32vf103/system_gd32vf103.c
  97. 5 5
      hw/bsp/imxrt/boards/mimxrt1010_evk/evkmimxrt1010_flexspi_nor_config.h
  98. 5 5
      hw/bsp/imxrt/boards/mimxrt1015_evk/evkmimxrt1015_flexspi_nor_config.h
  99. 5 5
      hw/bsp/imxrt/boards/mimxrt1020_evk/evkmimxrt1020_flexspi_nor_config.h
  100. 5 5
      hw/bsp/imxrt/boards/mimxrt1050_evkb/evkbimxrt1050_flexspi_nor_config.h

+ 1 - 0
.codespell/exclude-file.txt

@@ -0,0 +1 @@
+  return USB0.INTSTS1.BIT.ATTCH ? true : false;

+ 8 - 0
.codespell/ignore-words.txt

@@ -0,0 +1,8 @@
+synopsys
+sie
+tre
+hsi
+fro
+dout
+mot
+te

+ 10 - 0
.codespellrc

@@ -0,0 +1,10 @@
+# See: https://github.com/codespell-project/codespell#using-a-config-file
+[codespell]
+# In the event of a false positive, add the problematic word, in all lowercase, to 'ignore-words.txt' (one word per line).
+# Or copy & paste the whole problematic line to 'exclude-file.txt'
+ignore-words = .codespell/ignore-words.txt
+exclude-file = .codespell/exclude-file.txt
+check-filenames =
+check-hidden =
+count =
+skip = .cproject,./.git,./hw/mcu,./lib,./examples/*/*/_build,./examples/*/*/ses,./examples/*/*/ozone,./hw/mcu,./test/unit-test/vendor,./tests_obsolete,./tools/uf2

+ 9 - 1
.github/ISSUE_TEMPLATE/bug_report.yml

@@ -64,7 +64,7 @@ body:
       placeholder: |
         Attach your debug log txt file here, where the issue occurred, best with comments to explain the actual events.
         
-        Note1: Please DO NOT paste your lengthy log contents here since it hurts the readibility.
+        Note1: Please DO NOT paste your lengthy log contents here since it hurts the readability.
         Note2: To enable logging, add `LOG=3` to to the make command if building with stock examples or set `CFG_TUSB_DEBUG=3` in your tusb_config.h. 
         More information can be found at [example's readme](https://github.com/hathach/tinyusb/blob/master/docs/getting_started.md)
     validations:
@@ -76,3 +76,11 @@ body:
       description: If applicable, add screenshots to help explain your problem.
     validations:
       required: false
+
+  - type: checkboxes
+    attributes:
+      label: I have checked existing issues, dicussion and documentation
+      description: You agree to check all the resources above before opening a new issue.
+      options:
+        - label: I confirm I have checked existing issues, dicussion and documentation.
+          required: true

+ 0 - 14
.github/ISSUE_TEMPLATE/feature_request.md

@@ -1,14 +0,0 @@
----
-name: Feature Request
-about: Suggest an idea for this project
-title: ''
-labels: Feature 💡
-assignees: ''
-
----
-
-**Is your feature request related to a problem? Please describe.**
-A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
-
-**Describe the solution you'd like**
-A clear and concise description of what you want to happen.

+ 49 - 0
.github/ISSUE_TEMPLATE/feature_request.yml

@@ -0,0 +1,49 @@
+name: Feature Request
+description: Suggest an idea for this project
+labels: 'Feature 💡'
+body:
+  - type: markdown
+    attributes:
+      value: |
+        Thanks for taking the time to fill out this request!
+        It's okay to leave some blank if it doesn't apply to your request.
+
+  - type: input
+    attributes:
+      label: Related area
+      description: Please briefly explain the area of your Feature Request.
+      placeholder: eg. new port support, device stack, class driver ...
+    validations:
+      required: true
+
+  - type: input
+    attributes:
+      label: Hardware specification
+      description: Please provide if your proposal depends on specific Hardware.
+      placeholder: eg. rp2040, samd51 ...
+    validations:
+      required: true
+
+  - type: textarea
+    attributes:
+      label: Is your feature request related to a problem?
+      description: Please provide a clear and concise description of what the problem is. Add relevant issue link.
+      placeholder: ex. I'm facing the issue/missing function...
+    validations:
+      required: true
+
+  - type: textarea
+    attributes:
+      label: Describe the solution you'd like
+      description: Please provide a clear and concise description of what you want to happen.
+      placeholder: ex. When using this function...
+    validations:
+      required: true
+
+  - type: checkboxes
+    attributes:
+      label: I have checked existing issues, dicussion and documentation
+      description: You agree to check all the resources above before opening a new issue.
+      options:
+        - label: I confirm I have checked existing issues, dicussion and documentation.
+          required: true

+ 20 - 6
.github/workflows/build_aarch64.yml

@@ -1,11 +1,23 @@
 name: Build AArch64
 
 on:
-  pull_request:
   push:
-  release:
-    types:
-      - created
+    paths:
+      - 'src/**'
+      - 'examples/**'
+      - 'lib/**'
+      - 'hw/**'
+  pull_request:
+    branches: [ master ]
+    paths:
+      - 'src/**'
+      - 'examples/**'
+      - 'lib/**'
+      - 'hw/**'
+
+concurrency:
+  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
+  cancel-in-progress: true
 
 jobs:
   # ---------------------------------------
@@ -21,7 +33,9 @@ jobs:
         - 'broadcom_64bit'
     steps:
     - name: Setup Python
-      uses: actions/setup-python@v2
+      uses: actions/setup-python@v4
+      with:
+        python-version: '3.x'
 
     - name: Checkout TinyUSB
       uses: actions/checkout@v3
@@ -39,7 +53,7 @@ jobs:
       run: echo >> $GITHUB_ENV TOOLCHAIN_URL=https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz
 
     - name: Cache Toolchain
-      uses: actions/cache@v2
+      uses: actions/cache@v3
       id: cache-toolchain
       with:
         path: ~/cache/

+ 108 - 30
.github/workflows/build_arm.yml

@@ -1,34 +1,25 @@
 name: Build ARM
 
 on:
-  pull_request:
   push:
-  release:
-    types:
-      - created
-
-jobs:
-  # ---------------------------------------
-  # Unit testing with Ceedling
-  # ---------------------------------------
-  unit-test:
-    runs-on: ubuntu-latest
-    steps:
-    - name: Setup Ruby
-      uses: ruby/setup-ruby@v1
-      with:
-        ruby-version: '2.7'
-
-    - name: Checkout TinyUSB
-      uses: actions/checkout@v3
+    paths:
+      - 'src/**'
+      - 'examples/**'
+      - 'lib/**'
+      - 'hw/**'
+  pull_request:
+    branches: [ master ]
+    paths:
+      - 'src/**'
+      - 'examples/**'
+      - 'lib/**'
+      - 'hw/**'
 
-    - name: Unit Tests
-      run: |
-        # Install Ceedling
-        gem install ceedling
-        cd test
-        ceedling test:all
+concurrency:
+  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
+  cancel-in-progress: true
 
+jobs:
   # ---------------------------------------
   # Build ARM family
   # ---------------------------------------
@@ -65,7 +56,9 @@ jobs:
         - 'xmc4000'
     steps:
     - name: Setup Python
-      uses: actions/setup-python@v3
+      uses: actions/setup-python@v4
+      with:
+        python-version: '3.x'
 
     - name: Install ARM GCC
       uses: carlosperate/arm-none-eabi-gcc-action@v1
@@ -99,16 +92,33 @@ jobs:
     - name: Linker Map
       run: |
         pip install linkermap/
-        for ex in `ls -d examples/device/*/`; do \
-          find ${ex} -name *.map -print -quit | \
-          xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"'; \
+        # find -quit to only print linkermap of 1 board per example
+        for ex in `ls -d examples/*/*/`
+        do
+          find ${ex} -name *.map -print -quit | xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"'
         done
 
+    # Following steps are for Hardware Test with self-hosted
+
+    - name: Prepare Artifacts
+      if: matrix.family == 'rp2040' && github.repository_owner == 'hathach'
+      run: find examples/ -name "*.elf" -exec mv {} . \;
+
+    - name: Upload Artifacts for Hardware Test
+      if: matrix.family == 'rp2040' && github.repository_owner == 'hathach'
+      uses: actions/upload-artifact@v3
+      with:
+        name: ${{ matrix.family }}
+        path: |
+          *.elf
+
   # ---------------------------------------
   # Build all no-family (orphaned) boards
+  # disable this workflow since it is often failed randomly
   # ---------------------------------------
   build-board:
     runs-on: ubuntu-latest
+    if: false
     strategy:
       fail-fast: false
       matrix:
@@ -122,7 +132,9 @@ jobs:
 
     steps:
     - name: Setup Python
-      uses: actions/setup-python@v3
+      uses: actions/setup-python@v4
+      with:
+        python-version: '3.x'
 
     - name: Install ARM GCC
       uses: carlosperate/arm-none-eabi-gcc-action@v1
@@ -137,3 +149,69 @@ jobs:
 
     - name: Build
       run: python3 tools/build_board.py ${{ matrix.example }}
+
+  # ---------------------------------------
+  # Hardware in the loop (HIL)
+  # Current self-hosted instance is running on an RPI4 with
+  # - pico + pico-probe connected via USB
+  # - pico-probe is /dev/ttyACM0
+  # ---------------------------------------
+  hw-rp2040-test:
+    # Limit the run to only hathach due to limited resource on RPI4
+    if: github.repository_owner == 'hathach'
+    needs: build-arm
+    runs-on: [self-hosted, Linux, ARM64, rp2040]
+
+    steps:
+    - name: Clean workspace
+      run: |
+        echo "Cleaning up previous run"
+        rm -rf "${{ github.workspace }}"
+        mkdir -p "${{ github.workspace }}"
+
+    - name: Download rp2040 Artifacts
+      uses: actions/download-artifact@v3
+      with:
+        name: rp2040
+
+    - name: Create flash.sh
+      run: |
+        echo > flash.sh 'cmdout=$(openocd -f "interface/picoprobe.cfg" -f "target/rp2040.cfg" -c "program $1 reset exit")'
+        echo >> flash.sh 'if (( $? )) ; then echo $cmdout ; fi'
+        chmod +x flash.sh
+
+    - name: Test cdc_dual_ports
+      run: |
+        ./flash.sh cdc_dual_ports.elf
+        while (! ([ -e /dev/ttyACM1 ] && [ -e /dev/ttyACM2 ])) && [ $SECONDS -le 5 ]; do :; done
+        test -e /dev/ttyACM1 && echo "ttyACM1 exists"
+        test -e /dev/ttyACM2 && echo "ttyACM2 exists"
+
+    - name: Test cdc_msc
+      run: |
+        ./flash.sh cdc_msc.elf
+        readme='/media/pi/TinyUSB MSC/README.TXT'
+        while (! ([ -e /dev/ttyACM1 ] && [ -f "$readme" ])) && [ $SECONDS -le 5 ]; do :; done
+        test -e /dev/ttyACM1 && echo "ttyACM1 exists"
+        test -f "$readme" && echo "$readme exists"
+        cat "$readme"
+
+    - name: Test dfu
+      run: |
+        ./flash.sh dfu.elf
+        while (! (dfu-util -l | grep "Found DFU")) && [ $SECONDS -le 5 ]; do :; done
+        dfu-util -d cafe -a 0 -U dfu0
+        dfu-util -d cafe -a 1 -U dfu1
+        grep "TinyUSB DFU! - Partition 0" dfu0
+        grep "TinyUSB DFU! - Partition 1" dfu1
+
+    - name: Test dfu_runtime
+      run: |
+        ./flash.sh dfu_runtime.elf
+        while (! (dfu-util -l | grep "Found Runtime")) && [ $SECONDS -le 5 ]; do :; done
+
+#    - name: Test hid_boot_interface
+#      run: |
+#        ./flash.sh hid_boot_interface.elf
+#        while (! (dfu-util -l | grep "Found Runtime")) && [ $SECONDS -le 5 ]; do :; done
+

+ 23 - 8
.github/workflows/build_esp.yml

@@ -1,11 +1,23 @@
 name: Build ESP
 
 on:
-  pull_request:
   push:
-  release:
-    types:
-      - created
+    paths:
+      - 'src/**'
+      - 'examples/**'
+      - 'lib/**'
+      - 'hw/**'
+  pull_request:
+    branches: [ master ]
+    paths:
+      - 'src/**'
+      - 'examples/**'
+      - 'lib/**'
+      - 'hw/**'
+
+concurrency:
+  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
+  cancel-in-progress: true
 
 jobs:
   build-esp:
@@ -23,7 +35,9 @@ jobs:
 
     steps:
     - name: Setup Python
-      uses: actions/setup-python@v2
+      uses: actions/setup-python@v4
+      with:
+        python-version: '3.x'
 
     - name: Pull ESP-IDF docker
       run: docker pull espressif/idf:latest
@@ -43,7 +57,8 @@ jobs:
     - name: Linker Map
       run: |
         pip install linkermap/
-        for ex in `ls -d examples/device/*/`; do \
-          find ${ex} -maxdepth 3 -name *.map -print -quit | \
-          xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"'; \
+        # find -quit to only print linkermap of 1 board per example
+        for ex in `ls -d examples/device/*/`
+        do
+          find ${ex} -maxdepth 3 -name *.map -print -quit | xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"'
         done

+ 25 - 9
.github/workflows/build_msp430.yml

@@ -1,11 +1,23 @@
 name: Build MSP430
 
 on:
-  pull_request:
   push:
-  release:
-    types:
-      - created
+    paths:
+      - 'src/**'
+      - 'examples/**'
+      - 'lib/**'
+      - 'hw/**'
+  pull_request:
+    branches: [ master ]
+    paths:
+      - 'src/**'
+      - 'examples/**'
+      - 'lib/**'
+      - 'hw/**'
+
+concurrency:
+  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
+  cancel-in-progress: true
 
 jobs:  
   build-msp430:
@@ -16,9 +28,12 @@ jobs:
         family:
         # Alphabetical order
         - 'msp430'
+
     steps:
     - name: Setup Python
-      uses: actions/setup-python@v2
+      uses: actions/setup-python@v4
+      with:
+        python-version: '3.x'
 
     - name: Checkout TinyUSB
       uses: actions/checkout@v3
@@ -36,7 +51,7 @@ jobs:
       run: echo >> $GITHUB_ENV TOOLCHAIN_URL=http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSPGCC/9_2_0_0/export/msp430-gcc-9.2.0.50_linux64.tar.bz2
 
     - name: Cache Toolchain
-      uses: actions/cache@v2
+      uses: actions/cache@v3
       id: cache-toolchain
       with:
         path: ~/cache/
@@ -61,7 +76,8 @@ jobs:
     - name: Linker Map
       run: |
         pip install linkermap/
-        for ex in `ls -d examples/device/*/`; do \
-          find ${ex} -name *.map -print -quit | \
-          xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"'; \
+        # find -quit to only print linkermap of 1 board per example
+        for ex in `ls -d examples/device/*/`
+        do
+          find ${ex} -name *.map -print -quit | xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"'
         done

+ 24 - 9
.github/workflows/build_renesas.yml

@@ -1,11 +1,23 @@
 name: Build Renesas
 
 on:
-  pull_request:
   push:
-  release:
-    types:
-      - created
+    paths:
+      - 'src/**'
+      - 'examples/**'
+      - 'lib/**'
+      - 'hw/**'
+  pull_request:
+    branches: [ master ]
+    paths:
+      - 'src/**'
+      - 'examples/**'
+      - 'lib/**'
+      - 'hw/**'
+
+concurrency:
+  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
+  cancel-in-progress: true
 
 jobs:
   build-rx:
@@ -18,7 +30,9 @@ jobs:
         - 'rx'
     steps:
     - name: Setup Python
-      uses: actions/setup-python@v2
+      uses: actions/setup-python@v4
+      with:
+        python-version: '3.x'
 
     - name: Checkout TinyUSB
       uses: actions/checkout@v3
@@ -36,7 +50,7 @@ jobs:
       run: echo >> $GITHUB_ENV TOOLCHAIN_URL=http://gcc-renesas.com/downloads/get.php?f=rx/8.3.0.202004-gnurx/gcc-8.3.0.202004-GNURX-ELF.run
 
     - name: Cache Toolchain
-      uses: actions/cache@v2
+      uses: actions/cache@v3
       id: cache-toolchain
       with:
         path: ~/cache/
@@ -62,7 +76,8 @@ jobs:
     - name: Linker Map
       run: |
         pip install linkermap/
-        for ex in `ls -d examples/device/*/`; do \
-          find ${ex} -name *.map -print -quit | \
-          xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"'; \
+        # find -quit to only print linkermap of 1 board per example
+        for ex in `ls -d examples/device/*/`
+        do
+          find ${ex} -name *.map -print -quit | xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"'
         done

+ 24 - 9
.github/workflows/build_riscv.yml

@@ -1,11 +1,23 @@
 name: Build RISC-V
 
 on:
-  pull_request:
   push:
-  release:
-    types:
-      - created
+    paths:
+      - 'src/**'
+      - 'examples/**'
+      - 'lib/**'
+      - 'hw/**'
+  pull_request:
+    branches: [ master ]
+    paths:
+      - 'src/**'
+      - 'examples/**'
+      - 'lib/**'
+      - 'hw/**'
+
+concurrency:
+  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
+  cancel-in-progress: true
 
 jobs:
   build-riscv:
@@ -19,7 +31,9 @@ jobs:
         - 'gd32vf103'
     steps:
     - name: Setup Python
-      uses: actions/setup-python@v2
+      uses: actions/setup-python@v4
+      with:
+        python-version: '3.x'
 
     - name: Checkout TinyUSB
       uses: actions/checkout@v3
@@ -37,7 +51,7 @@ jobs:
       run: echo >> $GITHUB_ENV TOOLCHAIN_URL=https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack/releases/download/v10.1.0-1.1/xpack-riscv-none-embed-gcc-10.1.0-1.1-linux-x64.tar.gz
 
     - name: Cache Toolchain
-      uses: actions/cache@v2
+      uses: actions/cache@v3
       id: cache-toolchain
       with:
         path: ~/cache/
@@ -62,7 +76,8 @@ jobs:
     - name: Linker Map
       run: |
         pip install linkermap/
-        for ex in `ls -d examples/device/*/`; do \
-          find ${ex} -name *.map -print -quit | \
-          xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"'; \
+        # find -quit to only print linkermap of 1 board per example
+        for ex in `ls -d examples/device/*/`
+        do
+          find ${ex} -name *.map -print -quit | xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"'
         done

+ 48 - 0
.github/workflows/pre-commit.yml

@@ -0,0 +1,48 @@
+name: pre-commit
+
+on:
+  push:
+  pull_request:
+    branches: [ master ]
+
+concurrency:
+  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
+  cancel-in-progress: true
+
+jobs:
+  pre-commit:
+    runs-on: ubuntu-latest
+    steps:
+    - name: Setup Python
+      uses: actions/setup-python@v4
+      with:
+        python-version: '3.x'
+
+    - name: Setup Ruby
+      uses: ruby/setup-ruby@v1
+      with:
+        ruby-version: '3.0'
+
+    - name: Checkout TinyUSB
+      uses: actions/checkout@v3
+
+    - name: Run codespell
+      uses: codespell-project/actions-codespell@master
+
+    - name: Run Unit Tests
+      run: |
+        # Install Ceedling
+        gem install ceedling
+        cd test/unit-test
+        ceedling test:all
+
+    - name: Build Fuzzer
+      run: |
+        export CC=clang
+        export CXX=clang++
+        fuzz_harness=$(ls -d test/fuzz/device/*/)
+        for h in $fuzz_harness
+        do
+          make -C $h get-deps
+          make -C $h all
+        done

+ 94 - 0
.github/workflows/test_hardware.yml

@@ -0,0 +1,94 @@
+name: Hardware Test
+
+on:
+  push:
+    paths:
+      - 'src/**'
+      - 'examples/**'
+      - 'lib/**'
+      - 'hw/**'
+  pull_request:
+    branches: [ master ]
+    paths:
+      - 'src/**'
+      - 'examples/**'
+      - 'lib/**'
+      - 'hw/**'
+
+# Hardware in the loop (HIL)
+# Current self-hosted instance is running on an EPYC 7232 server hosted by HiFiPhile user
+# - STM32L412 Nucleo with on-board jlink as ttyACM0
+
+jobs:
+  stm32l412nucleo-test:
+    runs-on: [self-hosted, Linux, X64, hifiphile]
+
+    steps:
+    - name: Clean workspace
+      run: |
+        echo "Cleaning up previous run"
+        rm -rf "${{ github.workspace }}"
+        mkdir -p "${{ github.workspace }}"
+
+    - name: Checkout TinyUSB
+      uses: actions/checkout@v3
+
+    - name: Get Dependencies and Build
+      run: |
+        git submodule update --init lib/FreeRTOS-Kernel lib/lwip
+        python3 tools/get_dependencies.py stm32l4
+        python3 tools/build_family.py stm32l4
+
+    - name: Pick-up elf files
+      run: |
+        mkdir stm32l412nucleo/
+        find examples/ -path "*stm32l412nucleo/*.elf" -exec mv {} stm32l412nucleo/ \;
+
+    - name: Create flash.sh
+      run: |
+        echo > flash.sh 'echo halt > flash.jlink'
+        echo >> flash.sh 'echo r >> flash.jlink'
+        echo >> flash.sh 'echo loadfile stm32l412nucleo/$1 >> flash.jlink'
+        echo >> flash.sh 'echo r >> flash.jlink'
+        echo >> flash.sh 'echo go >> flash.jlink'
+        echo >> flash.sh 'echo exit >> flash.jlink'
+        echo >> flash.sh 'cmdout=$(JLinkExe -device stm32l412kb -if swd -JTAGConf -1,-1 -speed auto -NoGui 1 -ExitOnError 1 -CommandFile flash.jlink)'
+        echo >> flash.sh 'if (( $? )) ; then echo $cmdout ; fi'
+        chmod +x flash.sh
+
+    - name: Test cdc_dual_ports
+      run: |
+        ./flash.sh cdc_dual_ports.elf
+        while (! ([ -e /dev/ttyACM1 ] && [ -e /dev/ttyACM2 ])) && [ $SECONDS -le 5 ]; do :; done
+        test -e /dev/ttyACM1 && echo "ttyACM1 exists"
+        test -e /dev/ttyACM2 && echo "ttyACM2 exists"
+
+      # Debian does not auto mount usb drive. skip this test for now
+    - name: Test cdc_msc
+      if: false
+      run: |
+        ./flash.sh cdc_msc.elf
+        readme='/media/pi/TinyUSB MSC/README.TXT'
+        while (! ([ -e /dev/ttyACM1 ] && [ -f "$readme" ])) && [ $SECONDS -le 5 ]; do :; done
+        test -e /dev/ttyACM1 && echo "ttyACM1 exists"
+        test -f "$readme" && echo "$readme exists"
+        cat "$readme"
+
+    - name: Test dfu
+      run: |
+        ./flash.sh dfu.elf
+        while (! (dfu-util -l | grep "Found DFU")) && [ $SECONDS -le 5 ]; do :; done
+        dfu-util -d cafe -a 0 -U dfu0
+        dfu-util -d cafe -a 1 -U dfu1
+        grep "TinyUSB DFU! - Partition 0" dfu0
+        grep "TinyUSB DFU! - Partition 1" dfu1
+
+    - name: Test dfu_runtime
+      run: |
+        ./flash.sh dfu_runtime.elf
+        while (! (dfu-util -l | grep "Found Runtime")) && [ $SECONDS -le 5 ]; do :; done
+
+#    - name: Test hid_boot_interface
+#      run: |
+#        ./flash.sh hid_boot_interface.elf
+#        while (! (dfu-util -l | grep "Found Runtime")) && [ $SECONDS -le 5 ]; do :; done

+ 3 - 1
.github/workflows/trigger.yml

@@ -55,4 +55,6 @@ jobs:
         git push origin ${{ github.event.release.tag_name }}
         
         # Send POST reqwuest to release https://docs.github.com/en/rest/reference/repos#create-a-release
-        curl -X POST -H "Authorization: token ${{ secrets.API_TOKEN_GITHUB }}" -H "Accept: application/vnd.github.v3+json" --data '{"tag_name": "${{ github.event.release.tag_name }}", "name": "${{ github.event.release.name }}", "body": "${{ github.event.release.body }}", "draft": ${{ github.event.release.draft }}, "prerelease": ${{ github.event.release.prerelease }}}' https://api.github.com/repos/hathach/tinyusb_src/releases
+        bb={{ github.event.release.body }}
+        bb=${bb//\n/\\\n}
+        curl -X POST -H "Authorization: token ${{ secrets.API_TOKEN_GITHUB }}" -H "Accept: application/vnd.github.v3+json" --data '{"tag_name": "${{ github.event.release.tag_name }}", "name": "${{ github.event.release.name }}", "body": "$bb", "draft": ${{ github.event.release.draft }}, "prerelease": ${{ github.event.release.prerelease }}}' https://api.github.com/repos/hathach/tinyusb_src/releases

+ 4 - 4
README.rst

@@ -43,7 +43,7 @@ The stack supports the following MCUs:
 - **Nuvoton:** NUC120, NUC121/NUC125, NUC126, NUC505
 - **NXP:**
 
-  - iMX RT Series: RT1011, RT1015, RT1021, RT1052, RT1062, RT1064
+  - iMX RT Series: RT10xx, RT11xx
   - Kinetis: KL25, K32L2
   - LPC Series: 11u, 13, 15, 17, 18, 40, 43, 51u, 54, 55
 
@@ -51,7 +51,7 @@ The stack supports the following MCUs:
 - **Renesas:** RX63N, RX65N, RX72N
 - **Silabs:** EFM32GG
 - **Sony:** CXD56
-- **ST:** STM32 series: F0, F1, F2, F3, F4, F7, H7, G4, L0, L1, L4, L4+
+- **ST:** STM32 series: F0, F1, F2, F3, F4, F7, H7, G4, L0, L1, L4, L4+, WB
 - **TI:** MSP430, MSP432E4, TM4C123
 - **ValentyUSB:** eptri
 
@@ -94,8 +94,8 @@ TinyUSB is completely thread-safe by pushing all Interrupt Service Request (ISR)
 - `RT-Thread <https://github.com/RT-Thread/rt-thread>`_: `repo <https://github.com/RT-Thread-packages/tinyusb>`_
 - **Mynewt** Due to the newt package build system, Mynewt examples are better to be on its `own repo <https://github.com/hathach/mynewt-tinyusb-example>`_
 
-Local Docs
-==========
+Docs
+====
 
 - Info
 

+ 1 - 1
docs/contributing/index.rst

@@ -6,7 +6,7 @@ Contributing can be highly rewarding, but it can also be frustrating at times.
 It takes time to review patches, and as this is an open source project, that
 sometimes can take a while. The reviewing process depends on the availability
 of the maintainers, who may not be always available. Please try to be
-understanding throught the process.
+understanding through the process.
 
 There a few guidelines you need to keep in mind when contributing. Please have
 a look at them as that will make the contribution process easier for all

+ 2 - 2
docs/contributing/porting.rst

@@ -195,7 +195,7 @@ Others (like the nRF52) may need each USB packet queued individually. To make th
 some state for yourself and queue up an intermediate USB packet from the interrupt handler.
 
 Once the transaction is going, the interrupt handler will notify TinyUSB of transfer completion.
-During transmission, the IN data buffer is guarenteed to remain unchanged in memory until the ``dcd_xfer_complete`` function is called.
+During transmission, the IN data buffer is guaranteed to remain unchanged in memory until the ``dcd_xfer_complete`` function is called.
 
 The dcd_edpt_xfer function must never add zero-length-packets (ZLP) on its own to a transfer. If a ZLP is required,
 then it must be explicitly sent by the stack calling dcd_edpt_xfer(), by calling dcd_edpt_xfer() a second time with len=0.
@@ -238,4 +238,4 @@ Use `WireShark <https://www.wireshark.org/>`_ or `a Beagle <https://www.totalpha
 
 * If the host sends a SETUP packet and its not ACKed then your USB peripheral probably isn't started correctly.
 * If the peripheral is started correctly but it still didn't work, then verify your usb clock is correct. (You did output a PWM based on it right? ;-) )
-* If the SETUP packet is ACKed but nothing is sent back then you interrupt handler isn't queueing the setup packet correctly. (Also, if you are using your own code instead of an example ``tud_task`` may not be called.) If thats OK, the ``dcd_xfer_complete`` may not be setting up the next transaction correctly.
+* If the SETUP packet is ACKed but nothing is sent back then you interrupt handler isn't queueing the setup packet correctly. (Also, if you are using your own code instead of an example ``tud_task`` may not be called.) If that's OK, the ``dcd_xfer_complete`` may not be setting up the next transaction correctly.

+ 68 - 11
docs/info/changelog.rst

@@ -2,6 +2,63 @@
 Changelog
 *********
 
+0.14.0
+======
+
+- Improve compiler support for CCRX and IAR
+- Add timeout to osal_queue_receive()
+- Add tud_task_ext(timeout, in_isr) as generic version of tud_task(). Same as tuh_task_ext(), tuh_task()
+- Enable more warnings -Wnull-dereference -Wuninitialized -Wunused -Wredundant-decls -Wconversion
+- Add new examples 
+  - host/bare_api to demonstrate generic (app-level) enumeration and endpoint transfer
+  - dual/host_hid_to_device_cdc to run both device and host stack concurrently, get HID report from host and print out to device CDC. This example only work with multiple-controller MCUs and rp2040 with the help of pio-usb as added controller.
+
+Controller Driver (DCD & HCD)
+-----------------------------
+
+- Enhance rhports management to better support dual roles
+  - CFG_TUD_ENABLED/CFG_TUH_ENABLED, CFG_TUD_MAX_SPEED/CFG_TUH_MAX_SPEED can be used to replace CFG_TUSB_RHPORT0_MODE/CFG_TUSB_RHPORT1_MODE
+  - tud_init(rphort), tuh_init(rhport) can be used to init stack on specified roothub port (controller) instead of tusb_init(void)
+- Add dcd/hcd port specific defines TUP_ (stand for tinyusb port-specific)
+- [dwc2]
+  - Update to support stm32 h72x, h73x with only 1 otg controller
+  - Fix overwrite with grstctl when disable endpoint
+- [EHCI] Fix an issue with EHCI driver
+- [msp430] Fix for possible bug in msp430-elf-gcc 9.3.0
+- [nrf5x] Fix DMA access race condition using atomic function 
+- [pic32] Fix PIC32 santiy
+- [rp2040]
+  - Add PICO-PIO-USB as controller (device/host) support for rp2040
+  - Use shared IRQ handlers, so user can also hook the USB IRQ
+  - Fix resumed signal not reported to device stack
+- [stm32fsdev] Add support for stm32wb55 
+
+Device Stack
+------------
+
+- [Audio] Add support for feedback endpoint computation
+  - New API tud_audio_feedback_params_cb(), tud_audio_feedback_interval_isr().
+  - Supported computation method are: frequency with fixed/float or power of 2. Feedback with fifo count is not yet supported.
+  - Fix nitfs (should be 3) in TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR
+  - Fix typo in audiod_rx_done_cb()
+- [DFU] Fix coexistence with other interfaces BTH, RNDIS
+- [MSC] Fix inquiry response additional length field
+- [Venndor] Improve write performance
+
+Host Stack
+----------
+
+- Add new API tuh_configure(rhport, cfg_id, cfg_param) for dynamnic port specific behavior configuration
+- [HID] Open OUT endpoint if available
+- [Hub] hub clear port and device interrupts
+- [USBH] Major improvement
+  - Rework usbh control transfer with complete callback. New API tuh_control_xfer() though still only carry 1 usbh (no queueing) at a time.
+  - Add generic endpoint transfer with tuh_edpt_open(), tuh_edpt_xfer(). Require `CFG_TUH_API_EDPT_XFER=1`
+  - Support app-level enumeration with new APIs
+    - tuh_descriptor_get(), tuh_descriptor_get_device(), tuh_descriptor_get_configuration(), tuh_descriptor_get_hid_report()
+    - tuh_descriptor_get_string(), tuh_descriptor_get_manufacturer_string(), tuh_descriptor_get_product_string(), tuh_descriptor_get_serial_string()
+    - Also add _sync() as sync/blocking version for above APIs
+
 0.13.0
 ======
 
@@ -21,14 +78,14 @@ Controller Driver (DCD & HCD)
 - [MUSB] Add new DCD and HCD for Mentor musb with TI MSP432E4
 - [F1C100s] Add new DCD for Allwinner F1C100s family
 - [PIC32MZ] Add new DCD for PIC32MZ
-- [nRF] Fix/Enhance varous race condtion with: EASY DMA, request HFXO, EPOUT
+- [nRF] Fix/Enhance various race condition with: EASY DMA, request HFXO, EPOUT
 - [ChipIdea] rename Transdimension to more popular ChipIdea Highspeed, 
 - [RP2040] various update/fix for hcd/dcd
 - [FT9XX] new DCD port for Bridgetek FT90x and FT93x devices
 - [DA1469X] Fix resume
 - [OHCI] Fix device array out of bound
 
-Note: legacy drivers such as st/synopsys, nxp/transdimension are still present in this release but won't recieve more update and could be removed in the future.
+Note: legacy drivers such as st/synopsys, nxp/transdimension are still present in this release but won't receive more update and could be removed in the future.
 
 Device Stack
 ------------
@@ -109,7 +166,7 @@ RP2040
 ^^^^^^
 
 - Add RP2040 suspend & resume support
-- Implement double buffer for both host and device (#891). Howver device EPOUT is still single bufferred due to techinical issue with short packet 
+- Implement double buffer for both host and device (#891). However device EPOUT is still single buffered due to techinical issue with short packet 
 
 Device Stack
 ------------
@@ -118,7 +175,7 @@ USBD
 ^^^^
 
 - Better support big endian mcu
-- Add tuh_inited() and tud_inited(), will separte tusb_init/inited() to tud/tuh init/inited
+- Add tuh_inited() and tud_inited(), will separate tusb_init/inited() to tud/tuh init/inited
 - Add dcd_attr.h for defining common controller attribute such as max endpoints
 
 Bluetooth
@@ -163,8 +220,8 @@ Host Controller Driver (HCD)
 RP2040
 ^^^^^^
 
-- Implement double bufferred to fix E4 errata and boost performance
-- Lots of rp2040 update and enhancment
+- Implement double buffered to fix E4 errata and boost performance
+- Lots of rp2040 update and enhancement
 
 Host Stack
 ----------
@@ -172,7 +229,7 @@ Host Stack
 - Major update and rework most of host stack, still needs more improvement
 - Lots of improvement and update in parsing configuration and control
 - Rework and major update to HID driver. Will default to enable boot interface if available
-- Sepearate CFG_TUH_DEVICE_MAX and CFG_TUH_HUB for better management and reduce SRAM usage
+- Separate CFG_TUH_DEVICE_MAX and CFG_TUH_HUB for better management and reduce SRAM usage
 
 0.10.1 (2021-06-03)
 ===================
@@ -249,12 +306,12 @@ MIDI
 Host Controller Driver (HCD)
 ----------------------------
 
-- No noticable changes
+- No noticeable changes
 
 USB Host Driver (USBH)
 ----------------------
 
-- No noticable changes
+- No noticeable changes
 
 Host Class Driver
 -----------------
@@ -327,7 +384,7 @@ HID
 MIDI
 
 - Fix dropping MIDI sysex message when fifo is full
-- Fix typo in tud_midi_write24(), make example less ambigous for cable and channel
+- Fix typo in tud_midi_write24(), make example less ambiguous for cable and channel
 - Fix incorrect endpoint descriptor length, MIDI v1 use Audio v1 which has 9-byte endpoint descriptor (instead of 7)
 
 Host Stack
@@ -642,7 +699,7 @@ Changed
 - Generalized dcd_stm32f4.c to dcd_synopsys.c
 - Changed cdc_msc_hid to cdc_msc (drop hid) due to limited endpoints number of some MCUs
 - Improved DCD SAMD stability, fix missing setup packet occasionally
-- Improved usbd/usbd_control with proper hanlding of zero-length packet (ZLP)
+- Improved usbd/usbd_control with proper handling of zero-length packet (ZLP)
 - Improved STM32 DCD FSDev
 - Improved STM32 DCD Synopsys
 - Migrated CI from Travis to Github Action

+ 9 - 10
docs/reference/getting_started.rst

@@ -50,16 +50,7 @@ Some TinyUSB examples also requires external submodule libraries in ``/lib`` suc
 
    $ git submodule update --init lib
 
-In addition, MCU driver submodule is also needed to provide low-level MCU peripheral's driver. To download these depencies for your board, run the ``get-dpes`` as follow.
-
-.. code-block::
-
-   $ make BOARD=feather_nrf52840_express get-deps
-
-
-Some modules will also require a module-specific SDK (e.g. RP2040) or binary (e.g. Sony Spresense) to build examples.
-
-Note: some examples especially those that uses Vendor class (e.g webUSB) may requires udev permission on Linux (and/or macOS) to access usb device. It depends on your OS distro, typically copy ``/examples/device/99-tinyusb.rules`` file to /etc/udev/rules.d/ then run ``sudo udevadm control --reload-rules && sudo udevadm trigger`` is good enough.
+Some ports will also require a port-specific SDK (e.g. RP2040) or binary (e.g. Sony Spresense) to build examples. They are out of scope for tinyusb, you should download/install it first according to its manufacturer guide. 
 
 Build
 ^^^^^
@@ -70,6 +61,13 @@ To build example, first change directory to an example folder.
 
    $ cd examples/device/cdc_msc
 
+Before building, we need to download MCU driver submodule to provide low-level MCU peripheral's driver first. Run the ``get-deps`` target in one of the example folder as follow. You only need to do this once per mcu
+
+.. code-block::
+
+   $ make BOARD=feather_nrf52840_express get-deps
+
+
 Some modules (e.g. RP2040 and ESP32s2) require the project makefiles to be customized using CMake. If necessary apply any setup steps for the platform's SDK.
 
 Then compile with ``make BOARD=[board_name] all``\ , for example
@@ -79,6 +77,7 @@ Then compile with ``make BOARD=[board_name] all``\ , for example
    $ make BOARD=feather_nrf52840_express all
 
 Note: ``BOARD`` can be found as directory name in ``hw/bsp``\ , either in its family/boards or directly under bsp (no family).
+Note: some examples especially those that uses Vendor class (e.g webUSB) may requires udev permission on Linux (and/or macOS) to access usb device. It depends on your OS distro, typically copy ``/examples/device/99-tinyusb.rules`` file to /etc/udev/rules.d/ then run ``sudo udevadm control --reload-rules && sudo udevadm trigger`` is good enough.
 
 Port Selection
 ~~~~~~~~~~~~~~

+ 10 - 1
docs/reference/supported.rst

@@ -41,6 +41,8 @@ Supported MCUs
 |              | NUC505                | ✔      |      | ✔         |                   |              |
 +--------------+---------+-------------+--------+------+-----------+-------------------+--------------+
 | NXP          | iMXRT   | RT10xx      | ✔      | ✔    | ✔         | ci_hs             |              |
+|              |         +-------------+--------+------+-----------+-------------------+--------------+
+|              |         | RT11xx      | ✔      | ✔    | ✔         | ci_hs             |              |
 |              +---------+-------------+--------+------+-----------+-------------------+--------------+
 |              | Kinetis | KL25        | ✔      | ⚠    | ✖         |                   |              |
 |              |         +-------------+--------+------+-----------+-------------------+--------------+
@@ -58,7 +60,7 @@ Supported MCUs
 |              |         +-------------+--------+------+-----------+-------------------+--------------+
 |              |         | 55          | ✔      |      | ✔         | lpc_ip3511        |              |
 +--------------+---------+-------------+--------+------+-----------+-------------------+--------------+
-| Raspberry Pi | RP2040                | ✔      | ✔    | ✖         | rp2040            |              |
+| Raspberry Pi | RP2040                | ✔      | ✔    | ✖         | rp2040, pio_usb   |              |
 +--------------+-----------------------+--------+------+-----------+-------------------+--------------+
 | Renesas      | RX 63N, 65N, 72N      | ✔      | ✔    | ✖         | usba              |              |
 +--------------+-----------------------+--------+------+-----------+-------------------+--------------+
@@ -93,6 +95,8 @@ Supported MCUs
 |              | L4+                   | ✔      |      |           | dwc2              |              |
 |              +-----------------------+--------+------+-----------+-------------------+--------------+
 |              | U5                    | ⚠      |      |           | dwc2              |              |
+|              +-----------------------+--------+------+-----------+-------------------+--------------+
+|              | WBx5                  | ✔      |      |           | stm32_fsdev       |              |
 +--------------+-----------------------+--------+------+-----------+-------------------+--------------+
 | TI           | MSP430                | ✔      | ✖    | ✖         | msp430x5xx        |              |
 |              +-----------------------+--------+------+-----------+-------------------+--------------+
@@ -239,6 +243,7 @@ iMX RT
 -  `MIMX RT1060 Evaluation Kit <https://www.nxp.com/design/development-boards/i.mx-evaluation-and-development-boards/mimxrt1060-evk-i.mx-rt1060-evaluation-kit:MIMXRT1060-EVK>`__
 -  `MIMX RT1064 Evaluation Kit <https://www.nxp.com/design/development-boards/i.mx-evaluation-and-development-boards/mimxrt1064-evk-i.mx-rt1064-evaluation-kit:MIMXRT1064-EVK>`__
 -  `Teensy 4.0 Development Board <https://www.pjrc.com/store/teensy40.html>`__
+-  `Teensy 4.1 Development Board <https://www.pjrc.com/store/teensy41.html>`__
 
 Kinetis
 ^^^^^^^
@@ -377,6 +382,10 @@ L4
 -  `STM32 L4P5zg Nucleo <https://www.st.com/en/evaluation-tools/nucleo-l4p5zg.html>`__
 -  `STM32 L4R5zi Nucleo <https://www.st.com/en/evaluation-tools/nucleo-l4r5zi.html>`__
 
+WB
+^^
+-  `STM32 WB55 Nucleo <https://www.st.com/en/evaluation-tools/p-nucleo-wb55.html>`__
+
 TI
 --
 

+ 0 - 3
examples/device/audio_4_channel_mic/CMakeLists.txt

@@ -23,9 +23,6 @@ target_include_directories(${PROJECT} PUBLIC
   ${CMAKE_CURRENT_SOURCE_DIR}/src
 )
 
-# Example common such as compiler warnings
-include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake)
-
 # Configure compilation flags and libraries for the example... see the corresponding function
 # in hw/bsp/FAMILY/family.cmake for details.
 family_configure_device_example(${PROJECT})

+ 0 - 3
examples/device/audio_test/CMakeLists.txt

@@ -23,9 +23,6 @@ target_include_directories(${PROJECT} PUBLIC
   ${CMAKE_CURRENT_SOURCE_DIR}/src
 )
 
-# Example common such as compiler warnings
-include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake)
-
 # Configure compilation flags and libraries for the example... see the corresponding function
 # in hw/bsp/FAMILY/family.cmake for details.
 family_configure_device_example(${PROJECT})

+ 0 - 3
examples/device/board_test/CMakeLists.txt

@@ -36,9 +36,6 @@ else()
           ${CMAKE_CURRENT_SOURCE_DIR}/src
           )
 
-  # Example common such as compiler warnings
-  include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake)
-
   # Configure compilation flags and libraries for the example... see the corresponding function
   # in hw/bsp/FAMILY/family.cmake for details.
   family_configure_device_example(${PROJECT})

+ 8 - 1
examples/device/board_test/src/main.c

@@ -56,7 +56,7 @@ int main(void)
   {
     uint32_t interval_ms = board_button_read() ? BLINK_PRESSED : BLINK_UNPRESSED;
 
-    // Blink every interval ms
+    // Blink and print every interval ms
     if ( !(board_millis() - start_ms < interval_ms) )
     {
       board_uart_write(HELLO_STR, strlen(HELLO_STR));
@@ -66,6 +66,13 @@ int main(void)
       board_led_write(led_state);
       led_state = 1 - led_state; // toggle
     }
+
+    // echo
+    uint8_t ch;
+    if ( board_uart_read(&ch, 1) > 0 )
+    {
+      board_uart_write(&ch, 1);
+    }
   }
 
   return 0;

+ 0 - 3
examples/device/cdc_dual_ports/CMakeLists.txt

@@ -23,9 +23,6 @@ target_include_directories(${PROJECT} PUBLIC
         ${CMAKE_CURRENT_SOURCE_DIR}/src
         )
 
-# Example common such as compiler warnings
-include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake)
-
 # Configure compilation flags and libraries for the example... see the corresponding function
 # in hw/bsp/FAMILY/family.cmake for details.
 family_configure_device_example(${PROJECT})

+ 0 - 3
examples/device/cdc_msc/CMakeLists.txt

@@ -24,9 +24,6 @@ target_include_directories(${PROJECT} PUBLIC
         ${CMAKE_CURRENT_SOURCE_DIR}/src
         )
 
-# Example common such as compiler warnings
-include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake)
-
 # Configure compilation flags and libraries for the example... see the corresponding function
 # in hw/bsp/FAMILY/family.cmake for details.
 family_configure_device_example(${PROJECT})

+ 1 - 1
examples/device/cdc_msc/src/main.c

@@ -113,7 +113,7 @@ void cdc_task(void)
     // connected and there are data available
     if ( tud_cdc_available() )
     {
-      // read datas
+      // read data
       char buf[64];
       uint32_t count = tud_cdc_read(buf, sizeof(buf));
       (void) count;

+ 1 - 1
examples/device/cdc_msc_freertos/CMakeLists.txt

@@ -1,7 +1,7 @@
 cmake_minimum_required(VERSION 3.5)
 
 # TOP is absolute path to root directory of TinyUSB git repo
-# needed for esp32sx build. TOOD could be removed later on
+# needed for esp32sx build. TODO could be removed later on
 set(TOP "../../..")
 get_filename_component(TOP "${TOP}" REALPATH)
 

+ 9 - 2
examples/device/cdc_msc_freertos/Makefile

@@ -29,8 +29,15 @@ SRC_C += \
 	$(FREERTOS_SRC)/timers.c \
 	$(subst ../../../,,$(wildcard ../../../$(FREERTOS_SRC)/portable/GCC/$(FREERTOS_PORT)/*.c))
 
-# Suppress FreeRTOS warnings
-CFLAGS += -Wno-error=cast-qual -Wno-error=redundant-decls
+# include heap manage if configSUPPORT_DYNAMIC_ALLOCATION = 1
+# SRC_C += $(FREERTOS_SRC)/portable/MemMang/heap_1.c
+# CFLAGS += -Wno-error=sign-compare
+
+# Suppress FreeRTOSConfig.h warnings
+CFLAGS += -Wno-error=redundant-decls
+
+# Suppress FreeRTOS source warnings
+CFLAGS += -Wno-error=cast-qual
 
 # FreeRTOS (lto + Os) linker issue
 LDFLAGS += -Wl,--undefined=vTaskSwitchContext

+ 1 - 1
examples/device/cdc_msc_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h

@@ -69,7 +69,7 @@
 #define configTICK_RATE_HZ                      ( 1000 )
 #define configMAX_PRIORITIES                    ( 5 )
 #define configMINIMAL_STACK_SIZE                ( 128 )
-#define configTOTAL_HEAP_SIZE                   ( 0*1024 ) // dynamic is not used
+#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

+ 16 - 8
examples/device/cdc_msc_freertos/src/main.c

@@ -51,6 +51,8 @@
   #define USBD_STACK_SIZE    (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1)
 #endif
 
+#define CDC_STACK_SZIE      configMINIMAL_STACK_SIZE
+
 //--------------------------------------------------------------------+
 // MACRO CONSTANT TYPEDEF PROTYPES
 //--------------------------------------------------------------------+
@@ -66,19 +68,18 @@ enum  {
   BLINK_SUSPENDED = 2500,
 };
 
-// static timer
+// static timer & task
+#if configSUPPORT_STATIC_ALLOCATION
 StaticTimer_t blinky_tmdef;
-TimerHandle_t blinky_tm;
 
-// static task
 StackType_t  usb_device_stack[USBD_STACK_SIZE];
 StaticTask_t usb_device_taskdef;
 
-// static task for cdc
-#define CDC_STACK_SZIE      configMINIMAL_STACK_SIZE
 StackType_t  cdc_stack[CDC_STACK_SZIE];
 StaticTask_t cdc_taskdef;
+#endif
 
+TimerHandle_t blinky_tm;
 
 void led_blinky_cb(TimerHandle_t xTimer);
 void usb_device_task(void* param);
@@ -92,15 +93,22 @@ int main(void)
 {
   board_init();
 
+#if configSUPPORT_STATIC_ALLOCATION
   // soft timer for blinky
   blinky_tm = xTimerCreateStatic(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb, &blinky_tmdef);
-  xTimerStart(blinky_tm, 0);
 
   // Create a task for tinyusb device stack
-  (void) xTaskCreateStatic( usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef);
+  xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef);
 
   // Create CDC task
-  (void) xTaskCreateStatic( cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, cdc_stack, &cdc_taskdef);
+  xTaskCreateStatic(cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, cdc_stack, &cdc_taskdef);
+#else
+  blinky_tm = xTimerCreate(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb);
+  xTaskCreate( usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, NULL);
+  xTaskCreate( cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, NULL);
+#endif
+
+  xTimerStart(blinky_tm, 0);
 
   // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3
 #if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)

+ 0 - 3
examples/device/dfu/CMakeLists.txt

@@ -23,9 +23,6 @@ target_include_directories(${PROJECT} PUBLIC
         ${CMAKE_CURRENT_SOURCE_DIR}/src
         )
 
-# Example common such as compiler warnings
-include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake)
-
 # Configure compilation flags and libraries for the example... see the corresponding function
 # in hw/bsp/FAMILY/family.cmake for details.
 family_configure_device_example(${PROJECT})

+ 0 - 3
examples/device/dfu_runtime/CMakeLists.txt

@@ -23,9 +23,6 @@ target_include_directories(${PROJECT} PUBLIC
         ${CMAKE_CURRENT_SOURCE_DIR}/src
         )
 
-# Example common such as compiler warnings
-include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake)
-
 # Configure compilation flags and libraries for the example... see the corresponding function
 # in hw/bsp/FAMILY/family.cmake for details.
 family_configure_device_example(${PROJECT})

+ 1 - 1
examples/device/dfu_runtime/src/main.c

@@ -31,7 +31,7 @@
  *
  * $ dfu-util -e
  *
- * This will send DETTACH command to put device into bootloader. Since this example
+ * This will send DETACH command to put device into bootloader. Since this example
  * is minimal, it doesn't actually go into DFU mode but rather change the LED blinking
  * pattern to fast rate as indicator.
  */

+ 0 - 3
examples/device/dynamic_configuration/CMakeLists.txt

@@ -24,9 +24,6 @@ target_include_directories(${PROJECT} PUBLIC
         ${CMAKE_CURRENT_SOURCE_DIR}/src
         )
 
-# Example common such as compiler warnings
-include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake)
-
 # Configure compilation flags and libraries for the example... see the corresponding function
 # in hw/bsp/FAMILY/family.cmake for details.
 family_configure_device_example(${PROJECT})

+ 0 - 3
examples/device/hid_boot_interface/CMakeLists.txt

@@ -23,9 +23,6 @@ target_include_directories(${PROJECT} PUBLIC
         ${CMAKE_CURRENT_SOURCE_DIR}/src
         )
 
-# Example common such as compiler warnings
-include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake)
-
 # Configure compilation flags and libraries for the example... see the corresponding function
 # in hw/bsp/FAMILY/family.cmake for details.
 family_configure_device_example(${PROJECT})

+ 4 - 4
examples/device/hid_boot_interface/src/main.c

@@ -157,11 +157,11 @@ void hid_task(void)
       {
         uint8_t const report_id   = 0;
         uint8_t const button_mask = 0;
-        uint8_t const veritical   = 0;
+        uint8_t const vertical    = 0;
         uint8_t const horizontal  = 0;
         int8_t  const delta       = 5;
 
-        tud_hid_n_mouse_report(ITF_NUM_MOUSE, report_id, button_mask, delta, delta, veritical, horizontal);
+        tud_hid_n_mouse_report(ITF_NUM_MOUSE, report_id, button_mask, delta, delta, vertical, horizontal);
       }
     }
   }
@@ -175,13 +175,13 @@ void tud_hid_set_protocol_cb(uint8_t instance, uint8_t protocol)
   (void) protocol;
 
   // nothing to do since we use the same compatible boot report for both Boot and Report mode.
-  // TOOD set a indicator for user
+  // TODO set a indicator for user
 }
 
 // Invoked when sent REPORT successfully to host
 // Application can use this to send the next report
 // Note: For composite reports, report[0] is report ID
-void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len)
+void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, /*uint16_t*/ uint8_t len)
 {
   (void) instance;
   (void) report;

+ 0 - 3
examples/device/hid_composite/CMakeLists.txt

@@ -23,9 +23,6 @@ target_include_directories(${PROJECT} PUBLIC
         ${CMAKE_CURRENT_SOURCE_DIR}/src
         )
 
-# Example common such as compiler warnings
-include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake)
-
 # Configure compilation flags and libraries for the example... see the corresponding function
 # in hw/bsp/FAMILY/family.cmake for details.
 family_configure_device_example(${PROJECT})

+ 1 - 1
examples/device/hid_composite/src/main.c

@@ -225,7 +225,7 @@ void hid_task(void)
 // Invoked when sent REPORT successfully to host
 // Application can use this to send the next report
 // Note: For composite reports, report[0] is report ID
-void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len)
+void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, /*uint16_t*/ uint8_t len)
 {
   (void) instance;
   (void) len;

+ 9 - 2
examples/device/hid_composite_freertos/Makefile

@@ -28,8 +28,15 @@ SRC_C += \
 	$(FREERTOS_SRC)/timers.c \
 	$(subst ../../../,,$(wildcard ../../../$(FREERTOS_SRC)/portable/GCC/$(FREERTOS_PORT)/*.c))
 
-# Suppress FreeRTOS warnings
-CFLAGS += -Wno-error=cast-qual -Wno-error=redundant-decls
+# include heap manage if configSUPPORT_DYNAMIC_ALLOCATION = 1
+# SRC_C += $(FREERTOS_SRC)/portable/MemMang/heap_1.c
+# CFLAGS += -Wno-error=sign-compare
+
+# Suppress FreeRTOSConfig.h warnings
+CFLAGS += -Wno-error=redundant-decls
+
+# Suppress FreeRTOS source warnings
+CFLAGS += -Wno-error=cast-qual
 
 # FreeRTOS (lto + Os) linker issue
 LDFLAGS += -Wl,--undefined=vTaskSwitchContext

+ 4 - 3
examples/device/hid_composite_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h

@@ -46,13 +46,14 @@
 #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"
+  #error "ESP32-Sx should use IDF's FreeRTOSConfig.h"
 #endif
 
+// TODO fix later
 #if CFG_TUSB_MCU == OPT_MCU_MM32F327X
-  // TODO fix/remove later  
   extern u32 SystemCoreClock;
 #else
+  // FIXME cause redundant-decls warnings
   extern uint32_t SystemCoreClock;
 #endif
 
@@ -68,7 +69,7 @@
 #define configTICK_RATE_HZ                      ( 1000 )
 #define configMAX_PRIORITIES                    ( 5 )
 #define configMINIMAL_STACK_SIZE                ( 128 )
-#define configTOTAL_HEAP_SIZE                   ( 0*1024 ) // dynamic is not used
+#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

+ 17 - 9
examples/device/hid_composite_freertos/src/main.c

@@ -53,6 +53,8 @@
   #define USBD_STACK_SIZE    (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1)
 #endif
 
+#define HID_STACK_SZIE      configMINIMAL_STACK_SIZE
+
 //--------------------------------------------------------------------+
 // MACRO CONSTANT TYPEDEF PROTYPES
 //--------------------------------------------------------------------+
@@ -68,19 +70,18 @@ enum  {
   BLINK_SUSPENDED = 2500,
 };
 
-// static timer
+// static timer & task
+#if configSUPPORT_STATIC_ALLOCATION
 StaticTimer_t blinky_tmdef;
-TimerHandle_t blinky_tm;
 
-// static task
 StackType_t  usb_device_stack[USBD_STACK_SIZE];
 StaticTask_t usb_device_taskdef;
 
-// static task for hid
-#define HID_STACK_SZIE      configMINIMAL_STACK_SIZE
 StackType_t  hid_stack[HID_STACK_SZIE];
 StaticTask_t hid_taskdef;
+#endif
 
+TimerHandle_t blinky_tm;
 
 void led_blinky_cb(TimerHandle_t xTimer);
 void usb_device_task(void* param);
@@ -94,15 +95,22 @@ int main(void)
 {
   board_init();
 
+#if configSUPPORT_STATIC_ALLOCATION
   // soft timer for blinky
   blinky_tm = xTimerCreateStatic(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb, &blinky_tmdef);
-  xTimerStart(blinky_tm, 0);
 
   // Create a task for tinyusb device stack
-  (void) xTaskCreateStatic( usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef);
+  xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef);
 
   // Create HID task
-  (void) xTaskCreateStatic( hid_task, "hid", HID_STACK_SZIE, NULL, configMAX_PRIORITIES-2, hid_stack, &hid_taskdef);
+  xTaskCreateStatic(hid_task, "hid", HID_STACK_SZIE, NULL, configMAX_PRIORITIES-2, hid_stack, &hid_taskdef);
+#else
+  blinky_tm = xTimerCreate(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb);
+  xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, NULL);
+  xTaskCreate(hid_task, "hid", HID_STACK_SZIE, NULL, configMAX_PRIORITIES-2, NULL);
+#endif
+
+  xTimerStart(blinky_tm, 0);
 
   // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3
 #if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
@@ -294,7 +302,7 @@ void hid_task(void* param)
 // Invoked when sent REPORT successfully to host
 // Application can use this to send the next report
 // Note: For composite reports, report[0] is report ID
-void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len)
+void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, /*uint16_t*/ uint8_t len)
 {
   (void) instance;
   (void) len;

+ 0 - 3
examples/device/hid_generic_inout/CMakeLists.txt

@@ -23,9 +23,6 @@ target_include_directories(${PROJECT} PUBLIC
         ${CMAKE_CURRENT_SOURCE_DIR}/src
         )
 
-# Example common such as compiler warnings
-include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake)
-
 # Configure compilation flags and libraries for the example... see the corresponding function
 # in hw/bsp/FAMILY/family.cmake for details.
 family_configure_device_example(${PROJECT})

+ 2 - 2
examples/device/hid_generic_inout/hid_test.py

@@ -13,8 +13,8 @@ for vid in  USB_VID:
         if dev:
             while True:
                 # Get input from console and encode to UTF8 for array of chars.
-                # hid generic inout is single report therefore by HIDAPI requirement
-                # it must be preceeded with 0x00 as dummy reportID
+                # hid generic in/out is single report therefore by HIDAPI requirement
+                # it must be preceded, with 0x00 as dummy reportID
                 str_out = b'\x00'
                 str_out += input("Send text to HID Device : ").encode('utf-8')
                 dev.write(str_out)

+ 0 - 3
examples/device/hid_multiple_interface/CMakeLists.txt

@@ -23,9 +23,6 @@ target_include_directories(${PROJECT} PUBLIC
         ${CMAKE_CURRENT_SOURCE_DIR}/src
         )
 
-# Example common such as compiler warnings
-include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake)
-
 # Configure compilation flags and libraries for the example... see the corresponding function
 # in hw/bsp/FAMILY/family.cmake for details.
 family_configure_device_example(${PROJECT})

+ 0 - 3
examples/device/midi_test/CMakeLists.txt

@@ -23,9 +23,6 @@ target_include_directories(${PROJECT} PUBLIC
         ${CMAKE_CURRENT_SOURCE_DIR}/src
         )
 
-# Example common such as compiler warnings
-include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake)
-
 # Configure compilation flags and libraries for the example... see the corresponding function
 # in hw/bsp/FAMILY/family.cmake for details.
 family_configure_device_example(${PROJECT})

+ 0 - 3
examples/device/msc_dual_lun/CMakeLists.txt

@@ -24,9 +24,6 @@ target_include_directories(${PROJECT} PUBLIC
         ${CMAKE_CURRENT_SOURCE_DIR}/src
         )
 
-# Example common such as compiler warnings
-include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake)
-
 # Configure compilation flags and libraries for the example... see the corresponding function
 # in hw/bsp/FAMILY/family.cmake for details.
 family_configure_device_example(${PROJECT})

+ 0 - 3
examples/device/net_lwip_webserver/CMakeLists.txt

@@ -69,9 +69,6 @@ if (EXISTS ${TOP}/lib/lwip/src)
             ${TOP}/lib/networking/rndis_reports.c
             )
 
-    # Example common such as compiler warnings
-    include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake)
-
     # due to warnings from other net source, we need to prevent error from some of the warnings options
     target_compile_options(${PROJECT} PUBLIC
         -Wno-error=null-dereference

+ 0 - 3
examples/device/uac2_headset/CMakeLists.txt

@@ -23,9 +23,6 @@ target_include_directories(${PROJECT} PUBLIC
         ${CMAKE_CURRENT_SOURCE_DIR}/src
         )
 
-# Example common such as compiler warnings
-include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake)
-
 # Configure compilation flags and libraries for the example... see the corresponding function
 # in hw/bsp/FAMILY/family.cmake for details.
 family_configure_device_example(${PROJECT})

+ 2 - 1
examples/device/uac2_headset/skip.txt

@@ -3,4 +3,5 @@ mcu:LPC13XX
 mcu:NUC121
 mcu:SAMD11
 mcu:SAME5X
-mcu:SAMG
+mcu:SAMG
+board:stm32l052dap52

+ 0 - 3
examples/device/usbtmc/CMakeLists.txt

@@ -24,9 +24,6 @@ target_include_directories(${PROJECT} PUBLIC
         ${CMAKE_CURRENT_SOURCE_DIR}/src
         )
 
-# Example common such as compiler warnings
-include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake)
-
 # Configure compilation flags and libraries for the example... see the corresponding function
 # in hw/bsp/FAMILY/family.cmake for details.
 family_configure_device_example(${PROJECT})

+ 59 - 11
examples/device/usbtmc/src/usb_descriptors.c

@@ -37,6 +37,9 @@
 #define USB_PID           (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \
                            _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) )
 
+#define USB_VID   0xCafe
+#define USB_BCD   0x0200
+
 //--------------------------------------------------------------------+
 // Device Descriptors
 //--------------------------------------------------------------------+
@@ -51,9 +54,9 @@ tusb_desc_device_t const desc_device =
 
     .bMaxPacketSize0    = CFG_TUD_ENDPOINT0_SIZE,
 
-    .idVendor           = 0xCafe,
+    .idVendor           = USB_VID,
     .idProduct          = USB_PID,
-    .bcdDevice          = 0x0100,
+    .bcdDevice          = USB_BCD,
 
     .iManufacturer      = 0x01,
     .iProduct           = 0x02,
@@ -75,22 +78,22 @@ uint8_t const * tud_descriptor_device_cb(void)
 
 #if defined(CFG_TUD_USBTMC)
 
-#  define TUD_USBTMC_DESC_MAIN(_itfnum,_bNumEndpoints) \
+#  define TUD_USBTMC_DESC_MAIN(_itfnum,_bNumEndpoints, _bulkMaxPacketLength) \
      TUD_USBTMC_IF_DESCRIPTOR(_itfnum, _bNumEndpoints,  /*_stridx = */ 4u, TUD_USBTMC_PROTOCOL_USB488), \
-     TUD_USBTMC_BULK_DESCRIPTORS(/* OUT = */0x01, /* IN = */ 0x81, /* packet size = */USBTMCD_MAX_PACKET_SIZE)
+     TUD_USBTMC_BULK_DESCRIPTORS(/* OUT = */0x01, /* IN = */ 0x81, /* packet size = */_bulkMaxPacketLength)
 
 #if CFG_TUD_USBTMC_ENABLE_INT_EP
 // USBTMC Interrupt xfer always has length of 2, but we use epMaxSize=8 for
 //  compatibility with mcus that only allow 8, 16, 32 or 64 for FS endpoints
-#  define TUD_USBTMC_DESC(_itfnum) \
-     TUD_USBTMC_DESC_MAIN(_itfnum, /* _epCount = */ 3), \
+#  define TUD_USBTMC_DESC(_itfnum, _bulkMaxPacketLength) \
+     TUD_USBTMC_DESC_MAIN(_itfnum, /* _epCount = */ 3, _bulkMaxPacketLength), \
      TUD_USBTMC_INT_DESCRIPTOR(/* INT ep # */ 0x82, /* epMaxSize = */ 8, /* bInterval = */16u )
 #  define TUD_USBTMC_DESC_LEN (TUD_USBTMC_IF_DESCRIPTOR_LEN + TUD_USBTMC_BULK_DESCRIPTORS_LEN + TUD_USBTMC_INT_DESCRIPTOR_LEN)
 
 #else
 
-#  define TUD_USBTMC_DESC(_itfnum) \
-     TUD_USBTMC_DESC_MAIN(_itfnum, /* _epCount = */ 2u)
+#  define TUD_USBTMC_DESC(_itfnum, _bulkMaxPacketLength) \
+     TUD_USBTMC_DESC_MAIN(_itfnum, /* _epCount = */ 2u, _bulkMaxPacketLength)
 #  define TUD_USBTMC_DESC_LEN (TUD_USBTMC_IF_DESCRIPTOR_LEN + TUD_USBTMC_BULK_DESCRIPTORS_LEN)
 
 #endif /* CFG_TUD_USBTMC_ENABLE_INT_EP */
@@ -119,21 +122,66 @@ enum
 #endif
 
 
-uint8_t const desc_configuration[] =
+uint8_t const desc_fs_configuration[] =
 {
   // Config number, interface count, string index, total length, attribute, power in mA
   TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
 
-  TUD_USBTMC_DESC(ITF_NUM_USBTMC),
+  TUD_USBTMC_DESC(ITF_NUM_USBTMC, /* _bulkMaxPacketLength = */ 64),
 };
 
+#if TUD_OPT_HIGH_SPEED
+
+uint8_t const desc_hs_configuration[] =
+{
+  // Config number, interface count, string index, total length, attribute, power in mA
+  TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
+
+  TUD_USBTMC_DESC(ITF_NUM_USBTMC, /* _bulkMaxPacketLength = */ 512),
+};
+
+// other speed configuration
+uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN];
+
+// device qualifier is mostly similar to device descriptor since we don't change configuration based on speed
+tusb_desc_device_qualifier_t const desc_device_qualifier =
+{
+  .bLength            = sizeof(tusb_desc_device_qualifier_t),
+  .bDescriptorType    = TUSB_DESC_DEVICE_QUALIFIER,
+  .bcdUSB             = USB_BCD,
+
+  .bDeviceClass       = 0x00,
+  .bDeviceSubClass    = 0x00,
+  .bDeviceProtocol    = 0x00,
+
+  .bMaxPacketSize0    = CFG_TUD_ENDPOINT0_SIZE,
+  .bNumConfigurations = 0x01,
+  .bReserved          = 0x00
+};
+
+// Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request
+// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete.
+// device_qualifier descriptor describes information about a high-speed capable device that would
+// change if the device were operating at the other speed. If not highspeed capable stall this request.
+uint8_t const* tud_descriptor_device_qualifier_cb(void)
+{
+  return (uint8_t const*) &desc_device_qualifier;
+}
+
+#endif
+
 // Invoked when received GET CONFIGURATION DESCRIPTOR
 // Application return pointer to descriptor
 // Descriptor contents must exist long enough for transfer to complete
 uint8_t const * tud_descriptor_configuration_cb(uint8_t index)
 {
   (void) index; // for multiple configurations
-  return desc_configuration;
+#if TUD_OPT_HIGH_SPEED
+  // Although we are highspeed, host may be fullspeed.
+  return (tud_speed_get() == TUSB_SPEED_HIGH) ?  desc_hs_configuration : desc_fs_configuration;
+#else
+  return desc_fs_configuration;
+#endif
 }
 
 //--------------------------------------------------------------------+

+ 19 - 16
examples/device/usbtmc/visaQuery.py

@@ -1,6 +1,6 @@
 #!/usr/bin/env python3
 
-import visa
+import pyvisa
 import time
 import sys
 
@@ -54,9 +54,9 @@ def test_srq():
 	assert (inst.read_stb() == 0)
 	inst.write("123")
 	
-	#inst.enable_event(visa.constants.VI_EVENT_SERVICE_REQ, visa.constants.VI_QUEUE)
-	#waitrsp = inst.wait_on_event(visa.constants.VI_EVENT_SERVICE_REQ, 5000)
-	#inst.discard_events(visa.constants.VI_EVENT_SERVICE_REQ, visa.constants.VI_QUEUE)
+	#inst.enable_event(pyvisa.constants.VI_EVENT_SERVICE_REQ, pyvisa.constants.VI_QUEUE)
+	#waitrsp = inst.wait_on_event(pyvisa.constants.VI_EVENT_SERVICE_REQ, 5000)
+	#inst.discard_events(pyvisa.constants.VI_EVENT_SERVICE_REQ, pyvisa.constants.VI_QUEUE)
 	#inst.wait_for_srq()
 	time.sleep(0.3)
 	stb = inst.read_stb()
@@ -77,8 +77,8 @@ def test_read_timeout():
 	t0 = time.monotonic()
 	try:
 		rsp = inst.read()
-		assert(false), "Read should have resulted in timeout"
-	except visa.VisaIOError:
+		assert(False), "Read should have resulted in timeout"
+	except pyvisa.VisaIOError:
 		print("  Got expected exception")
 	t = time.monotonic() - t0
 	assert ((t*1000.0) > (inst.timeout - 300))
@@ -99,23 +99,27 @@ def test_abort_in():
 	t0 = time.monotonic()
 	try:
 		rsp = inst.read()
-		assert(false), "Read should have resulted in timeout"
-	except visa.VisaIOError:
+		assert(False), "Read should have resulted in timeout"
+	except pyvisa.VisaIOError:
 		print("  Got expected exception")
 	t = time.monotonic() - t0
 	assert ((t*1000.0) > (inst.timeout - 300))
 	assert ((t*1000.0) < (inst.timeout + 300))
 	print(f"  Delay was {t:0.3}")
-	# Response is still in queue, so send a clear (to be more helpful to the next test)
+	# Response is still in queue, so read it out (to be more helpful to the next test)
 	inst.timeout = 800
 	y = inst.read()
 	assert(y == "xxx\r\n")
 	
 def test_indicate():
 	# perform indicator pulse
-	usb_iface = inst.get_visa_attribute(visa.constants.VI_ATTR_USB_INTFC_NUM)
+	usb_iface = inst.get_visa_attribute(pyvisa.constants.VI_ATTR_USB_INTFC_NUM)
 	retv = inst.control_in(request_type_bitmap_field=0xA1, request_id=64, request_value=0x0000, index=usb_iface, length=0x0001)
-	assert((retv[1] == visa.constants.StatusCode(0)) and (retv[0] == b'\x01')), f"indicator pulse failed: retv={retv}"
+	# pyvisa used to return (statuscode,bytes), but now only returns bytes, so we need to handle both cases
+	if(isinstance(retv,bytes)):
+		assert(retv == b'\x01')
+	else:
+		assert((retv[1] == pyvisa.constants.StatusCode(0)) and (retv[0] == b'\x01')), f"indicator pulse failed: retv={retv}"
 	
 	
 def test_multi_read():
@@ -131,19 +135,19 @@ def test_multi_read():
 	#inst.chunk_size = old_chunk_size
 	
 def test_stall_ep0():
-	usb_iface = inst.get_visa_attribute(visa.constants.VI_ATTR_USB_INTFC_NUM)
+	usb_iface = inst.get_visa_attribute(pyvisa.constants.VI_ATTR_USB_INTFC_NUM)
 	inst.read_stb()
 	# This is an invalid request, should create stall.
 	try:
 		retv = inst.control_in(request_type_bitmap_field=0xA1, request_id=60, request_value=0x0000, index=usb_iface, length=0x0001)
-		assert false
-	except visa.VisaIOError:
+		assert(False)
+	except pyvisa.VisaIOError:
 		pass
 	
 	assert (inst.read_stb() == 0)
 
 
-rm = visa.ResourceManager()
+rm = pyvisa.ResourceManager()
 reslist = rm.list_resources("USB?::?*::INSTR")
 print(reslist)
 
@@ -167,7 +171,6 @@ inst.timeout = 2000
 print("+ multi read")
 test_multi_read()
 
-
 print("+ echo delay=0")
 inst.write("delay 0")
 test_echo(1,175)

+ 6 - 3
examples/device/video_capture/CMakeLists.txt

@@ -12,6 +12,12 @@ family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
 
 add_executable(${PROJECT})
 
+if (FORCE_READONLY)
+target_compile_definitions(${PROJECT} PRIVATE
+  CFG_EXAMPLE_VIDEO_READONLY
+)
+endif()
+
 # Example source
 target_sources(${PROJECT} PUBLIC
   ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
@@ -23,9 +29,6 @@ target_include_directories(${PROJECT} PUBLIC
   ${CMAKE_CURRENT_SOURCE_DIR}/src
 )
 
-# Example common such as compiler warnings
-include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake)
-
 # Configure compilation flags and libraries for the example... see the corresponding function
 # in hw/bsp/FAMILY/family.cmake for details.
 family_configure_device_example(${PROJECT})

+ 7 - 0
examples/device/video_capture/Makefile

@@ -1,6 +1,13 @@
 include ../../../tools/top.mk
 include ../../make.mk
 
+ifeq ($(DISABLE_MJPEG),1)
+CFLAGS += -DCFG_EXAMPLE_VIDEO_DISABLE_MJPEG
+endif
+ifeq ($(FORCE_READONLY),1)
+CFLAGS += -DCFG_EXAMPLE_VIDEO_READONLY
+endif
+
 INC += \
 	src \
 	$(TOP)/hw \

+ 285 - 0
examples/device/video_capture/src/images.h

@@ -1,3 +1,4 @@
+#if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPG)
 static const unsigned char frame_buffer[128 * (96 + 1) * 2] = {
   /* 0 */
   0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80, 0xeb, 0x80,
@@ -1649,3 +1650,287 @@ static const unsigned char frame_buffer[128 * (96 + 1) * 2] = {
   0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80,
   0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80,
 };
+#else
+
+#define color_bar_0_jpg_len  511
+#define color_bar_1_jpg_len  512
+#define color_bar_2_jpg_len  511
+#define color_bar_3_jpg_len  511
+#define color_bar_4_jpg_len  511
+#define color_bar_5_jpg_len  512
+#define color_bar_6_jpg_len  511
+#define color_bar_7_jpg_len  511
+
+unsigned char color_bar_0_jpg[] = {
+  0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11,
+  0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff,
+  0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x92, 0x8a, 0x00,
+  0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45,
+  0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89,
+  0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad,
+  0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25,
+  0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3,
+  0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1,
+  0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00,
+  0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45,
+  0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89,
+  0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad,
+  0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25,
+  0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3,
+  0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1,
+  0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00,
+  0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45,
+  0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89,
+  0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad,
+  0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25,
+  0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3,
+  0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1,
+  0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0xff, 0xd9
+};
+unsigned char color_bar_1_jpg[] = {
+  0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11,
+  0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff,
+  0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x7d, 0x15, 0x98,
+  0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94,
+  0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32,
+  0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51,
+  0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63,
+  0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45,
+  0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84,
+  0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98,
+  0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94,
+  0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32,
+  0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51,
+  0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63,
+  0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45,
+  0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84,
+  0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98,
+  0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94,
+  0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32,
+  0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51,
+  0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63,
+  0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45,
+  0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84,
+  0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x7f, 0xff, 0xd9
+};
+unsigned char color_bar_2_jpg[] = {
+  0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11,
+  0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff,
+  0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x75, 0x14, 0xcc,
+  0xc4, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94,
+  0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18,
+  0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51,
+  0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61,
+  0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66,
+  0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25,
+  0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c,
+  0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94,
+  0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18,
+  0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51,
+  0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61,
+  0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66,
+  0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25,
+  0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c,
+  0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94,
+  0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18,
+  0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51,
+  0x40, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61,
+  0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66,
+  0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x18, 0xda, 0x2b, 0x63, 0x61, 0x28, 0xac, 0xc6, 0x25,
+  0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x2c, 0x51, 0x40, 0x09, 0x45, 0x66, 0x33, 0xff, 0xd9
+};
+unsigned char color_bar_3_jpg[] = {
+  0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11,
+  0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff,
+  0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x5a, 0x2a, 0x08,
+  0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a,
+  0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c,
+  0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac,
+  0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4,
+  0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9,
+  0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12,
+  0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63,
+  0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a,
+  0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c,
+  0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac,
+  0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4,
+  0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9,
+  0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12,
+  0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63,
+  0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a,
+  0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c,
+  0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac,
+  0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4,
+  0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9,
+  0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12,
+  0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x91, 0xff, 0xd9
+};
+unsigned char color_bar_4_jpg[] = {
+  0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11,
+  0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff,
+  0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x4a, 0x2a, 0xcb,
+  0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56,
+  0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62,
+  0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4,
+  0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09,
+  0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31,
+  0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5,
+  0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36,
+  0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56,
+  0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62,
+  0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4,
+  0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09,
+  0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31,
+  0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5,
+  0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36,
+  0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56,
+  0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62,
+  0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4,
+  0xc8, 0x4a, 0x2b, 0x31, 0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09,
+  0x45, 0x66, 0x32, 0xc5, 0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31,
+  0x8d, 0xa2, 0xb6, 0x36, 0x12, 0x8a, 0xcc, 0x62, 0x51, 0x5a, 0x99, 0x09, 0x45, 0x66, 0x32, 0xc5,
+  0x14, 0x00, 0x94, 0x56, 0x63, 0x12, 0x8a, 0xd4, 0xc8, 0x4a, 0x2b, 0x31, 0x9f, 0xff, 0xd9
+};
+unsigned char color_bar_5_jpg[] = {
+  0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11,
+  0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff,
+  0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x6d, 0x14, 0x8d,
+  0x04, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15,
+  0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32,
+  0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56,
+  0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65,
+  0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c,
+  0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28,
+  0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98,
+  0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15,
+  0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32,
+  0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56,
+  0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65,
+  0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c,
+  0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28,
+  0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98,
+  0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15,
+  0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32,
+  0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56,
+  0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65,
+  0x8a, 0x28, 0x01, 0x28, 0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c,
+  0x6c, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x65, 0x8a, 0x28, 0x01, 0x28,
+  0xac, 0xc6, 0x25, 0x15, 0xa9, 0x90, 0x94, 0x56, 0x63, 0x1b, 0x45, 0x6c, 0x6c, 0x7f, 0xff, 0xd9
+};
+unsigned char color_bar_6_jpg[] = {
+  0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11,
+  0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff,
+  0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x65, 0x15, 0xa0,
+  0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15,
+  0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19,
+  0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b,
+  0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a,
+  0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66,
+  0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45,
+  0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c,
+  0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15,
+  0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19,
+  0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b,
+  0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a,
+  0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66,
+  0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45,
+  0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c,
+  0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15,
+  0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19,
+  0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b,
+  0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a,
+  0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66,
+  0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45,
+  0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x33, 0xff, 0xd9
+};
+unsigned char color_bar_7_jpg[] = {
+  0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11,
+  0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff,
+  0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x8e, 0x8a, 0x00,
+  0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad,
+  0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25,
+  0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3,
+  0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2,
+  0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6,
+  0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a,
+  0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c,
+  0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad,
+  0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25,
+  0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3,
+  0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2,
+  0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6,
+  0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a,
+  0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c,
+  0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad,
+  0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25,
+  0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3,
+  0x18, 0x94, 0x56, 0xa6, 0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2,
+  0xb5, 0x32, 0x12, 0x8a, 0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6,
+  0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a,
+  0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x47, 0xff, 0xd9
+};
+#endif

+ 27 - 2
examples/device/video_capture/src/main.c

@@ -112,6 +112,23 @@ static unsigned interval_ms = 1000 / FRAME_RATE;
 /* YUY2 frame buffer */
 #ifdef CFG_EXAMPLE_VIDEO_READONLY
 #include "images.h"
+
+# if !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPG)
+static struct {
+  uint32_t       size;
+  uint8_t const *buffer;
+} const frames[] = {
+  {color_bar_0_jpg_len, color_bar_0_jpg},
+  {color_bar_1_jpg_len, color_bar_1_jpg},
+  {color_bar_2_jpg_len, color_bar_2_jpg},
+  {color_bar_3_jpg_len, color_bar_3_jpg},
+  {color_bar_4_jpg_len, color_bar_4_jpg},
+  {color_bar_5_jpg_len, color_bar_5_jpg},
+  {color_bar_6_jpg_len, color_bar_6_jpg},
+  {color_bar_7_jpg_len, color_bar_7_jpg},
+};
+# endif
+
 #else
 static uint8_t frame_buffer[FRAME_WIDTH * FRAME_HEIGHT * 16 / 8];
 static void fill_color_bar(uint8_t *buffer, unsigned start_position)
@@ -168,8 +185,12 @@ void video_task(void)
     already_sent = 1;
     start_ms = board_millis();
 #ifdef CFG_EXAMPLE_VIDEO_READONLY
-    tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t) &frame_buffer[(frame_num % (FRAME_WIDTH / 2)) * 4],
+# if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPG)
+    tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)&frame_buffer[(frame_num % (FRAME_WIDTH / 2)) * 4],
                            FRAME_WIDTH * FRAME_HEIGHT * 16/8);
+# else
+    tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)frames[frame_num % 8].buffer, frames[frame_num % 8].size);
+# endif
 #else
     fill_color_bar(frame_buffer, frame_num);
     tud_video_n_frame_xfer(0, 0, (void*)frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16/8);
@@ -182,8 +203,12 @@ void video_task(void)
   start_ms += interval_ms;
 
 #ifdef CFG_EXAMPLE_VIDEO_READONLY
-  tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t) &frame_buffer[(frame_num % (FRAME_WIDTH / 2)) * 4],
+# if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPG)
+  tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)&frame_buffer[(frame_num % (FRAME_WIDTH / 2)) * 4],
                          FRAME_WIDTH * FRAME_HEIGHT * 16/8);
+# else
+  tud_video_n_frame_xfer(0, 0, (void*)(uintptr_t)frames[frame_num % 8].buffer, frames[frame_num % 8].size);
+# endif
 #else
   fill_color_bar(frame_buffer, frame_num);
   tud_video_n_frame_xfer(0, 0, (void*)frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16/8);

+ 14 - 4
examples/device/video_capture/src/usb_descriptors.c

@@ -75,7 +75,11 @@ uint8_t const * tud_descriptor_device_cb(void)
 // Configuration Descriptor
 //--------------------------------------------------------------------+
 
-#define CONFIG_TOTAL_LEN    (TUD_CONFIG_DESC_LEN + TUD_VIDEO_CAPTURE_DESC_LEN)
+#if defined(CFG_EXAMPLE_VIDEO_READONLY) && !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG)
+#define CONFIG_TOTAL_LEN    (TUD_CONFIG_DESC_LEN + TUD_VIDEO_CAPTURE_DESC_MJPEG_LEN)
+#else
+#define CONFIG_TOTAL_LEN    (TUD_CONFIG_DESC_LEN + TUD_VIDEO_CAPTURE_DESC_UNCOMPR_LEN)
+#endif
 
 #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
@@ -96,9 +100,15 @@ uint8_t const desc_fs_configuration[] =
   // Config number, interface count, string index, total length, attribute, power in mA
   TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0, 500),
   // IAD for Video Control
-  TUD_VIDEO_CAPTURE_DESCRIPTOR(4, EPNUM_VIDEO_IN,
-                               FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE,
-                               CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE)
+#if defined(CFG_EXAMPLE_VIDEO_READONLY) && !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG)
+  TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(4, EPNUM_VIDEO_IN,
+                                     FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE,
+                                     CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE)
+#else
+  TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(4, EPNUM_VIDEO_IN,
+                                       FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE,
+                                       CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE)
+#endif
 };
 
 // Invoked when received GET CONFIGURATION DESCRIPTOR

+ 62 - 7
examples/device/video_capture/src/usb_descriptors.h

@@ -38,12 +38,12 @@
 #define FRAME_RATE    10
 
 enum {
-  ITF_NUM_VIDEO_CONTROL = 0,
+  ITF_NUM_VIDEO_CONTROL,
   ITF_NUM_VIDEO_STREAMING,
   ITF_NUM_TOTAL
 };
 
-#define TUD_VIDEO_CAPTURE_DESC_LEN (\
+#define TUD_VIDEO_CAPTURE_DESC_UNCOMPR_LEN (\
     TUD_VIDEO_DESC_IAD_LEN\
     /* control */\
     + TUD_VIDEO_DESC_STD_VC_LEN\
@@ -61,6 +61,24 @@ enum {
     + 7/* Endpoint */\
   )
 
+#define TUD_VIDEO_CAPTURE_DESC_MJPEG_LEN (\
+    TUD_VIDEO_DESC_IAD_LEN\
+    /* control */\
+    + TUD_VIDEO_DESC_STD_VC_LEN\
+    + (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\
+    + TUD_VIDEO_DESC_CAMERA_TERM_LEN\
+    + TUD_VIDEO_DESC_OUTPUT_TERM_LEN\
+    /* Interface 1, Alternate 0 */\
+    + TUD_VIDEO_DESC_STD_VS_LEN\
+    + (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\
+    + TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\
+    + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\
+    + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\
+    /* Interface 1, Alternate 1 */\
+    + TUD_VIDEO_DESC_STD_VS_LEN\
+    + 7/* Endpoint */\
+  )
+
 /* Windows support YUY2 and NV12
  * https://docs.microsoft.com/en-us/windows-hardware/drivers/stream/usb-video-class-driver-overview */
 
@@ -73,20 +91,20 @@ enum {
 #define TUD_VIDEO_DESC_CS_VS_FMT_I420(_fmtidx, _numfmtdesc, _frmidx, _asrx, _asry, _interlace, _cp) \
   TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfmtdesc, TUD_VIDEO_GUID_I420, 12, _frmidx, _asrx, _asry, _interlace, _cp)
 
-#define TUD_VIDEO_CAPTURE_DESCRIPTOR(_stridx, _epin, _width, _height, _fps, _epsize) \
-  TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, ITF_NUM_TOTAL, _stridx), \
+#define TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(_stridx, _epin, _width, _height, _fps, _epsize) \
+  TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \
   /* Video control 0 */ \
   TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \
     TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \
          /* wTotalLength - bLength */ \
          TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \
-         UVC_CLOCK_FREQUENCY, 1), \
+         UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \
       TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\
                                  /*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\
                                  /*wObjectiveFocalLength*/0, /*bmControls*/0), \
       TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \
   /* Video stream alt. 0 */ \
-  TUD_VIDEO_DESC_STD_VS( 1, 0, 0, 0), \
+  TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 0, _stridx), \
     /* Video stream header for without still image capture */ \
     TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \
         /*wTotalLength - bLength */\
@@ -106,7 +124,44 @@ enum {
             (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \
         TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \
   /* VS alt 1 */\
-  TUD_VIDEO_DESC_STD_VS(1, 1, 1, 0), \
+  TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 1, 1, _stridx), \
+    /* EP */ \
+    TUD_VIDEO_DESC_EP_ISO(_epin, _epsize, 1)
+
+#define TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(_stridx, _epin, _width, _height, _fps, _epsize) \
+  TUD_VIDEO_DESC_IAD(ITF_NUM_VIDEO_CONTROL, /* 2 Interfaces */ 0x02, _stridx), \
+  /* Video control 0 */ \
+  TUD_VIDEO_DESC_STD_VC(ITF_NUM_VIDEO_CONTROL, 0, _stridx), \
+    TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \
+         /* wTotalLength - bLength */ \
+         TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \
+         UVC_CLOCK_FREQUENCY, ITF_NUM_VIDEO_STREAMING), \
+      TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\
+                                 /*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\
+                                 /*wObjectiveFocalLength*/0, /*bmControls*/0), \
+      TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \
+  /* Video stream alt. 0 */ \
+  TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 0, 0, _stridx), \
+    /* Video stream header for without still image capture */ \
+    TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \
+        /*wTotalLength - bLength */\
+        TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\
+        + TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\
+        + TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\
+        _epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \
+        /*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \
+        /*bmaControls(1)*/0), \
+      /* Video stream format */ \
+      TUD_VIDEO_DESC_CS_VS_FMT_MJPEG(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \
+        /*bmFlags*/0, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \
+        /* Video stream frame format */ \
+        TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT(/*bFrameIndex */1, 0, _width, _height, \
+            _width * _height * 16, _width * _height * 16 * _fps, \
+            _width * _height * 16 / 8, \
+            (10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \
+        TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \
+  /* VS alt 1 */\
+  TUD_VIDEO_DESC_STD_VS(ITF_NUM_VIDEO_STREAMING, 1, 1, _stridx), \
     /* EP */ \
     TUD_VIDEO_DESC_EP_ISO(_epin, _epsize, 1)
 

+ 0 - 3
examples/device/webusb_serial/CMakeLists.txt

@@ -23,9 +23,6 @@ target_include_directories(${PROJECT} PUBLIC
         ${CMAKE_CURRENT_SOURCE_DIR}/src
         )
 
-# Example common such as compiler warnings
-include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake)
-
 # Configure compilation flags and libraries for the example... see the corresponding function
 # in hw/bsp/FAMILY/family.cmake for details.
 family_configure_device_example(${PROJECT})

+ 4 - 2
examples/device/webusb_serial/src/main.c

@@ -71,7 +71,7 @@ enum  {
 
 static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
 
-#define URL  "example.tinyusb.org/webusb-serial/"
+#define URL  "example.tinyusb.org/webusb-serial/index.html"
 
 const tusb_desc_webusb_url_t desc_url =
 {
@@ -114,6 +114,7 @@ void echo_all(uint8_t buf[], uint32_t count)
   if ( web_serial_connected )
   {
     tud_vendor_write(buf, count);
+    tud_vendor_flush();
   }
 
   // echo to cdc
@@ -211,7 +212,8 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ
           board_led_write(true);
           blink_interval_ms = BLINK_ALWAYS_ON;
 
-          tud_vendor_write_str("\r\nTinyUSB WebUSB device example\r\n");
+          tud_vendor_write_str("\r\nWebUSB interface connected\r\n");
+          tud_vendor_flush();
         }else
         {
           blink_interval_ms = BLINK_MOUNTED;

+ 4 - 7
examples/dual/host_hid_to_device_cdc/CMakeLists.txt

@@ -23,10 +23,11 @@ target_include_directories(${PROJECT} PUBLIC
         ${CMAKE_CURRENT_SOURCE_DIR}/src
         )
 
-# Example common such as compiler warnings
-include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake)
+# Configure compilation flags and libraries for the example... see the corresponding function
+# in hw/bsp/FAMILY/family.cmake for details.
+family_configure_dual_usb_example(${PROJECT})
 
-# due to warnings from other net source, we need to prevent error from some of the warnings options
+# due to warnings from Pico-PIO-USB
 target_compile_options(${PROJECT} PUBLIC
         -Wno-error=shadow
         -Wno-error=cast-align
@@ -37,7 +38,3 @@ target_compile_options(${PROJECT} PUBLIC
         -Wno-error=sign-compare
         -Wno-error=unused-function
         )
-
-# Configure compilation flags and libraries for the example... see the corresponding function
-# in hw/bsp/FAMILY/family.cmake for details.
-family_configure_dual_usb_example(${PROJECT})

+ 0 - 31
examples/example.cmake

@@ -1,31 +0,0 @@
-target_compile_options(${PROJECT} PUBLIC
-        -Wall
-        -Wextra
-        -Werror
-        -Wfatal-errors
-        -Wdouble-promotion
-        #-Wstrict-prototypes
-        -Wstrict-overflow
-        #-Werror-implicit-function-declaration
-        -Wfloat-equal
-        #-Wundef
-        -Wshadow
-        -Wwrite-strings
-        -Wsign-compare
-        -Wmissing-format-attribute
-        -Wunreachable-code
-        -Wcast-align
-        -Wcast-function-type
-        -Wcast-qual
-        -Wnull-dereference
-        -Wuninitialized
-        -Wunused
-        -Wredundant-decls
-        )
-
-# GCC version 9 or prior has a bug with incorrect Wconversion warnings
-if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10.0)
-  target_compile_options(${PROJECT} PUBLIC
-        -Wconversion
-        )
-endif()

+ 2 - 0
examples/host/CMakeLists.txt

@@ -6,5 +6,7 @@ project(tinyusb_host_examples)
 family_initialize_project(tinyusb_host_examples ${CMAKE_CURRENT_LIST_DIR})
 
 # family_add_subdirectory will filter what to actually add based on selected FAMILY
+family_add_subdirectory(bare_api)
 family_add_subdirectory(cdc_msc_hid)
 family_add_subdirectory(hid_controller)
+family_add_subdirectory(msc_file_explorer)

+ 11 - 5
examples/host/bare_api/CMakeLists.txt

@@ -22,12 +22,18 @@ target_include_directories(${PROJECT} PUBLIC
         ${CMAKE_CURRENT_SOURCE_DIR}/src
         )
 
-# Example common such as compiler warnings
-include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake)
-
 # Configure compilation flags and libraries for the example... see the corresponding function
 # in hw/bsp/FAMILY/family.cmake for details.
 family_configure_host_example(${PROJECT})
 
-# For rp2040, un-comment to enable pico-pio-usb
-# family_add_pico_pio_usb(${PROJECT})
+# For rp2040 enable pico-pio-usb
+if(FAMILY STREQUAL "rp2040")
+  family_add_pico_pio_usb(${PROJECT})
+
+  # due to warnings from Pico-PIO-USB
+  target_compile_options(${PROJECT} PUBLIC
+          -Wno-error=cast-qual
+          -Wno-error=sign-conversion
+          -Wno-error=conversion
+          )
+endif()

+ 0 - 3
examples/host/bare_api/Makefile

@@ -11,9 +11,6 @@ EXAMPLE_SOURCE += \
 
 SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE))
 
-# TODO: suppress warning caused by host stack
-CFLAGS += -Wno-error=cast-align -Wno-error=null-dereference
-
 # TinyUSB Host Stack source
 SRC_C += \
 	src/class/cdc/cdc_host.c \

+ 6 - 0
examples/host/bare_api/src/tusb_config.h

@@ -34,6 +34,12 @@
 // Board Specific Configuration
 //--------------------------------------------------------------------+
 
+#if CFG_TUSB_MCU == OPT_MCU_RP2040
+// change to 1 if using pico-pio-usb as host controller for raspberry rp2040
+#define CFG_TUH_RPI_PIO_USB   0
+#define BOARD_TUH_RHPORT      CFG_TUH_RPI_PIO_USB
+#endif
+
 // RHPort number used for host can be defined by board.mk, default to port 0
 #ifndef BOARD_TUH_RHPORT
 #define BOARD_TUH_RHPORT      0

+ 12 - 5
examples/host/cdc_msc_hid/CMakeLists.txt

@@ -14,6 +14,7 @@ add_executable(${PROJECT})
 
 # Example source
 target_sources(${PROJECT} PUBLIC
+        ${CMAKE_CURRENT_SOURCE_DIR}/src/cdc_app.c
         ${CMAKE_CURRENT_SOURCE_DIR}/src/hid_app.c
         ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
         ${CMAKE_CURRENT_SOURCE_DIR}/src/msc_app.c
@@ -24,12 +25,18 @@ target_include_directories(${PROJECT} PUBLIC
         ${CMAKE_CURRENT_SOURCE_DIR}/src
         )
 
-# Example common such as compiler warnings
-include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake)
-
 # Configure compilation flags and libraries for the example... see the corresponding function
 # in hw/bsp/FAMILY/family.cmake for details.
 family_configure_host_example(${PROJECT})
 
-# For rp2040, un-comment to enable pico-pio-usb
-# family_add_pico_pio_usb(${PROJECT})
+# For rp2040 enable pico-pio-usb
+if(FAMILY STREQUAL "rp2040")
+  family_add_pico_pio_usb(${PROJECT})
+
+  # due to warnings from Pico-PIO-USB
+  target_compile_options(${PROJECT} PUBLIC
+          -Wno-error=cast-qual
+          -Wno-error=sign-conversion
+          -Wno-error=conversion
+          )
+endif()

+ 6 - 4
examples/host/cdc_msc_hid/Makefile

@@ -6,11 +6,13 @@ INC += \
 	$(TOP)/hw \
 
 # Example source
-EXAMPLE_SOURCE += $(wildcard src/*.c)
-SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE))
+EXAMPLE_SOURCE = \
+  src/cdc_app.c \
+  src/hid_app.c \
+  src/main.c \
+  src/msc_app.c \
 
-# TODO: suppress warning caused by host stack
-CFLAGS += -Wno-error=cast-align -Wno-error=null-dereference
+SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE))
 
 # TinyUSB Host Stack source
 SRC_C += \

+ 113 - 0
examples/host/cdc_msc_hid/src/cdc_app.c

@@ -0,0 +1,113 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2022, Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#include "tusb.h"
+#include "bsp/board.h"
+
+//--------------------------------------------------------------------+
+// MACRO TYPEDEF CONSTANT ENUM DECLARATION
+//--------------------------------------------------------------------+
+
+
+//------------- IMPLEMENTATION -------------//
+
+size_t get_console_inputs(uint8_t* buf, size_t bufsize)
+{
+  size_t count = 0;
+  while (count < bufsize)
+  {
+    int ch = board_getchar();
+    if ( ch <= 0 ) break;
+
+    buf[count] = (uint8_t) ch;
+    count++;
+  }
+
+  return count;
+}
+
+void cdc_app_task(void)
+{
+  uint8_t buf[64+1]; // +1 for extra null character
+  uint32_t const bufsize = sizeof(buf)-1;
+
+  uint32_t count = get_console_inputs(buf, bufsize);
+  buf[count] = 0;
+
+  // loop over all mounted interfaces
+  for(uint8_t idx=0; idx<CFG_TUH_CDC; idx++)
+  {
+    if ( tuh_cdc_mounted(idx) )
+    {
+      // console --> cdc interfaces
+      if (count)
+      {
+        tuh_cdc_write(idx, buf, count);
+        tuh_cdc_write_flush(idx);
+      }
+    }
+  }
+}
+
+// Invoked when received new data
+void tuh_cdc_rx_cb(uint8_t idx)
+{
+  uint8_t buf[64+1]; // +1 for extra null character
+  uint32_t const bufsize = sizeof(buf)-1;
+
+  // forward cdc interfaces -> console
+  uint32_t count = tuh_cdc_read(idx, buf, bufsize);
+  buf[count] = 0;
+
+  printf((char*) buf);
+}
+
+void tuh_cdc_mount_cb(uint8_t idx)
+{
+  tuh_cdc_itf_info_t itf_info = { 0 };
+  tuh_cdc_itf_get_info(idx, &itf_info);
+
+  printf("CDC Interface is mounted: address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.bInterfaceNumber);
+
+#ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM
+  // CFG_TUH_CDC_LINE_CODING_ON_ENUM must be defined for line coding is set by tinyusb in enumeration
+  // otherwise you need to call tuh_cdc_set_line_coding() first
+  cdc_line_coding_t line_coding = { 0 };
+  if ( tuh_cdc_get_local_line_coding(idx, &line_coding) )
+  {
+    printf("  Baudrate: %lu, Stop Bits : %u\r\n", line_coding.bit_rate, line_coding.stop_bits);
+    printf("  Parity  : %u, Data Width: %u\r\n", line_coding.parity  , line_coding.data_bits);
+  }
+#endif
+}
+
+void tuh_cdc_umount_cb(uint8_t idx)
+{
+  tuh_cdc_itf_info_t itf_info = { 0 };
+  tuh_cdc_itf_get_info(idx, &itf_info);
+
+  printf("CDC Interface is unmounted: address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.bInterfaceNumber);
+}

+ 1 - 1
examples/host/cdc_msc_hid/src/hid_app.c

@@ -247,7 +247,7 @@ static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t c
     // Composite report, 1st byte is report ID, data starts from 2nd byte
     uint8_t const rpt_id = report[0];
 
-    // Find report id in the arrray
+    // Find report id in the array
     for(uint8_t i=0; i<rpt_count; i++)
     {
       if (rpt_id == rpt_info_arr[i].report_id )

+ 3 - 34
examples/host/cdc_msc_hid/src/main.c

@@ -35,7 +35,7 @@
 //--------------------------------------------------------------------+
 void led_blinking_task(void);
 
-extern void cdc_task(void);
+extern void cdc_app_task(void);
 extern void hid_app_task(void);
 
 /*------------- MAIN -------------*/
@@ -52,46 +52,15 @@ int main(void)
   {
     // tinyusb host task
     tuh_task();
-    led_blinking_task();
-
-#if CFG_TUH_CDC
-    cdc_task();
-#endif
 
-#if CFG_TUH_HID
+    led_blinking_task();
+    cdc_app_task();
     hid_app_task();
-#endif
   }
 
   return 0;
 }
 
-//--------------------------------------------------------------------+
-// USB CDC
-//--------------------------------------------------------------------+
-#if CFG_TUH_CDC
-CFG_TUSB_MEM_SECTION static char serial_in_buffer[64] = { 0 };
-
-// invoked ISR context
-void tuh_cdc_xfer_isr(uint8_t dev_addr, xfer_result_t event, cdc_pipeid_t pipe_id, uint32_t xferred_bytes)
-{
-  (void) event;
-  (void) pipe_id;
-  (void) xferred_bytes;
-
-  printf(serial_in_buffer);
-  tu_memclr(serial_in_buffer, sizeof(serial_in_buffer));
-
-  tuh_cdc_receive(dev_addr, serial_in_buffer, sizeof(serial_in_buffer), true); // waiting for next data
-}
-
-void cdc_task(void)
-{
-
-}
-
-#endif
-
 //--------------------------------------------------------------------+
 // TinyUSB Callbacks
 //--------------------------------------------------------------------+

+ 5 - 40
examples/host/cdc_msc_hid/src/msc_app.c

@@ -25,15 +25,16 @@
 
 #include "tusb.h"
 
-#if CFG_TUH_MSC
-
 //--------------------------------------------------------------------+
 // MACRO TYPEDEF CONSTANT ENUM DECLARATION
 //--------------------------------------------------------------------+
 static scsi_inquiry_resp_t inquiry_resp;
 
-bool inquiry_complete_cb(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw)
+bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_data)
 {
+  msc_cbw_t const* cbw = cb_data->cbw;
+  msc_csw_t const* csw = cb_data->csw;
+
   if (csw->status != 0)
   {
     printf("Inquiry failed\r\n");
@@ -59,48 +60,12 @@ void tuh_msc_mount_cb(uint8_t dev_addr)
   printf("A MassStorage device is mounted\r\n");
 
   uint8_t const lun = 0;
-  tuh_msc_inquiry(dev_addr, lun, &inquiry_resp, inquiry_complete_cb);
-//
-//  //------------- file system (only 1 LUN support) -------------//
-//  uint8_t phy_disk = dev_addr-1;
-//  disk_initialize(phy_disk);
-//
-//  if ( disk_is_ready(phy_disk) )
-//  {
-//    if ( f_mount(phy_disk, &fatfs[phy_disk]) != FR_OK )
-//    {
-//      puts("mount failed");
-//      return;
-//    }
-//
-//    f_chdrive(phy_disk); // change to newly mounted drive
-//    f_chdir("/"); // root as current dir
-//
-//    cli_init();
-//  }
+  tuh_msc_inquiry(dev_addr, lun, &inquiry_resp, inquiry_complete_cb, 0);
 }
 
 void tuh_msc_umount_cb(uint8_t dev_addr)
 {
   (void) dev_addr;
   printf("A MassStorage device is unmounted\r\n");
-
-//  uint8_t phy_disk = dev_addr-1;
-//
-//  f_mount(phy_disk, NULL); // unmount disk
-//  disk_deinitialize(phy_disk);
-//
-//  if ( phy_disk == f_get_current_drive() )
-//  { // active drive is unplugged --> change to other drive
-//    for(uint8_t i=0; i<CFG_TUH_DEVICE_MAX; i++)
-//    {
-//      if ( disk_is_ready(i) )
-//      {
-//        f_chdrive(i);
-//        cli_init(); // refractor, rename
-//      }
-//    }
-//  }
 }
 
-#endif

+ 17 - 0
examples/host/cdc_msc_hid/src/tusb_config.h

@@ -34,6 +34,12 @@
 // Board Specific Configuration
 //--------------------------------------------------------------------+
 
+#if CFG_TUSB_MCU == OPT_MCU_RP2040
+// change to 1 if using pico-pio-usb as host controller for raspberry rp2040
+#define CFG_TUH_RPI_PIO_USB   0
+#define BOARD_TUH_RHPORT      CFG_TUH_RPI_PIO_USB
+#endif
+
 // RHPort number used for host can be defined by board.mk, default to port 0
 #ifndef BOARD_TUH_RHPORT
 #define BOARD_TUH_RHPORT      0
@@ -102,6 +108,17 @@
 #define CFG_TUH_HID_EPIN_BUFSIZE    64
 #define CFG_TUH_HID_EPOUT_BUFSIZE   64
 
+//------------- CDC -------------//
+
+// Set Line Control state on enumeration/mounted:
+// DTR ( bit 0), RTS (bit 1)
+#define CFG_TUH_CDC_LINE_CONTROL_ON_ENUM    0x03
+
+// Set Line Coding on enumeration/mounted, value for cdc_line_coding_t
+// bit rate = 115200, 1 stop bit, no parity, 8 bit data width
+#define CFG_TUH_CDC_LINE_CODING_ON_ENUM   { 115200, CDC_LINE_CONDING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 }
+
+
 #ifdef __cplusplus
  }
 #endif

+ 11 - 5
examples/host/hid_controller/CMakeLists.txt

@@ -23,12 +23,18 @@ target_include_directories(${PROJECT} PUBLIC
         ${CMAKE_CURRENT_SOURCE_DIR}/src
         )
 
-# Example common such as compiler warnings
-include(${CMAKE_CURRENT_SOURCE_DIR}/../../example.cmake)
-
 # Configure compilation flags and libraries for the example... see the corresponding function
 # in hw/bsp/FAMILY/family.cmake for details.
 family_configure_host_example(${PROJECT})
 
-# For rp2040, un-comment to enable pico-pio-usb
-# family_add_pico_pio_usb(${PROJECT})
+# For rp2040 enable pico-pio-usb
+if(FAMILY STREQUAL "rp2040")
+  family_add_pico_pio_usb(${PROJECT})
+
+  # due to warnings from Pico-PIO-USB
+  target_compile_options(${PROJECT} PUBLIC
+          -Wno-error=cast-qual
+          -Wno-error=sign-conversion
+          -Wno-error=conversion
+          )
+endif()

+ 0 - 3
examples/host/hid_controller/Makefile

@@ -12,9 +12,6 @@ EXAMPLE_SOURCE += \
 
 SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE))
 
-# TODO: suppress warning caused by host stack
-CFLAGS += -Wno-error=cast-align -Wno-error=null-dereference
-
 # TinyUSB Host Stack source
 SRC_C += \
 	src/class/cdc/cdc_host.c \

+ 0 - 1
examples/host/hid_controller/src/hid_app.c

@@ -162,7 +162,6 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re
 void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance)
 {
   printf("HID device address = %d, instance = %d is unmounted\r\n", dev_addr, instance);
-
 }
 
 // check if different than 2

+ 6 - 0
examples/host/hid_controller/src/tusb_config.h

@@ -34,6 +34,12 @@
 // Board Specific Configuration
 //--------------------------------------------------------------------+
 
+ #if CFG_TUSB_MCU == OPT_MCU_RP2040
+// change to 1 if using pico-pio-usb as host controller for raspberry rp2040
+#define CFG_TUH_RPI_PIO_USB   0
+#define BOARD_TUH_RHPORT      CFG_TUH_RPI_PIO_USB
+#endif
+
 // RHPort number used for host can be defined by board.mk, default to port 0
 #ifndef BOARD_TUH_RHPORT
 #define BOARD_TUH_RHPORT      0

+ 45 - 0
examples/host/msc_file_explorer/CMakeLists.txt

@@ -0,0 +1,45 @@
+cmake_minimum_required(VERSION 3.5)
+
+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})
+
+# Checks this example is valid for the family and initializes the project
+family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+
+add_executable(${PROJECT})
+
+# Example source
+target_sources(${PROJECT} PUBLIC
+        ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
+        ${CMAKE_CURRENT_SOURCE_DIR}/src/msc_app.c
+        ${TOP}/lib/fatfs/source/ff.c
+        ${TOP}/lib/fatfs/source/ffsystem.c
+        ${TOP}/lib/fatfs/source/ffunicode.c
+        )
+
+# Example include
+target_include_directories(${PROJECT} PUBLIC
+        ${CMAKE_CURRENT_SOURCE_DIR}/src
+        ${TOP}/lib/fatfs/source
+        ${TOP}/lib/embedded-cli
+        )
+
+# Configure compilation flags and libraries for the example... see the corresponding function
+# in hw/bsp/FAMILY/family.cmake for details.
+family_configure_host_example(${PROJECT})
+
+# For rp2040 enable pico-pio-usb
+if(FAMILY STREQUAL "rp2040")
+  family_add_pico_pio_usb(${PROJECT})
+
+  # due to warnings from Pico-PIO-USB
+  target_compile_options(${PROJECT} PUBLIC
+          -Wno-error=cast-qual
+          -Wno-error=sign-conversion
+          -Wno-error=conversion
+          )
+endif()

+ 38 - 0
examples/host/msc_file_explorer/Makefile

@@ -0,0 +1,38 @@
+include ../../../tools/top.mk
+include ../../make.mk
+
+FATFS_PATH = lib/fatfs/source
+
+INC += \
+	src \
+	$(TOP)/hw \
+	$(TOP)/$(FATFS_PATH) \
+	$(TOP)/lib/embedded-cli \
+
+# Example source
+EXAMPLE_SOURCE = \
+  src/main.c \
+  src/msc_app.c \
+
+SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE))
+
+# FatFS source
+SRC_C += \
+  $(FATFS_PATH)/ff.c \
+  $(FATFS_PATH)/ffsystem.c \
+  $(FATFS_PATH)/ffunicode.c \
+
+# suppress warning caused by fatfs
+CFLAGS += -Wno-error=cast-qual
+
+# TinyUSB Host Stack source
+SRC_C += \
+	src/class/cdc/cdc_host.c \
+	src/class/hid/hid_host.c \
+	src/class/msc/msc_host.c \
+	src/host/hub.c \
+	src/host/usbh.c \
+	src/portable/ohci/ohci.c \
+	src/portable/nxp/lpc17_40/hcd_lpc17_40.c
+
+include ../../rules.mk

+ 11 - 0
examples/host/msc_file_explorer/only.txt

@@ -0,0 +1,11 @@
+mcu:LPC175X_6X
+mcu:LPC177X_8X
+mcu:LPC18XX
+mcu:LPC40XX
+mcu:LPC43XX
+mcu:MIMXRT
+mcu:MIMXRT10XX
+mcu:MIMXRT11XX
+mcu:RP2040
+mcu:MSP432E4
+mcu:RX65X

+ 95 - 0
examples/host/msc_file_explorer/src/main.c

@@ -0,0 +1,95 @@
+/* 
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "bsp/board.h"
+#include "tusb.h"
+
+//--------------------------------------------------------------------+
+// MACRO CONSTANT TYPEDEF PROTYPES
+//--------------------------------------------------------------------+
+void led_blinking_task(void);
+
+// from msc_app.c
+extern bool msc_app_init(void);
+extern void msc_app_task(void);
+
+/*------------- MAIN -------------*/
+int main(void)
+{
+  board_init();
+
+  printf("TinyUSB Host MassStorage Explorer Example\r\n");
+
+  // init host stack on configured roothub port
+  tuh_init(BOARD_TUH_RHPORT);
+  msc_app_init();
+
+  while (1)
+  {
+    // tinyusb host task
+    tuh_task();
+
+    msc_app_task();
+    led_blinking_task();
+  }
+
+  return 0;
+}
+
+//--------------------------------------------------------------------+
+// TinyUSB Callbacks
+//--------------------------------------------------------------------+
+
+void tuh_mount_cb(uint8_t dev_addr)
+{
+  (void) dev_addr;
+}
+
+void tuh_umount_cb(uint8_t dev_addr)
+{
+  (void) dev_addr;
+}
+
+//--------------------------------------------------------------------+
+// Blinking Task
+//--------------------------------------------------------------------+
+void led_blinking_task(void)
+{
+  const uint32_t interval_ms = 1000;
+  static uint32_t start_ms = 0;
+
+  static bool led_state = false;
+
+  // Blink every interval ms
+  if ( board_millis() - start_ms < interval_ms) return; // not enough time
+  start_ms += interval_ms;
+
+  board_led_write(led_state);
+  led_state = 1 - led_state; // toggle
+}

+ 640 - 0
examples/host/msc_file_explorer/src/msc_app.c

@@ -0,0 +1,640 @@
+/* 
+ * 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 <ctype.h>
+#include "tusb.h"
+#include "bsp/board.h"
+
+#include "ff.h"
+#include "diskio.h"
+
+// lib/embedded-cli
+#define EMBEDDED_CLI_IMPL
+#include "embedded_cli.h"
+
+
+//--------------------------------------------------------------------+
+// MACRO TYPEDEF CONSTANT ENUM DECLARATION
+//--------------------------------------------------------------------+
+
+//------------- embedded-cli -------------//
+#define CLI_BUFFER_SIZE     512
+#define CLI_RX_BUFFER_SIZE  16
+#define CLI_CMD_BUFFER_SIZE 64
+#define CLI_HISTORY_SIZE    32
+#define CLI_BINDING_COUNT   8
+
+static EmbeddedCli *_cli;
+static CLI_UINT cli_buffer[BYTES_TO_CLI_UINTS(CLI_BUFFER_SIZE)];
+
+//------------- Elm Chan FatFS -------------//
+static FATFS fatfs[CFG_TUH_DEVICE_MAX]; // for simplicity only support 1 LUN per device
+static volatile bool _disk_busy[CFG_TUH_DEVICE_MAX];
+
+static scsi_inquiry_resp_t inquiry_resp;
+
+//--------------------------------------------------------------------+
+//
+//--------------------------------------------------------------------+
+
+bool cli_init(void);
+
+bool msc_app_init(void)
+{
+  for(size_t i=0; i<CFG_TUH_DEVICE_MAX; i++) _disk_busy[i] = false;
+
+  // disable stdout buffered for echoing typing command
+  setbuf(stdout, NULL);
+  cli_init();
+
+  return true;
+}
+
+void msc_app_task(void)
+{
+  if (!_cli) return;
+
+  int ch = board_getchar();
+  if ( ch > 0 )
+  {
+    while( ch > 0 )
+    {
+      embeddedCliReceiveChar(_cli, (char) ch);
+      ch = board_getchar();
+    }
+    embeddedCliProcess(_cli);
+  }
+}
+
+//--------------------------------------------------------------------+
+//
+//--------------------------------------------------------------------+
+
+
+bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_data)
+{
+  msc_cbw_t const* cbw = cb_data->cbw;
+  msc_csw_t const* csw = cb_data->csw;
+
+  if (csw->status != 0)
+  {
+    printf("Inquiry failed\r\n");
+    return false;
+  }
+
+  // Print out Vendor ID, Product ID and Rev
+  printf("%.8s %.16s rev %.4s\r\n", inquiry_resp.vendor_id, inquiry_resp.product_id, inquiry_resp.product_rev);
+
+  // Get capacity of device
+  uint32_t const block_count = tuh_msc_get_block_count(dev_addr, cbw->lun);
+  uint32_t const block_size = tuh_msc_get_block_size(dev_addr, cbw->lun);
+
+  printf("Disk Size: %lu MB\r\n", block_count / ((1024*1024)/block_size));
+  // printf("Block Count = %lu, Block Size: %lu\r\n", block_count, block_size);
+
+  // For simplicity: we only mount 1 LUN per device
+  uint8_t const drive_num = dev_addr-1;
+  char drive_path[3] = "0:";
+  drive_path[0] += drive_num;
+
+  if ( f_mount(&fatfs[drive_num], drive_path, 1) != FR_OK )
+  {
+    puts("mount failed");
+  }
+
+  // change to newly mounted drive
+  f_chdir(drive_path);
+
+  // print the drive label
+//  char label[34];
+//  if ( FR_OK == f_getlabel(drive_path, label, NULL) )
+//  {
+//    puts(label);
+//  }
+
+  return true;
+}
+
+//------------- IMPLEMENTATION -------------//
+void tuh_msc_mount_cb(uint8_t dev_addr)
+{
+  printf("A MassStorage device is mounted\r\n");
+
+  uint8_t const lun = 0;
+  tuh_msc_inquiry(dev_addr, lun, &inquiry_resp, inquiry_complete_cb, 0);
+}
+
+void tuh_msc_umount_cb(uint8_t dev_addr)
+{
+  printf("A MassStorage device is unmounted\r\n");
+
+  uint8_t const drive_num = dev_addr-1;
+  char drive_path[3] = "0:";
+  drive_path[0] += drive_num;
+
+  f_unmount(drive_path);
+
+//  if ( phy_disk == f_get_current_drive() )
+//  { // active drive is unplugged --> change to other drive
+//    for(uint8_t i=0; i<CFG_TUH_DEVICE_MAX; i++)
+//    {
+//      if ( disk_is_ready(i) )
+//      {
+//        f_chdrive(i);
+//        cli_init(); // refractor, rename
+//      }
+//    }
+//  }
+}
+
+//--------------------------------------------------------------------+
+// DiskIO
+//--------------------------------------------------------------------+
+
+static void wait_for_disk_io(BYTE pdrv)
+{
+  while(_disk_busy[pdrv])
+  {
+    tuh_task();
+  }
+}
+
+static bool disk_io_complete(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_data)
+{
+  (void) dev_addr; (void) cb_data;
+  _disk_busy[dev_addr-1] = false;
+  return true;
+}
+
+DSTATUS disk_status (
+	BYTE pdrv		/* Physical drive nmuber to identify the drive */
+)
+{
+  uint8_t dev_addr = pdrv + 1;
+  return tuh_msc_mounted(dev_addr) ? 0 : STA_NODISK;
+}
+
+DSTATUS disk_initialize (
+	BYTE pdrv				/* Physical drive nmuber to identify the drive */
+)
+{
+  (void) pdrv;
+	return 0; // nothing to do
+}
+
+DRESULT disk_read (
+	BYTE pdrv,		/* Physical drive nmuber to identify the drive */
+	BYTE *buff,		/* Data buffer to store read data */
+	LBA_t sector,	/* Start sector in LBA */
+	UINT count		/* Number of sectors to read */
+)
+{
+	uint8_t const dev_addr = pdrv + 1;
+	uint8_t const lun = 0;
+
+	_disk_busy[pdrv] = true;
+	tuh_msc_read10(dev_addr, lun, buff, sector, (uint16_t) count, disk_io_complete, 0);
+	wait_for_disk_io(pdrv);
+
+	return RES_OK;
+}
+
+#if FF_FS_READONLY == 0
+
+DRESULT disk_write (
+	BYTE pdrv,			/* Physical drive nmuber to identify the drive */
+	const BYTE *buff,	/* Data to be written */
+	LBA_t sector,		/* Start sector in LBA */
+	UINT count			/* Number of sectors to write */
+)
+{
+	uint8_t const dev_addr = pdrv + 1;
+	uint8_t const lun = 0;
+
+	_disk_busy[pdrv] = true;
+	tuh_msc_write10(dev_addr, lun, buff, sector, (uint16_t) count, disk_io_complete, 0);
+	wait_for_disk_io(pdrv);
+
+	return RES_OK;
+}
+
+#endif
+
+DRESULT disk_ioctl (
+	BYTE pdrv,		/* Physical drive nmuber (0..) */
+	BYTE cmd,		/* Control code */
+	void *buff		/* Buffer to send/receive control data */
+)
+{
+  uint8_t const dev_addr = pdrv + 1;
+  uint8_t const lun = 0;
+  switch ( cmd )
+  {
+    case CTRL_SYNC:
+      // nothing to do since we do blocking
+      return RES_OK;
+
+    case GET_SECTOR_COUNT:
+      *((DWORD*) buff) = (WORD) tuh_msc_get_block_count(dev_addr, lun);
+      return RES_OK;
+
+    case GET_SECTOR_SIZE:
+      *((WORD*) buff) = (WORD) tuh_msc_get_block_size(dev_addr, lun);
+      return RES_OK;
+
+    case GET_BLOCK_SIZE:
+      *((DWORD*) buff) = 1;    // erase block size in units of sector size
+      return RES_OK;
+
+    default:
+      return RES_PARERR;
+  }
+
+	return RES_OK;
+}
+
+//--------------------------------------------------------------------+
+// CLI Commands
+//--------------------------------------------------------------------+
+
+void cli_cmd_cat(EmbeddedCli *cli, char *args, void *context);
+void cli_cmd_cd(EmbeddedCli *cli, char *args, void *context);
+void cli_cmd_cp(EmbeddedCli *cli, char *args, void *context);
+void cli_cmd_ls(EmbeddedCli *cli, char *args, void *context);
+void cli_cmd_pwd(EmbeddedCli *cli, char *args, void *context);
+void cli_cmd_mkdir(EmbeddedCli *cli, char *args, void *context);
+void cli_cmd_mv(EmbeddedCli *cli, char *args, void *context);
+void cli_cmd_rm(EmbeddedCli *cli, char *args, void *context);
+
+void cli_write_char(EmbeddedCli *cli, char c)
+{
+  (void) cli;
+  putchar((int) c);
+}
+
+void cli_cmd_unknown(EmbeddedCli *cli, CliCommand *command)
+{
+  (void) cli;
+  printf("%s: command not found\r\n", command->name);
+}
+
+bool cli_init(void)
+{
+  EmbeddedCliConfig *config = embeddedCliDefaultConfig();
+  config->cliBuffer         = cli_buffer;
+  config->cliBufferSize     = CLI_BUFFER_SIZE;
+  config->rxBufferSize      = CLI_RX_BUFFER_SIZE;
+  config->cmdBufferSize     = CLI_CMD_BUFFER_SIZE;
+  config->historyBufferSize = CLI_HISTORY_SIZE;
+  config->maxBindingCount   = CLI_BINDING_COUNT;
+
+  TU_ASSERT(embeddedCliRequiredSize(config) <= CLI_BUFFER_SIZE);
+
+  _cli = embeddedCliNew(config);
+  TU_ASSERT(_cli != NULL);
+
+  _cli->writeChar = cli_write_char;
+
+  embeddedCliAddBinding(_cli, (CliCommandBinding) {
+    "cat",
+    "Usage: cat [FILE]...\r\n\tConcatenate FILE(s) to standard output..",
+    true,
+    NULL,
+    cli_cmd_cat
+  });
+
+  embeddedCliAddBinding(_cli, (CliCommandBinding) {
+    "cd",
+    "Usage: cd [DIR]...\r\n\tChange the current directory to DIR.",
+    true,
+    NULL,
+    cli_cmd_cd
+  });
+
+  embeddedCliAddBinding(_cli, (CliCommandBinding) {
+    "cp",
+    "Usage: cp SOURCE DEST\r\n\tCopy SOURCE to DEST.",
+    true,
+    NULL,
+    cli_cmd_cp
+  });
+
+  embeddedCliAddBinding(_cli, (CliCommandBinding) {
+    "ls",
+    "Usage: ls [DIR]...\r\n\tList information about the FILEs (the current directory by default).",
+    true,
+    NULL,
+    cli_cmd_ls
+  });
+
+  embeddedCliAddBinding(_cli, (CliCommandBinding) {
+    "pwd",
+    "Usage: pwd\r\n\tPrint the name of the current working directory.",
+    true,
+    NULL,
+    cli_cmd_pwd
+  });
+
+  embeddedCliAddBinding(_cli, (CliCommandBinding) {
+    "mkdir",
+    "Usage: mkdir DIR...\r\n\tCreate the DIRECTORY(ies), if they do not already exist..",
+    true,
+    NULL,
+    cli_cmd_mkdir
+  });
+
+  embeddedCliAddBinding(_cli, (CliCommandBinding) {
+    "mv",
+    "Usage: mv SOURCE DEST...\r\n\tRename SOURCE to DEST.",
+    true,
+    NULL,
+    cli_cmd_mv
+  });
+
+  embeddedCliAddBinding(_cli, (CliCommandBinding) {
+    "rm",
+    "Usage: rm [FILE]...\r\n\tRemove (unlink) the FILE(s).",
+    true,
+    NULL,
+    cli_cmd_rm
+  });
+
+  return true;
+}
+
+void cli_cmd_cat(EmbeddedCli *cli, char *args, void *context)
+{
+  (void) cli; (void) context;
+
+  uint16_t argc = embeddedCliGetTokenCount(args);
+
+  // need at least 1 argument
+  if ( argc == 0 )
+  {
+    printf("invalid arguments\r\n");
+    return;
+  }
+
+  for(uint16_t i=0; i<argc; i++)
+  {
+    FIL fi;
+    const char* fpath = embeddedCliGetToken(args, i+1); // token count from 1
+
+    if ( FR_OK != f_open(&fi, fpath, FA_READ) )
+    {
+      printf("%s: No such file or directory\r\n", fpath);
+    }else
+    {
+      uint8_t buf[512];
+      UINT count = 0;
+      while ( (FR_OK == f_read(&fi, buf, sizeof(buf), &count)) && (count > 0) )
+      {
+        for(UINT c = 0; c < count; c++)
+        {
+          const char ch = buf[c];
+          if (isprint(ch) || iscntrl(ch))
+          {
+            putchar(ch);
+          }else
+          {
+            putchar('.');
+          }
+        }
+      }
+    }
+
+    f_close(&fi);
+  }
+}
+
+void cli_cmd_cd(EmbeddedCli *cli, char *args, void *context)
+{
+  (void) cli; (void) context;
+
+  uint16_t argc = embeddedCliGetTokenCount(args);
+
+  // only support 1 argument
+  if ( argc != 1 )
+  {
+    printf("invalid arguments\r\n");
+    return;
+  }
+
+  // default is current directory
+  const char* dpath = args;
+
+  if ( FR_OK != f_chdir(dpath) )
+  {
+    printf("%s: No such file or directory\r\n", dpath);
+    return;
+  }
+}
+
+void cli_cmd_cp(EmbeddedCli *cli, char *args, void *context)
+{
+  (void) cli; (void) context;
+
+  uint16_t argc = embeddedCliGetTokenCount(args);
+  if ( argc != 2 )
+  {
+    printf("invalid arguments\r\n");
+    return;
+  }
+
+  // default is current directory
+  const char* src = embeddedCliGetToken(args, 1);
+  const char* dst = embeddedCliGetToken(args, 2);
+
+  FIL f_src;
+  FIL f_dst;
+
+  if ( FR_OK != f_open(&f_src, src, FA_READ) )
+  {
+    printf("cannot stat '%s': No such file or directory\r\n", src);
+    return;
+  }
+
+  if ( FR_OK != f_open(&f_dst, dst, FA_WRITE | FA_CREATE_ALWAYS) )
+  {
+    printf("cannot create '%s'\r\n", dst);
+    return;
+  }else
+  {
+    uint8_t buf[512];
+    UINT rd_count = 0;
+    while ( (FR_OK == f_read(&f_src, buf, sizeof(buf), &rd_count)) && (rd_count > 0) )
+    {
+      UINT wr_count = 0;
+
+      if ( FR_OK != f_write(&f_dst, buf, rd_count, &wr_count) )
+      {
+        printf("cannot write to '%s'\r\n", dst);
+        break;
+      }
+    }
+  }
+
+  f_close(&f_src);
+  f_close(&f_dst);
+}
+
+void cli_cmd_ls(EmbeddedCli *cli, char *args, void *context)
+{
+  (void) cli; (void) context;
+
+  uint16_t argc = embeddedCliGetTokenCount(args);
+
+  // only support 1 argument
+  if ( argc > 1 )
+  {
+    printf("invalid arguments\r\n");
+    return;
+  }
+
+  // default is current directory
+  const char* dpath = ".";
+  if (argc) dpath = args;
+
+  DIR dir;
+  if ( FR_OK != f_opendir(&dir, dpath) )
+  {
+    printf("cannot access '%s': No such file or directory\r\n", dpath);
+    return;
+  }
+
+  FILINFO fno;
+  while( (f_readdir(&dir, &fno) == FR_OK) && (fno.fname[0] != 0) )
+  {
+    if ( fno.fname[0] != '.' ) // ignore . and .. entry
+    {
+      if ( fno.fattrib & AM_DIR )
+      {
+        // directory
+        printf("/%s\r\n", fno.fname);
+      }else
+      {
+        printf("%-40s", fno.fname);
+        if (fno.fsize < 1024)
+        {
+          printf("%lu B\r\n", fno.fsize);
+        }else
+        {
+          printf("%lu KB\r\n", fno.fsize / 1024);
+        }
+      }
+    }
+  }
+
+  f_closedir(&dir);
+}
+
+void cli_cmd_pwd(EmbeddedCli *cli, char *args, void *context)
+{
+  (void) cli; (void) context;
+  uint16_t argc = embeddedCliGetTokenCount(args);
+
+  if (argc != 0)
+  {
+    printf("invalid arguments\r\n");
+    return;
+  }
+
+  char path[256];
+  if (FR_OK != f_getcwd(path, sizeof(path)))
+  {
+    printf("cannot get current working directory\r\n");
+  }
+
+  puts(path);
+}
+
+void cli_cmd_mkdir(EmbeddedCli *cli, char *args, void *context)
+{
+  (void) cli; (void) context;
+
+  uint16_t argc = embeddedCliGetTokenCount(args);
+
+  // only support 1 argument
+  if ( argc != 1 )
+  {
+    printf("invalid arguments\r\n");
+    return;
+  }
+
+  // default is current directory
+  const char* dpath = args;
+
+  if ( FR_OK != f_mkdir(dpath) )
+  {
+    printf("%s: cannot create this directory\r\n", dpath);
+    return;
+  }
+}
+
+void cli_cmd_mv(EmbeddedCli *cli, char *args, void *context)
+{
+  (void) cli; (void) context;
+
+  uint16_t argc = embeddedCliGetTokenCount(args);
+  if ( argc != 2 )
+  {
+    printf("invalid arguments\r\n");
+    return;
+  }
+
+  // default is current directory
+  const char* src = embeddedCliGetToken(args, 1);
+  const char* dst = embeddedCliGetToken(args, 2);
+
+  if ( FR_OK != f_rename(src, dst) )
+  {
+    printf("cannot mv %s to %s\r\n", src, dst);
+    return;
+  }
+}
+
+void cli_cmd_rm(EmbeddedCli *cli, char *args, void *context)
+{
+  (void) cli; (void) context;
+
+  uint16_t argc = embeddedCliGetTokenCount(args);
+
+  // need at least 1 argument
+  if ( argc == 0 )
+  {
+    printf("invalid arguments\r\n");
+    return;
+  }
+
+  for(uint16_t i=0; i<argc; i++)
+  {
+    const char* fpath = embeddedCliGetToken(args, i+1); // token count from 1
+
+    if ( FR_OK != f_unlink(fpath) )
+    {
+      printf("cannot remove '%s': No such file or directory\r\n", fpath);
+    }
+  }
+}

+ 114 - 0
examples/host/msc_file_explorer/src/tusb_config.h

@@ -0,0 +1,114 @@
+/* 
+ * 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
+//--------------------------------------------------------------------+
+
+#if CFG_TUSB_MCU == OPT_MCU_RP2040
+// change to 1 if using pico-pio-usb as host controller for raspberry rp2040
+#define CFG_TUH_RPI_PIO_USB   0
+#define BOARD_TUH_RHPORT      CFG_TUH_RPI_PIO_USB
+#endif
+
+// RHPort number used for host can be defined by board.mk, default to port 0
+#ifndef BOARD_TUH_RHPORT
+#define BOARD_TUH_RHPORT      0
+#endif
+
+// RHPort max operational speed can defined by board.mk
+#ifndef BOARD_TUH_MAX_SPEED
+#define BOARD_TUH_MAX_SPEED   OPT_MODE_DEFAULT_SPEED
+#endif
+
+//--------------------------------------------------------------------
+// COMMON CONFIGURATION
+//--------------------------------------------------------------------
+
+// defined by compiler flags for flexibility
+#ifndef CFG_TUSB_MCU
+#error CFG_TUSB_MCU must be defined
+#endif
+
+#ifndef CFG_TUSB_OS
+#define CFG_TUSB_OS           OPT_OS_NONE
+#endif
+
+#ifndef CFG_TUSB_DEBUG
+#define CFG_TUSB_DEBUG        0
+#endif
+
+// Enable Host stack
+#define CFG_TUH_ENABLED       1
+
+// Default is max speed that hardware controller could support with on-chip PHY
+#define CFG_TUH_MAX_SPEED     BOARD_TUH_MAX_SPEED
+
+/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
+ * Tinyusb use follows macros to declare transferring memory so that they can be put
+ * into those specific section.
+ * 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
+
+//--------------------------------------------------------------------
+// CONFIGURATION
+//--------------------------------------------------------------------
+
+// Size of buffer to hold descriptors and other data used for enumeration
+#define CFG_TUH_ENUMERATION_BUFSIZE 256
+
+#define CFG_TUH_HUB                 1 // number of supported hubs
+#define CFG_TUH_MSC                 1
+#define CFG_TUH_CDC                 0
+#define CFG_TUH_HID                 0 // typical keyboard + mouse device can have 3-4 HID interfaces
+#define CFG_TUH_VENDOR              0
+
+// max device support (excluding hub device)
+#define CFG_TUH_DEVICE_MAX          (CFG_TUH_HUB ? 4 : 1) // hub typically has 4 ports
+
+//------------- MSC -------------//
+#define CFG_TUH_MSC_MAXLUN    4 // typical for most card reader
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_CONFIG_H_ */

+ 2 - 1
examples/make.mk

@@ -113,7 +113,8 @@ CFLAGS += \
   
 # Debugging/Optimization
 ifeq ($(DEBUG), 1)
-  CFLAGS += -Og
+  CFLAGS += -O0
+  NO_LTO = 1
 else
   CFLAGS += $(CFLAGS_OPTIMIZED)
 endif

+ 1 - 1
hw/bsp/ansi_escape.h

@@ -25,7 +25,7 @@
  */
 
 /** \ingroup group_board
- *  \defgroup group_ansi_esc ANSI Esacpe Code
+ *  \defgroup group_ansi_esc ANSI Escape Code
  *  @{ */
 
 #ifndef _TUSB_ANSI_ESC_CODE_H_

+ 11 - 2
hw/bsp/board.c

@@ -103,8 +103,10 @@ TU_ATTR_USED int sys_write (int fhdl, const void *buf, size_t count)
 TU_ATTR_USED int sys_read (int fhdl, char *buf, size_t count)
 {
   (void) fhdl;
-  return SEGGER_RTT_Read(0, buf, count);
+  int rd = (int) SEGGER_RTT_Read(0, buf, count);
+  return (rd > 0) ? rd : -1;
 }
+
 #endif
 
 #elif defined(LOGGER_SWO)
@@ -143,7 +145,14 @@ TU_ATTR_USED int sys_write (int fhdl, const void *buf, size_t count)
 TU_ATTR_USED int sys_read (int fhdl, char *buf, size_t count)
 {
   (void) fhdl;
-  return board_uart_read((uint8_t*) buf, (int) count);
+  int rd = board_uart_read((uint8_t*) buf, (int) count);
+  return (rd > 0) ? rd : -1;
 }
 
 #endif
+
+int board_getchar(void)
+{
+  char c;
+  return ( sys_read(0, &c, 1) > 0 ) ? (int) c : (-1);
+}

+ 4 - 10
hw/bsp/board.h

@@ -66,9 +66,11 @@ void board_led_write(bool state);
 uint32_t board_button_read(void);
 
 // Get characters from UART
+// Return number of read bytes
 int board_uart_read(uint8_t* buf, int len);
 
 // Send characters to UART
+// Return number of sent bytes
 int board_uart_write(void const * buf, int len);
 
 #if CFG_TUSB_OS == OPT_OS_NONE
@@ -130,16 +132,8 @@ static inline void board_delay(uint32_t ms)
   }
 }
 
-static inline int board_uart_getchar(void)
-{
-  uint8_t c;
-  return board_uart_read(&c, 1) ? (int) c : (-1);
-}
-
-static inline int board_uart_putchar(uint8_t c)
-{
-  return board_uart_write(&c, 1);
-}
+// stdio getchar() is blocking, this is non-blocking version
+int board_getchar(void);
 
 #ifdef __cplusplus
  }

+ 3 - 0
hw/bsp/board_mcu.h

@@ -98,6 +98,9 @@
 #elif CFG_TUSB_MCU == OPT_MCU_STM32WB
   #include "stm32wbxx.h"
 
+#elif CFG_TUSB_MCU == OPT_MCU_STM32U5
+  #include "stm32u5xx.h"
+
 #elif CFG_TUSB_MCU == OPT_MCU_CXD56
   // no header needed
 

+ 1 - 3
hw/bsp/ea4357/ea4357.c

@@ -272,9 +272,7 @@ uint32_t board_button_read(void)
 
 int board_uart_read(uint8_t* buf, int len)
 {
-  //return UART_ReceiveByte(BOARD_UART_DEV);
-  (void) buf; (void) len;
-  return 0;
+  return Chip_UART_Read(UART_DEV, buf, len);
 }
 
 int board_uart_write(void const * buf, int len)

+ 1 - 1
hw/bsp/esp32s2/components/led_strip/src/led_strip_rmt_ws2812.c

@@ -50,7 +50,7 @@ typedef struct {
 } ws2812_t;
 
 /**
- * @brief Conver RGB data to RMT format.
+ * @brief Convert RGB data to RMT format.
  *
  * @note For WS2812, R,G,B each contains 256 different choices (i.e. uint8_t)
  *

+ 1 - 1
hw/bsp/esp32s3/components/led_strip/src/led_strip_rmt_ws2812.c

@@ -50,7 +50,7 @@ typedef struct {
 } ws2812_t;
 
 /**
- * @brief Conver RGB data to RMT format.
+ * @brief Convert RGB data to RMT format.
  *
  * @note For WS2812, R,G,B each contains 256 different choices (i.e. uint8_t)
  *

+ 44 - 2
hw/bsp/family_support.cmake

@@ -79,14 +79,56 @@ if (NOT TARGET _family_support_marker)
         endif()
     endfunction()
 
+    function(family_add_default_example_warnings TARGET)
+        target_compile_options(${TARGET} PUBLIC
+                -Wall
+                -Wextra
+                -Werror
+                -Wfatal-errors
+                -Wdouble-promotion
+                -Wfloat-equal
+                -Wshadow
+                -Wwrite-strings
+                -Wsign-compare
+                -Wmissing-format-attribute
+                -Wunreachable-code
+                -Wcast-align
+                -Wcast-qual
+                -Wnull-dereference
+                -Wuninitialized
+                -Wunused
+                -Wredundant-decls
+                #-Wstrict-prototypes
+                #-Werror-implicit-function-declaration
+                #-Wundef
+                )
+
+        if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
+            # GCC 10
+            if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10.0)
+                target_compile_options(${TARGET} PUBLIC -Wconversion)
+            endif()
+
+            # GCC 8
+            if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 8.0)
+                target_compile_options(${TARGET} PUBLIC -Wcast-function-type -Wstrict-overflow)
+            endif()
+
+            # GCC 6
+            if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 6.0)
+                target_compile_options(${TARGET} PUBLIC -Wno-strict-aliasing)
+            endif()
+        endif()
+    endfunction()
+
     # configure an executable target to link to tinyusb in device mode, and add the board implementation
     function(family_configure_device_example TARGET)
-        # default implentation is empty, the function should be redefined in the FAMILY/family.cmake
+        # default implementation is empty, the function should be redefined in the FAMILY/family.cmake
     endfunction()
 
     # configure an executable target to link to tinyusb in host mode, and add the board implementation
     function(family_configure_host_example TARGET)
-        # default implentation is empty, the function should be redefined in the FAMILY/family.cmake
+        # default implementation is empty, the function should be redefined in the FAMILY/family.cmake
     endfunction()
 
     include(${CMAKE_CURRENT_LIST_DIR}/${FAMILY}/family.cmake)

+ 2 - 2
hw/bsp/gd32vf103/family.c

@@ -112,7 +112,7 @@ void board_init(void) {
   otg_core_regs->GCCFG &= ~GCCFG_VBUSIG;
 #endif
 
-  /* Enable interrupts globaly */
+  /* Enable interrupts globally */
   __enable_irq();
 }
 
@@ -120,7 +120,7 @@ void gd32vf103_reset(void) {
   /* The MTIMER unit of the GD32VF103 doesn't have the MSFRST
    * register to generate a software reset request.
    * BUT instead two undocumented registers in the debug peripheral
-   * that allow issueing a software reset.
+   * that allow issuing a software reset.
    * https://github.com/esmil/gd32vf103inator/blob/master/include/gd32vf103/dbg.h
    */
   DBG_KEY = DBG_KEY_UNLOCK;

+ 1 - 1
hw/bsp/gd32vf103/system_gd32vf103.c

@@ -574,7 +574,7 @@ void ECLIC_Init(void)
  * \param [in]  IRQn        NMI interrupt handler address
  * \param [in]  shv         \ref ECLIC_NON_VECTOR_INTERRUPT means non-vector mode, and \ref ECLIC_VECTOR_INTERRUPT is vector mode
  * \param [in]  trig_mode   see \ref ECLIC_TRIGGER_Type
- * \param [in]  lvl         interupt level
+ * \param [in]  lvl         interrupt level
  * \param [in]  priority    interrupt priority
  * \param [in]  handler     interrupt handler, if NULL, handler will not be installed
  * \return       -1 means invalid input parameter. 0 means successful.

+ 5 - 5
hw/bsp/imxrt/boards/mimxrt1010_evk/evkmimxrt1010_flexspi_nor_config.h

@@ -18,7 +18,7 @@
 #define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
 /*@}*/
 
-/* FLEXSPI memory config block related defintions */
+/* FLEXSPI memory config block related definitions */
 #define FLEXSPI_CFG_BLK_TAG (0x42464346UL)     // ascii "FCFB" Big Endian
 #define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0
 #define FLEXSPI_CFG_BLK_SIZE (512)
@@ -26,7 +26,7 @@
 /* FLEXSPI Feature related definitions */
 #define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1
 
-/* Lookup table related defintions */
+/* Lookup table related definitions */
 #define CMD_INDEX_READ 0
 #define CMD_INDEX_READSTATUS 1
 #define CMD_INDEX_WRITEENABLE 2
@@ -123,7 +123,7 @@ enum
     kFlexSpiDeviceType_SerialNAND   = 2,    //!< Flash devices are Serial NAND
     kFlexSpiDeviceType_SerialRAM    = 3,    //!< Flash devices are Serial RAM/HyperFLASH
     kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND
-    kFlexSpiDeviceType_MCP_NOR_RAM  = 0x13, //!< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs
+    kFlexSpiDeviceType_MCP_NOR_RAM  = 0x13, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial RAMs
 };
 
 //!@brief Flash Pad Definitions
@@ -184,7 +184,7 @@ typedef struct _FlexSPIConfig
     //! details
     uint8_t deviceType;    //!< [0x044-0x044] Device Type:  See Flash Type Definition for more details
     uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal
-    uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot
+    uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequency, device specific definitions, See System Boot
     //! Chapter for more details
     uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot
     //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH
@@ -252,7 +252,7 @@ typedef struct _flexspi_nor_config
     uint8_t serialNorType;          //!< Serial NOR Flash type: 0/1/2/3
     uint8_t needExitNoCmdMode;      //!< Need to exit NoCmd mode before other IP command
     uint8_t halfClkForNonReadCmd;   //!< Half the Serial Clock for non-read command: true/false
-    uint8_t needRestoreNoCmdMode;   //!< Need to Restore NoCmd mode after IP commmand execution
+    uint8_t needRestoreNoCmdMode;   //!< Need to Restore NoCmd mode after IP command execution
     uint32_t blockSize;             //!< Block size
     uint32_t reserve2[11];          //!< Reserved for future use
 } flexspi_nor_config_t;

+ 5 - 5
hw/bsp/imxrt/boards/mimxrt1015_evk/evkmimxrt1015_flexspi_nor_config.h

@@ -18,7 +18,7 @@
 #define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
 /*@}*/
 
-/* FLEXSPI memory config block related defintions */
+/* FLEXSPI memory config block related definitions */
 #define FLEXSPI_CFG_BLK_TAG (0x42464346UL)     // ascii "FCFB" Big Endian
 #define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0
 #define FLEXSPI_CFG_BLK_SIZE (512)
@@ -26,7 +26,7 @@
 /* FLEXSPI Feature related definitions */
 #define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1
 
-/* Lookup table related defintions */
+/* Lookup table related definitions */
 #define CMD_INDEX_READ 0
 #define CMD_INDEX_READSTATUS 1
 #define CMD_INDEX_WRITEENABLE 2
@@ -124,7 +124,7 @@ enum
     kFlexSpiDeviceType_SerialNAND   = 2,    //!< Flash devices are Serial NAND
     kFlexSpiDeviceType_SerialRAM    = 3,    //!< Flash devices are Serial RAM/HyperFLASH
     kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND
-    kFlexSpiDeviceType_MCP_NOR_RAM  = 0x13, //!< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs
+    kFlexSpiDeviceType_MCP_NOR_RAM  = 0x13, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial RAMs
 };
 
 //!@brief Flash Pad Definitions
@@ -185,7 +185,7 @@ typedef struct _FlexSPIConfig
     //! details
     uint8_t deviceType;    //!< [0x044-0x044] Device Type:  See Flash Type Definition for more details
     uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal
-    uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot
+    uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequency, device specific definitions, See System Boot
     //! Chapter for more details
     uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot
     //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH
@@ -253,7 +253,7 @@ typedef struct _flexspi_nor_config
     uint8_t serialNorType;          //!< Serial NOR Flash type: 0/1/2/3
     uint8_t needExitNoCmdMode;      //!< Need to exit NoCmd mode before other IP command
     uint8_t halfClkForNonReadCmd;   //!< Half the Serial Clock for non-read command: true/false
-    uint8_t needRestoreNoCmdMode;   //!< Need to Restore NoCmd mode after IP commmand execution
+    uint8_t needRestoreNoCmdMode;   //!< Need to Restore NoCmd mode after IP command execution
     uint32_t blockSize;             //!< Block size
     uint32_t reserve2[11];          //!< Reserved for future use
 } flexspi_nor_config_t;

+ 5 - 5
hw/bsp/imxrt/boards/mimxrt1020_evk/evkmimxrt1020_flexspi_nor_config.h

@@ -18,7 +18,7 @@
 #define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
 /*@}*/
 
-/* FLEXSPI memory config block related defintions */
+/* FLEXSPI memory config block related definitions */
 #define FLEXSPI_CFG_BLK_TAG (0x42464346UL)     // ascii "FCFB" Big Endian
 #define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0
 #define FLEXSPI_CFG_BLK_SIZE (512)
@@ -26,7 +26,7 @@
 /* FLEXSPI Feature related definitions */
 #define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1
 
-/* Lookup table related defintions */
+/* Lookup table related definitions */
 #define CMD_INDEX_READ 0
 #define CMD_INDEX_READSTATUS 1
 #define CMD_INDEX_WRITEENABLE 2
@@ -124,7 +124,7 @@ enum
     kFlexSpiDeviceType_SerialNAND   = 2,    //!< Flash devices are Serial NAND
     kFlexSpiDeviceType_SerialRAM    = 3,    //!< Flash devices are Serial RAM/HyperFLASH
     kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND
-    kFlexSpiDeviceType_MCP_NOR_RAM  = 0x13, //!< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs
+    kFlexSpiDeviceType_MCP_NOR_RAM  = 0x13, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial RAMs
 };
 
 //!@brief Flash Pad Definitions
@@ -185,7 +185,7 @@ typedef struct _FlexSPIConfig
     //! details
     uint8_t deviceType;    //!< [0x044-0x044] Device Type:  See Flash Type Definition for more details
     uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal
-    uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot
+    uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequency, device specific definitions, See System Boot
     //! Chapter for more details
     uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot
     //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH
@@ -253,7 +253,7 @@ typedef struct _flexspi_nor_config
     uint8_t serialNorType;          //!< Serial NOR Flash type: 0/1/2/3
     uint8_t needExitNoCmdMode;      //!< Need to exit NoCmd mode before other IP command
     uint8_t halfClkForNonReadCmd;   //!< Half the Serial Clock for non-read command: true/false
-    uint8_t needRestoreNoCmdMode;   //!< Need to Restore NoCmd mode after IP commmand execution
+    uint8_t needRestoreNoCmdMode;   //!< Need to Restore NoCmd mode after IP command execution
     uint32_t blockSize;             //!< Block size
     uint32_t reserve2[11];          //!< Reserved for future use
 } flexspi_nor_config_t;

+ 5 - 5
hw/bsp/imxrt/boards/mimxrt1050_evkb/evkbimxrt1050_flexspi_nor_config.h

@@ -19,7 +19,7 @@
 #define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
 /*@}*/
 
-/* FLEXSPI memory config block related defintions */
+/* FLEXSPI memory config block related definitions */
 #define FLEXSPI_CFG_BLK_TAG (0x42464346UL)     // ascii "FCFB" Big Endian
 #define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0
 #define FLEXSPI_CFG_BLK_SIZE (512)
@@ -27,7 +27,7 @@
 /* FLEXSPI Feature related definitions */
 #define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1
 
-/* Lookup table related defintions */
+/* Lookup table related definitions */
 #define CMD_INDEX_READ 0
 #define CMD_INDEX_READSTATUS 1
 #define CMD_INDEX_WRITEENABLE 2
@@ -125,7 +125,7 @@ enum
     kFlexSpiDeviceType_SerialNAND   = 2,    //!< Flash devices are Serial NAND
     kFlexSpiDeviceType_SerialRAM    = 3,    //!< Flash devices are Serial RAM/HyperFLASH
     kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND
-    kFlexSpiDeviceType_MCP_NOR_RAM  = 0x13, //!< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs
+    kFlexSpiDeviceType_MCP_NOR_RAM  = 0x13, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial RAMs
 };
 
 //!@brief Flash Pad Definitions
@@ -186,7 +186,7 @@ typedef struct _FlexSPIConfig
     //! details
     uint8_t deviceType;    //!< [0x044-0x044] Device Type:  See Flash Type Definition for more details
     uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal
-    uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot
+    uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequency, device specific definitions, See System Boot
     //! Chapter for more details
     uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot
     //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH
@@ -254,7 +254,7 @@ typedef struct _flexspi_nor_config
     uint8_t serialNorType;          //!< Serial NOR Flash type: 0/1/2/3
     uint8_t needExitNoCmdMode;      //!< Need to exit NoCmd mode before other IP command
     uint8_t halfClkForNonReadCmd;   //!< Half the Serial Clock for non-read command: true/false
-    uint8_t needRestoreNoCmdMode;   //!< Need to Restore NoCmd mode after IP commmand execution
+    uint8_t needRestoreNoCmdMode;   //!< Need to Restore NoCmd mode after IP command execution
     uint32_t blockSize;             //!< Block size
     uint32_t reserve2[11];          //!< Reserved for future use
 } flexspi_nor_config_t;

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików