diff --git a/.clang-tidy b/.clang-tidy index bff0592d9d..d33851630e 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,28 +1,48 @@ --- -Checks: 'clang-diagnostic-*,clang-analyzer-*,-clang-analyzer-alpha*' -HeaderFilterRegex: '' -AnalyzeTemporaryDtors: false -User: slavey +Checks: + -* + bugprone-* + -bugprone-macro-parentheses + -bugprone-reserved-identifier + -bugprone-easily-swappable-parameters + clang-analyzer-* + performance-* + portability-* + cppcoreguidelines-* + -cppcoreguidelines-avoid-c-arrays + -cppcoreguidelines-avoid-do-while + -cppcoreguidelines-pro-bounds-array-to-pointer-decay + -cppcoreguidelines-macro-usage + -cppcoreguidelines-pro-type-reinterpret-cast + -cppcoreguidelines-pro-type-static-cast-downcast + -cppcoreguidelines-pro-type-vararg + -cppcoreguidelines-pro-bounds-pointer-arithmetic + -cppcoreguidelines-pro-bounds-constant-array-index + -cppcoreguidelines-pro-type-union-access + -cppcoreguidelines-avoid-const-or-ref-data-members + -cppcoreguidelines-non-private-member-variables-in-classes +HeaderFilterRegex: '.*' CheckOptions: - - key: google-readability-braces-around-statements.ShortStatementLines - value: '1' - - key: google-readability-function-size.StatementThreshold - value: '800' - - key: google-readability-namespace-comments.ShortNamespaceLines - value: '10' - - key: google-readability-namespace-comments.SpacesBeforeComments - value: '2' - - key: modernize-loop-convert.MaxCopySize - value: '16' - - key: modernize-loop-convert.MinConfidence - value: reasonable - - key: modernize-loop-convert.NamingStyle - value: CamelCase - - key: modernize-pass-by-value.IncludeStyle - value: llvm - - key: modernize-replace-auto-ptr.IncludeStyle - value: llvm - - key: modernize-use-nullptr.NullMacros - value: 'NULL' + - key: google-readability-braces-around-statements.ShortStatementLines + value: '1' + - key: google-readability-function-size.StatementThreshold + value: '800' + - key: google-readability-namespace-comments.ShortNamespaceLines + value: '10' + - key: google-readability-namespace-comments.SpacesBeforeComments + value: '2' + - key: modernize-loop-convert.MaxCopySize + value: '16' + - key: modernize-loop-convert.MinConfidence + value: reasonable + - key: modernize-loop-convert.NamingStyle + value: CamelCase + - key: modernize-pass-by-value.IncludeStyle + value: llvm + - key: modernize-replace-auto-ptr.IncludeStyle + value: llvm + - key: cppcoreguidelines-pro-type-static-cast-downcast.StrictMode + value: false + - key: cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors + value: true ... - diff --git a/.github/workflows/cache-clean.yml b/.github/workflows/cache-clean.yml new file mode 100644 index 0000000000..3ccbea4891 --- /dev/null +++ b/.github/workflows/cache-clean.yml @@ -0,0 +1,55 @@ +name: Cache clean + +on: + workflow_dispatch: + inputs: + clean_opt: + description: 'Level of cleaning required' + type: choice + default: push-requests + options: + - pull-requests + - ccache + - idf-tools + - ccache+idf + +jobs: + cleanup: + runs-on: ubuntu-latest + steps: + - name: Cleanup + run: | + gh extension install actions/gh-actions-cache + + echo "Fetching list of cache keys" + case $CLEAN_OPT in + pull-requests) + filter="-v develop" + ;; + ccache) + filter="ccache" + ;; + idf-tools) + filter="idf" + ;; + ccache+idf) + filter="ccache\|idf" + ;; + *) + echo "Unknown option '$CLEAN_OPT'" + exit 1 + ;; + esac + + cacheKeys=$(gh actions-cache list -R $REPO -L 100 | grep $filter | cut -f 1 ) + + echo "Deleting caches..." + set +e + for cacheKey in $cacheKeys; do + gh actions-cache delete "$cacheKey" -R "$REPO" --confirm + done + echo "Done" + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REPO: ${{ github.repository }} + CLEAN_OPT: ${{ inputs.clean_opt }} diff --git a/.github/workflows/ci-esp32.yml b/.github/workflows/ci-esp32.yml index 4036e42932..21e3d98dab 100644 --- a/.github/workflows/ci-esp32.yml +++ b/.github/workflows/ci-esp32.yml @@ -2,7 +2,9 @@ name: Continuous Integration (CI) for Esp32 on: push: - + + workflow_dispatch: + pull_request: branches: [ develop ] @@ -11,27 +13,39 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-20.04, windows-latest] + os: [ubuntu-latest, macos-latest, windows-latest] variant: [esp32, esp32s2, esp32c3, esp32s3, esp32c2] - idf_version: ["4.3", "4.4", "5.0"] - exclude: - - variant: esp32s3 - idf_version: "4.3" - - variant: esp32c2 + idf_version: ["4.4", "5.0", "5.2"] + include: + - os: ubuntu-latest + variant: esp32 idf_version: "4.3" + exclude: - variant: esp32c2 idf_version: "4.4" + - os: macos-latest + idf_version: "4.4" + - os: macos-latest + idf_version: "5.0" + - os: windows-latest + idf_version: "5.0" - concurrency: + concurrency: group: ${{ github.workflow }}-${{ github.ref }}-${{ toJson(matrix) }} cancel-in-progress: true runs-on: ${{ matrix.os }} env: + CI_BUILD_DIR: ${{ github.workspace }} + SMING_HOME: ${{ github.workspace }}/Sming SMING_ARCH: Esp32 SMING_SOC: ${{ matrix.variant }} INSTALL_IDF_VER: ${{ matrix.idf_version }} + IDF_SKIP_CHECK_SUBMODULES: 1 + ENABLE_CCACHE: 1 + CCACHE_DIR: ${{ github.workspace }}/.ccache + CCACHE_MAXSIZE: 500M steps: - name: Fix autocrlf setting @@ -39,33 +53,75 @@ jobs: git config --global --add core.autocrlf input - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 + + - name: Setup python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.idf_version == '4.3' && '3.8' || '3.12' }} - - name: Configure environment - shell: pwsh + - name: Fix permissions + if: matrix.os != 'windows-latest' run: | - "CI_BUILD_DIR=" + (Resolve-Path ".").path >> $env:GITHUB_ENV - "SMING_HOME=" + (Resolve-Path "Sming").path >> $env:GITHUB_ENV + sudo chown $USER /opt - - name: Install build tools for Ubuntu - if: ${{ matrix.os == 'ubuntu-20.04' }} + - name: Cache ESP-IDF and build tools + uses: actions/cache@v4 + with: + path: | + /opt/esp-idf-${{ matrix.idf_version }} + /opt/esp32 + key: ${{ matrix.os }}-idf-${{ matrix.idf_version }} + + - name: Install build tools for Ubuntu / MacOS + if: matrix.os != 'windows-latest' run: | Tools/ci/install.sh - - name: Install build tools for Windows - if: ${{ matrix.os == 'windows-latest' }} + - name: Install build tools for Windows + if: matrix.os == 'windows-latest' run: | - . Tools/ci/setenv.ps1 - Tools/ci/install.cmd + . Tools/ci/setenv.ps1 + Tools/ci/install.cmd - - name: Build and test for ${{matrix.variant}} with IDF v${{matrix.idf_version}} on Ubuntu - if: ${{ matrix.os == 'ubuntu-20.04' }} + - name: Restore Compiler Cache + id: ccache + uses: actions/cache/restore@v4 + with: + path: ${{ env.CCACHE_DIR }} + key: ${{ matrix.os }}-ccache-${{ matrix.variant }}-${{ matrix.idf_version }} + + - name: Build and test for ${{matrix.variant}} with IDF v${{matrix.idf_version}} on Ubuntu / MacOS + if: matrix.os != 'windows-latest' run: | - source $SMING_HOME/../Tools/export.sh + ccache -z + . Tools/export.sh Tools/ci/build.sh - name: Build and test for ${{matrix.variant}} with IDF v${{matrix.idf_version}} on Windows - if: ${{ matrix.os == 'windows-latest' }} + if: matrix.os == 'windows-latest' run: | + ccache -z . Tools/ci/setenv.ps1 Tools/ci/build.cmd + + - name: Compiler Cache stats + run: | + ccache --evict-older-than 14400s + ccache -sv + + - name: Delete Previous Compiler Cache + if: github.ref_name == github.event.repository.default_branch && steps.ccache.outputs.cache-hit + continue-on-error: true + run: | + gh extension install actions/gh-actions-cache + gh actions-cache delete "${{ steps.ccache.outputs.cache-primary-key }}" --branch ${{ github.ref_name }} --confirm + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Save Compiler Cache + if: github.ref_name == github.event.repository.default_branch || !steps.ccache.outputs.cache-hit + uses: actions/cache/save@v4 + with: + path: ${{ env.CCACHE_DIR }} + key: ${{ steps.ccache.outputs.cache-primary-key }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7173fb515d..8b33ec55ea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,7 +2,9 @@ name: Continuous Integration (CI) on: push: - + + workflow_dispatch: + pull_request: branches: [ develop ] @@ -11,25 +13,41 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-20.04, windows-latest] + os: [ubuntu-latest, macos-latest, windows-latest] variant: [esp8266, host, rp2040] + toolchain: [gcc] include: - variant: esp8266 arch: Esp8266 - variant: host arch: Host + - os: ubuntu-latest + variant: host + arch: Host + toolchain: clang + - os: ubuntu-latest + variant: host + arch: Host + toolchain: gcc64 - variant: rp2040 arch: Rp2040 - concurrency: + concurrency: group: ${{ github.workflow }}-${{ github.ref }}-${{ toJson(matrix) }} cancel-in-progress: true runs-on: ${{ matrix.os }} env: + CI_BUILD_DIR: ${{ github.workspace }} + SMING_HOME: ${{ github.workspace }}/Sming SMING_ARCH: ${{ matrix.arch }} SMING_SOC: ${{ matrix.variant }} + CLANG_BUILD: ${{ matrix.toolchain == 'clang' && '15' || '0' }} + BUILD64: ${{ matrix.toolchain == 'gcc64' && 1 || 0 }} + ENABLE_CCACHE: 1 + CCACHE_DIR: ${{ github.workspace }}/.ccache + CCACHE_MAXSIZE: 500M steps: - name: Fix autocrlf setting @@ -37,36 +55,64 @@ jobs: git config --global --add core.autocrlf input - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - - name: Configure environment - shell: pwsh - run: | - "CI_BUILD_DIR=" + (Resolve-Path ".").path >> $env:GITHUB_ENV - "SMING_HOME=" + (Resolve-Path "Sming").path >> $env:GITHUB_ENV + - name: Setup python + uses: actions/setup-python@v5 + with: + python-version: "3.12" - - name: Install build tools for Ubuntu - if: ${{ matrix.os == 'ubuntu-20.04' }} + - name: Install build tools for Ubuntu / MacOS + if: matrix.os != 'windows-latest' run: | Tools/ci/install.sh - - name: Install build tools for Windows - if: ${{ matrix.os == 'windows-latest' }} + - name: Install build tools for Windows + if: matrix.os == 'windows-latest' run: | - . Tools/ci/setenv.ps1 - Tools/ci/install.cmd + . Tools/ci/setenv.ps1 + Tools/ci/install.cmd - - name: Build and test for ${{matrix.variant}} on Ubuntu - env: + - name: Restore Compiler Cache + id: ccache + uses: actions/cache/restore@v4 + with: + path: ${{ env.CCACHE_DIR }} + key: ${{ matrix.os }}-ccache-${{ matrix.toolchain }}-${{ matrix.variant }} + + - name: Build and test for ${{matrix.variant}} on Ubuntu / MacOS + env: CLANG_FORMAT: clang-format-8 - if: ${{ matrix.os == 'ubuntu-20.04' }} + if: matrix.os != 'windows-latest' run: | - source $SMING_HOME/../Tools/export.sh - $CLANG_FORMAT --version + ccache -z + . Tools/export.sh Tools/ci/build.sh - name: Build and test for ${{matrix.variant}} on Windows - if: ${{ matrix.os == 'windows-latest' }} + if: matrix.os == 'windows-latest' run: | + ccache -z . Tools/ci/setenv.ps1 Tools/ci/build.cmd + + - name: Compiler Cache stats + run: | + ccache --evict-older-than 14400s + ccache -sv + + - name: Delete Previous Compiler Cache + if: github.ref_name == github.event.repository.default_branch && steps.ccache.outputs.cache-hit + continue-on-error: true + run: | + gh extension install actions/gh-actions-cache + gh actions-cache delete "${{ steps.ccache.outputs.cache-primary-key }}" --branch ${{ github.ref_name }} --confirm + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Save Compiler Cache + if: github.ref_name == github.event.repository.default_branch || !steps.ccache.outputs.cache-hit + uses: actions/cache/save@v4 + with: + path: ${{ env.CCACHE_DIR }} + key: ${{ steps.ccache.outputs.cache-primary-key }} diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index da50404adc..3b56ecb4f0 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -17,7 +17,7 @@ on: jobs: analyze: name: Analyze - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest strategy: fail-fast: false @@ -30,7 +30,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: # We must fetch at least the immediate parents so that if this is # a pull request then we can checkout the head. @@ -38,7 +38,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -67,4 +67,4 @@ jobs: make -j3 SMING_ARCH=Host - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/coverity-scan.yml b/.github/workflows/coverity-scan.yml index 10287b0e53..daa11e047b 100644 --- a/.github/workflows/coverity-scan.yml +++ b/.github/workflows/coverity-scan.yml @@ -18,11 +18,11 @@ jobs: # group: ${{ github.head_ref || github.run_id }} # cancel-in-progress: true - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Check if we are allowed to scan env: BRANCH: ${{github.ref_name}} @@ -44,19 +44,19 @@ jobs: echo "CHECK_SCA=$CHECK_SCA" >> $GITHUB_ENV - name: Setup SMING_HOME for Ubuntu - if: ${{ env.CHECK_SCA == 1 }} + if: env.CHECK_SCA == 1 run: | echo "CI_BUILD_DIR=$GITHUB_WORKSPACE" >> $GITHUB_ENV echo "SMING_HOME=$GITHUB_WORKSPACE/Sming" >> $GITHUB_ENV echo "SMING_ARCH=Host" >> $GITHUB_ENV - name: Install Sming Framework on Ubuntu - if: ${{ env.CHECK_SCA == 1 }} + if: env.CHECK_SCA == 1 run: | Tools/ci/install.sh - name: Run Coverity Scan - if: ${{ env.CHECK_SCA == 1 }} + if: env.CHECK_SCA == 1 env: COVERITY_SCAN_TOKEN: ${{secrets.COVERITY_SCAN_TOKEN}} run: | @@ -67,7 +67,7 @@ jobs: $SMING_HOME/Arch/Host/Tools/ci/coverity-scan.sh - name: Archive scan log - if: ${{ env.CHECK_SCA == 1 }} + if: env.CHECK_SCA == 1 uses: actions/upload-artifact@v3 with: name: coverity-scan-report diff --git a/.github/workflows/library.yml b/.github/workflows/library.yml index 531b04f0a6..7a02c305b6 100644 --- a/.github/workflows/library.yml +++ b/.github/workflows/library.yml @@ -1,4 +1,4 @@ -name: Continuous Integration (CI) +name: Continuous Integration (CI) for Library on: workflow_call: @@ -21,38 +21,79 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-20.04, windows-latest] - variant: [esp8266, host, esp32, esp32s2, esp32c3, rp2040] + os: [ubuntu-latest, macos-latest, windows-latest] + variant: [esp8266, host, esp32, esp32s2, esp32c3, esp32s3, esp32c2, rp2040] + idf_version: ["4.4", ""] # "" denotes default, currently 5.2 + toolchain: [gcc] include: - variant: esp8266 arch: Esp8266 - variant: host arch: Host + - os: ubuntu-latest + variant: host + arch: Host + toolchain: clang + - os: ubuntu-latest + variant: host + arch: Host + toolchain: gcc64 - variant: esp32 arch: Esp32 - variant: esp32s2 arch: Esp32 - variant: esp32c3 arch: Esp32 + - variant: esp32s3 + arch: Esp32 + - variant: esp32c2 + arch: Esp32 - variant: rp2040 arch: Rp2040 + exclude: + - variant: esp32c2 + idf_version: "4.4" + - variant: esp8266 + idf_version: "4.4" + - variant: host + idf_version: "4.4" + - variant: rp2040 + idf_version: "4.4" + - os: macos-latest + idf_version: "4.4" - concurrency: + concurrency: group: ${{ github.workflow }}-${{ github.ref }}-${{ toJson(matrix) }} cancel-in-progress: true runs-on: ${{ matrix.os }} + env: + CI_BUILD_DIR: ${{ github.workspace }} + SMING_ARCH: ${{ matrix.arch }} + SMING_SOC: ${{ matrix.variant }} + INSTALL_IDF_VER: ${{ matrix.idf_version || '5.2' }} + CLANG_BUILD: ${{ matrix.toolchain == 'clang' && '15' || '0' }} + BUILD64: ${{ matrix.toolchain == 'gcc64' && 1 || 0 }} + ENABLE_CCACHE: 1 + CCACHE_DIR: ${{ github.workspace }}/.ccache + CCACHE_MAXSIZE: 500M + steps: - name: Fix autocrlf setting run: | git config --global --add core.autocrlf input - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 + + - name: Setup python + uses: actions/setup-python@v5 + with: + python-version: "3.12" - name: Create library alias - if: ${{ inputs.alias }} + if: inputs.alias shell: pwsh run: | New-Item -ItemType SymbolicLink -Path "../${{ inputs.alias }}" -Target (Resolve-Path ".").path @@ -67,31 +108,73 @@ jobs: "SMING_HOME=" + (Resolve-Path "../../sming/Sming").path >> $env:GITHUB_ENV "COMPONENT_SEARCH_DIRS=" + (Resolve-Path "..").path >> $env:GITHUB_ENV "CI_MAKEFILE=" + (Resolve-Path "../../sming/Tools/ci/library/Makefile") >> $env:GITHUB_ENV - "SMING_ARCH=${{ matrix.arch }}" >> $env:GITHUB_ENV - "SMING_SOC=${{ matrix.variant }}" >> $env:GITHUB_ENV - - name: Install build tools for Ubuntu - if: ${{ matrix.os == 'ubuntu-20.04' }} + - name: Fix permissions + if: matrix.os != 'windows-latest' run: | - . $SMING_HOME/../Tools/export.sh - $SMING_HOME/../Tools/ci/install.sh $SMING_ARCH + sudo chown $USER /opt + + - name: Cache ESP-IDF and build tools + if: matrix.arch == 'Esp32' + uses: actions/cache@v4 + with: + path: | + /opt/esp-idf-${{ env.INSTALL_IDF_VER }} + /opt/esp32 + key: ${{ matrix.os }}-idf-${{ env.INSTALL_IDF_VER }} - - name: Install build tools for Windows - if: ${{ matrix.os == 'windows-latest' }} + - name: Install build tools for Ubuntu / MacOS + if: matrix.os != 'windows-latest' run: | - . "$env:SMING_HOME/../Tools/ci/setenv.ps1" - . "$env:SMING_HOME/../Tools/ci/install.cmd" + $SMING_HOME/../Tools/ci/install.sh + + - name: Install build tools for Windows + if: matrix.os == 'windows-latest' + run: | + cd $env:SMING_HOME/.. + . Tools/ci/setenv.ps1 + Tools/ci/install.cmd - - name: Build and Test for ${{matrix.arch}} on Ubuntu + - name: Restore Compiler Cache + id: ccache + uses: actions/cache/restore@v4 + with: + path: ${{ env.CCACHE_DIR }} + key: ${{ matrix.os }}-ccache-${{ matrix.toolchain }}-${{ matrix.variant }}-${{ matrix.arch == 'Esp32' && env.INSTALL_IDF_VER || '' }} + + - name: Build and Test for ${{matrix.arch}} on Ubuntu / MacOS env: CLANG_FORMAT: clang-format-8 - if: ${{ matrix.os == 'ubuntu-20.04' }} + if: matrix.os != 'windows-latest' run: | + ccache -z . $SMING_HOME/../Tools/export.sh make -j$(nproc) -f $CI_MAKEFILE - name: Build and Test for ${{matrix.arch}} on Windows - if: ${{ matrix.os == 'windows-latest' }} + if: matrix.os == 'windows-latest' run: | + ccache -z . "$env:SMING_HOME/../Tools/ci/setenv.ps1" make -j $env:NUMBER_OF_PROCESSORS -f $env:CI_MAKEFILE + + - name: Compiler Cache stats + run: | + ccache --evict-older-than 14400s + ccache -sv + + - name: Delete Previous Compiler Cache + if: github.ref_name == github.event.repository.default_branch && steps.ccache.outputs.cache-hit + continue-on-error: true + run: | + gh extension install actions/gh-actions-cache + gh actions-cache delete "${{ steps.ccache.outputs.cache-primary-key }}" --branch ${{ github.ref_name }} --confirm + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Save Compiler Cache + if: github.ref_name == github.event.repository.default_branch || !steps.ccache.outputs.cache-hit + uses: actions/cache/save@v4 + with: + path: ${{ env.CCACHE_DIR }} + key: ${{ steps.ccache.outputs.cache-primary-key }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 06cf230995..8f2d4dee10 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,31 +5,31 @@ on: push: tags: - '[0-9]+.[0-9]+.[0-9]+' - + # TODO: check if the tag is pointing to the tip of the master branch jobs: release: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: trstringer/manual-approval@v1 - if: ${{ github.ref_type == 'tag' }} + if: github.ref_type == 'tag' with: secret: ${{ github.TOKEN }} approvers: slaff - name: Install xmlstarlet - if: ${{ github.ref_type == 'tag' }} - run: sudo apt-get install -y xmlstarlet + if: github.ref_type == 'tag' + run: sudo apt-get install -y jq xmlstarlet - name: Build docs - if: ${{ github.ref_type == 'tag' }} + if: github.ref_type == 'tag' run: | Tools/install.sh doc make -C docs html zip -r sming-docs.zip docs/build/html - name: Release New Version - if: ${{ github.ref_type == 'tag' }} - env: + if: github.ref_type == 'tag' + env: SMING_ARCH: Host RELEASE_TOKEN: ${{secrets.RELEASE_TOKEN}} CI_REPO_NAME: ${{github.repository}} diff --git a/.github/workflows/spelling-check.yml b/.github/workflows/spelling-check.yml index 4e8d27e7be..9d3a76dba8 100644 --- a/.github/workflows/spelling-check.yml +++ b/.github/workflows/spelling-check.yml @@ -10,7 +10,7 @@ jobs: name: Check spelling runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: false - name: Get submodules diff --git a/.gitignore b/.gitignore index 70e63abe10..180c1a5cc0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,8 @@ # generated binaries out -# generated documentation -docs/api -docs/build -docs/source/_inc -*.pyc +# Python cache +__pycache__ # Eclipse .project diff --git a/.gitmodules b/.gitmodules index 67d22b225b..a1404fb3cd 100644 --- a/.gitmodules +++ b/.gitmodules @@ -97,7 +97,7 @@ ignore = dirty [submodule "Esp8266.lwip2"] path = Sming/Arch/Esp8266/Components/lwip2/lwip2 - url = https://github.com/mikee47/esp82xx-nonos-linklayer.git + url = https://github.com/d-a-v/esp82xx-nonos-linklayer.git ignore = dirty [submodule "Esp8266.umm_malloc"] path = Sming/Arch/Esp8266/Components/heap/umm_malloc @@ -217,6 +217,10 @@ path = Sming/Libraries/CS5460/CS5460 url = https://github.com/xxzl0130/CS5460.git ignore = dirty +[submodule "Libraries.CsvReader"] + path = Sming/Libraries/CsvReader + url = https://github.com/mikee47/CsvReader + ignore = dirty [submodule "Libraries.DFRobotDFPlayerMini"] path = Sming/Libraries/DFRobotDFPlayerMini url = https://github.com/DFRobot/DFRobotDFPlayerMini.git @@ -349,6 +353,10 @@ path = Sming/Libraries/SolarCalculator url = https://github.com/mikee47/SolarCalculator ignore = dirty +[submodule "Libraries.SparkFun_APDS9960"] + path = Sming/Libraries/SparkFun_APDS9960 + url = https://github.com/sparkfun/SparkFun_APDS-9960_Sensor_Arduino_Library + ignore = dirty [submodule "Libraries.spiffs"] path = Sming/Libraries/Spiffs/spiffs url = https://github.com/pellepl/spiffs.git diff --git a/.readthedocs.yml b/.readthedocs.yml index fa3b0a80e9..13b0003085 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -7,9 +7,9 @@ version: 2 # Required build: - os: ubuntu-20.04 + os: ubuntu-22.04 tools: - python: "3.8" + python: "3.12" # Optionally build your docs in additional formats such as PDF and ePub formats: diff --git a/README.md b/README.md index 5bd3e7d19a..b35dca3b58 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Sming -Sming is an asynchronous embedded C/C++ framework with superb performance and multiple network features. +Sming is an asynchronous embedded C++ framework with superb performance and multiple network features. Sming is [open source](LICENSE), modular and supports [multiple architectures](https://sming.readthedocs.io/en/latest/features.html) including ESP8266, ESP32 and RP2040. [![Examples](https://github.com/SmingHub/Sming/wiki/images/small/combine.png)](https://github.com/SmingHub/Sming/wiki/examples) @@ -29,33 +29,34 @@ You can also try Sming without installing anything locally. We have an [interact The purpose of Sming is to simplify the creation of embedded applications. The documentation will help you get started in no time. -- [**Documentation for version 5.1.0**](https://sming.readthedocs.io/en/stable) - current stable version. +- [**Documentation for version 5.2.0**](https://sming.readthedocs.io/en/stable) - current stable version. - [Documentation for latest](https://sming.readthedocs.io/en/latest) - development version. ## Releases ### Stable -- [Sming V5.1.0](https://github.com/SmingHub/Sming/releases/tag/5.1.0) - great new features, performance and stability improvements. +- [Sming V5.2.0](https://github.com/SmingHub/Sming/releases/tag/5.2.0) - great new features, performance and stability improvements. ### Development To follow the latest development you will need to clone our `develop` branch: -``` +```bash git clone https://github.com/SmingHub/Sming.git ``` ## Examples -The examples are a great way to learn the API and brush up your C/C++ knowledge. -Once you have completed the installation of the development tools, you can get the latest source code. -``` +The examples are a great way to learn the API and brush up your C++ knowledge. +Once you have completed the installation of the development tools, you can get the latest source code: + +```bash git clone https://github.com/SmingHub/Sming.git ``` -And check some of the examples. +And check some of the examples: - [Basic Blink](#basic-blink) - [Simple GPIO input/output](#simple-gpio-inputoutput) @@ -68,9 +69,10 @@ And check some of the examples. - [Email Client](#email-client) ### Basic Blink + Blinking is something like the "Hello World" example for the embedded world. You can check it using the commands below: -``` +```bash cd Sming/samples cd Basic_Blink make # -- compiles the application @@ -80,6 +82,7 @@ make flash # -- tries to upload the application to your ESP8266 device. More information at **[Sample Projects](https://sming.readthedocs.io/en/latest/samples.html)** page. ### Simple GPIO Input/Output + ```c++ #define LED_PIN 2 // GPIO2 ... @@ -90,18 +93,21 @@ digitalWrite(LED_PIN, HIGH); For a complete example take a look at the [Basic_Blink](samples/Basic_Blink/app/application.cpp) sample. ### Start Serial Communication + ```c++ Serial.begin(9600); Serial.println("Hello Sming! Let's do smart things."); ``` ### Connect to WiFi + ```c++ WifiStation.enable(true); WifiStation.config("LOCAL-NETWORK", "123456789087"); // Put your SSID and password here ``` ### Read DHT22 sensor + ```c++ #include // This is just a popular Arduino library! @@ -110,16 +116,17 @@ DHTesp dht; void init() { -  dht.setup(DHT_PIN, DHTesp::DHT22); + dht.setup(DHT_PIN, DHTesp::DHT22); -  float h = dht.getHumidity(); -  float t = dht.getTemperature(); + float h = dht.getHumidity(); + float t = dht.getTemperature(); } ``` Take a look at the code of the [Humidity_DHT22](samples/Humidity_DHT22/app/application.cpp) sample. ### HTTP Client + ```c++ HttpClient thingSpeak; ... @@ -127,18 +134,19 @@ thingSpeak.downloadString("http://api.thingspeak.com/update?key=XXXXXXX&field1=" void onDataSent(HttpClient& client, bool successful) { -  if (successful) { -    Serial.println("Successful!"); -  } -  else { -    Serial.println("Failed"); -  } + if (successful) { + Serial.println("Successful!"); + } + else { + Serial.println("Failed"); + } } ``` For more examples take a look at the [HttpClient](samples/HttpClient/app/application.cpp), [HttpClient_Instapush](samples/HttpClient_Instapush/app/application.cpp) and [HttpClient_ThingSpeak](samples/HttpClient_ThingSpeak/app/application.cpp) samples. ### OTA Application Update + ```c++ void doUpgrade() { @@ -151,20 +159,21 @@ void doUpgrade() // select rom partition to flash auto part = ota.getNextBootPartition(); -  // The content located on ROM_0_URL will be stored to the new partition -  otaUpdater->addItem(ROM_0_URL, part); + // The content located on ROM_0_URL will be stored to the new partition + otaUpdater->addItem(ROM_0_URL, part); -  // and/or set a callback (called on failure or success without switching requested) -  otaUpdater->setCallback(upgradeCallback); + // and/or set a callback (called on failure or success without switching requested) + otaUpdater->setCallback(upgradeCallback); -  // start update -  otaUpdater->start(); + // start update + otaUpdater->start(); } ``` For a complete example take a look at the [Basic_Ota](samples/Basic_Ota/app/application.cpp) sample. ### HTTP Server + ```c++ server.listen(80); server.paths.set("/", onIndex); @@ -178,28 +187,29 @@ Serial.println(WifiStation.getIP()); void onIndex(HttpRequest &request, HttpResponse &response) { -  TemplateFileStream *tmpl = new TemplateFileStream("index.html"); -  auto &vars = tmpl->variables(); -  vars["counter"] = String(counter); -  vars["IP"] = WifiStation.getIP().toString(); -  vars["MAC"] = WifiStation.getMAC(); -  response.sendTemplate(tmpl); + TemplateFileStream *tmpl = new TemplateFileStream("index.html"); + auto &vars = tmpl->variables(); + vars["counter"] = String(counter); + vars["IP"] = WifiStation.getIP().toString(); + vars["MAC"] = WifiStation.getMAC(); + response.sendTemplate(tmpl); } void onFile(HttpRequest &request, HttpResponse &response) { -  String file = request.getPath(); -  if (file[0] == '/') -    file = file.substring(1); + String file = request.getPath(); + if (file[0] == '/') + file = file.substring(1); -  response.setCache(86400, true); -  response.sendFile(file); + response.setCache(86400, true); + response.sendFile(file); } ``` For more examples take a look at the [HttpServer_ConfigNetwork](samples/HttpServer_ConfigNetwork/app/application.cpp), [HttpServer_Bootstrap](samples/HttpServer_Bootstrap/app/application.cpp), [HttpServer_WebSockets](samples/HttpServer_WebSockets/app/application.cpp) and [HttpServer_AJAX](samples/HttpServer_AJAX/app/application.cpp) samples. ### Email Client + ```c++ SmtpClient emailClient; @@ -221,15 +231,15 @@ emailClient.send(mail); int onMailSent(SmtpClient& client, int code, char* status) { -    MailMessage* mail = client.getCurrentMessage(); + MailMessage* mail = client.getCurrentMessage(); -    ... + ... -    if(!client.countPending()) { -        client.quit(); -    } + if(!client.countPending()) { + client.quit(); + } -    return 0; + return 0; } ``` @@ -237,10 +247,11 @@ int onMailSent(SmtpClient& client, int code, char* status) See the [SmtpClient sample](samples/SmtpClient/app/application.cpp) for details. ## Live Debugging + Applications based on Sming Framework that are flashed and running on an ESP8266 device can be debugged using interactive debuggers. In order to debug an application it has to be re-compiled with the ENABLE_GDB=1 directive. And then flashed on the device. As shown below: -``` +```bash cd $SMING_HOME/../samples/LiveDebug make clean make ENABLE_GDB=1 @@ -248,7 +259,8 @@ make flashapp # <-- this will update only the application firmware. ``` Once the debuggable application is flashed on the device the developers have to run GDB. The easiest way to run the command-line GDB is to execute the following command: -``` + +```bash make gdb ``` @@ -260,7 +272,8 @@ See [LiveDebug sample](samples/LiveDebug/) for details. ## Contribute -You can contribute to Sming by +You can contribute to Sming by: + - Providing Pull Requests with new features, bug fixes, new ideas, etc. See [Contributing](https://smingdev.readthedocs.io/en/latest/contribute/index.html) for details. - Testing our latest source code and reporting issues. - Supporting us financially to acquire hardware for testing and implementing or out of gratitude @@ -276,8 +289,10 @@ In addition to that anyone who is helping this project can file an expense. If t #### Backers and sponsors Thank you to all the people who have backed Sming - + +backer or sponsored it. - + +sponsor diff --git a/Sming/Arch/Esp32/Components/driver/hw_timer.cpp b/Sming/Arch/Esp32/Components/driver/hw_timer.cpp index 9b5cc202dc..c7495c1152 100644 --- a/Sming/Arch/Esp32/Components/driver/hw_timer.cpp +++ b/Sming/Arch/Esp32/Components/driver/hw_timer.cpp @@ -10,7 +10,10 @@ #include #include +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" #include +#pragma GCC diagnostic pop #include #include @@ -43,7 +46,7 @@ class TimerConfig #endif } - void IRAM_ATTR attach_interrupt(hw_timer_source_type_t source_type, hw_timer_callback_t callback, void* arg) + void IRAM_ATTR attach_interrupt(hw_timer_source_type_t, hw_timer_callback_t callback, void* arg) { if(isr_handle != nullptr) { detach_interrupt(); @@ -54,6 +57,7 @@ class TimerConfig } this->callback = callback; + this->arg = arg; uint32_t status_reg = reinterpret_cast(timer_ll_get_intr_status_reg(dev)); uint32_t mask = 1 << index; @@ -62,8 +66,8 @@ class TimerConfig #else int source = timer_group_periph_signals.groups[group].timer_irq_id[index]; #endif - esp_intr_alloc_intrstatus(source, ESP_INTR_FLAG_IRAM, status_reg, mask, timerIsr, this, &isr_handle); clear_intr_status(); + esp_intr_alloc_intrstatus(source, ESP_INTR_FLAG_IRAM, status_reg, mask, timerIsr, this, &isr_handle); enable_intr(true); } @@ -83,13 +87,17 @@ class TimerConfig timer_ll_intr_disable(dev, index); } #else - timer_ll_enable_intr(dev, index, state); + timer_ll_enable_intr(dev, TIMER_LL_EVENT_ALARM(index), state); #endif } void __forceinline clear_intr_status() { +#if ESP_IDF_VERSION_MAJOR < 5 timer_ll_clear_intr_status(dev, index); +#else + timer_ll_clear_intr_status(dev, TIMER_LL_EVENT_ALARM(index)); +#endif } void __forceinline set_alarm_value(uint64_t value) @@ -142,6 +150,9 @@ class TimerConfig timer_ll_get_counter_value(dev, index, &val); return val; #else +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0) + timer_ll_trigger_soft_capture(dev, index); +#endif return timer_ll_get_counter_value(dev, index); #endif } @@ -161,7 +172,7 @@ class TimerConfig auto& timer = *static_cast(arg); if(timer.callback != nullptr) { - timer.callback(arg); + timer.callback(timer.arg); } timer.clear_intr_status(); @@ -213,7 +224,7 @@ void IRAM_ATTR hw_timer1_disable(void) timer.enable_counter(false); } -uint32_t hw_timer1_read(void) +uint32_t IRAM_ATTR hw_timer1_read(void) { return timer.get_counter_value(); } diff --git a/Sming/Arch/Esp32/Components/driver/hw_timer.rst b/Sming/Arch/Esp32/Components/driver/hw_timer.rst index 14fae3de0f..979e853f93 100644 --- a/Sming/Arch/Esp32/Components/driver/hw_timer.rst +++ b/Sming/Arch/Esp32/Components/driver/hw_timer.rst @@ -3,25 +3,6 @@ hw_timer: Hardware Timers Driver for hardware timers. -Variables ---------- - -.. envvar:: USE_US_TIMER - - 0 (default): Use default /256 prescale for Timer2 - 1: Use /16 prescale - - The following functions depend on Timer2: - - NOW() return value, the Timer2 tick count - - Software timers - - System time - - Software timers are driven by Timer2, which by default uses a /256 prescale - providing a resolution of 3.2us and a range of 1' 54". - - Enabling this setting increases the resolution to 200ns but reduces the maximum - software timer to 7" 9.5s. - API Documentation ----------------- diff --git a/Sming/Arch/Esp32/Components/driver/i2s.rst b/Sming/Arch/Esp32/Components/driver/i2s.rst index fc56ee73d7..4eb56bfc4a 100644 --- a/Sming/Arch/Esp32/Components/driver/i2s.rst +++ b/Sming/Arch/Esp32/Components/driver/i2s.rst @@ -1,64 +1,4 @@ I2S: Inter-IC Serial communications =================================== -Introduction ------------- - -`I2S `__ was designed for transfer of digital audio data. - -The ESP8266 has two I2S modules (one transmitter and one receiver), both with hardware -`DMA `__ support, which means transfers from -RAM to the hardware SPI FIFO can be handled directly in hardware without any CPU involvement. - - -Sming I2S support ------------------ - -The Sming driver deals with the complicated of setting up the hardware, using an API -similar to that in the Espressif RTOS SDK. In addition, DMA buffers may be accessed directly -to avoid double-buffering and the associated RAM and copy overhead. - - -Applications ------------- - -Audio -~~~~~ - -Playing MIDI files, MP3 files, speech synthesis, etc. is all possible using the ESP8266, -though many audio applications require considerable processing power. -That means you may need to disable WiFi and set the processor to run at full 160MHz speed. - -High-quality multi-channel audio requires an external I2S DAC, which is what the protocol -was designed for in the first place. You may find problems with insufficient RAM, -but you can always add external SPI RAM. - -More realistic uses include generating simple tones, beeps, playing pre-recorded WAV audio, -etc. to supplement existing projects. This can all be done in the background without -disrupting the system's main purpose, whatever that may be. - -For such applications you can generate single-channel audio via the I2S OUT pin, -using `Pulse-density modulation `__. - -See the :library:`ToneGenerator` library for a demonstration of this. - - -GPIO Expansion -~~~~~~~~~~~~~~ - -Expand GPIO using low-cost shift registers. https://github.com/lhartmann/esp8266_reprap. - - -Pixel-strip control -~~~~~~~~~~~~~~~~~~~ - -Devices such as WS2812-based NeoPixels use a simple, single-wire protocol. -I2S is ideal for this as it can be used to generate a precisely-timed bitstream -with very low CPU loading. - - -API Documentation ------------------ - -.. doxygengroup:: i2s_driver - :content-only: +Not currently implemented for Esp32. diff --git a/Sming/Arch/Esp32/Components/driver/include/driver/hw_timer.h b/Sming/Arch/Esp32/Components/driver/include/driver/hw_timer.h index 8f2a7e2ccd..1979b45072 100644 --- a/Sming/Arch/Esp32/Components/driver/include/driver/hw_timer.h +++ b/Sming/Arch/Esp32/Components/driver/include/driver/hw_timer.h @@ -147,6 +147,7 @@ uint32_t hw_timer1_read(void); __forceinline static uint32_t hw_timer2_read(void) { #if CONFIG_ESP_TIMER_IMPL_TG0_LAC + REG_WRITE(TIMG_LACTUPDATE_REG(0), 1); return REG_READ(TIMG_LACTLO_REG(0)); #elif ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0) systimer_ll_counter_snapshot(&SYSTIMER, 0); diff --git a/Sming/Arch/Esp32/Components/driver/include/driver/spi_master.h b/Sming/Arch/Esp32/Components/driver/include/driver/spi_master.h index 0d18f8d13e..add4c29c35 100644 --- a/Sming/Arch/Esp32/Components/driver/include/driver/spi_master.h +++ b/Sming/Arch/Esp32/Components/driver/include/driver/spi_master.h @@ -2,6 +2,7 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsign-compare" +#pragma GCC diagnostic ignored "-Wunused-parameter" #include_next diff --git a/Sming/Arch/Esp32/Components/driver/include/driver/uart.h b/Sming/Arch/Esp32/Components/driver/include/driver/uart.h index ba4c6e3664..3633b5c0ef 100644 --- a/Sming/Arch/Esp32/Components/driver/include/driver/uart.h +++ b/Sming/Arch/Esp32/Components/driver/include/driver/uart.h @@ -1,8 +1,15 @@ #pragma once +#include #include +#if SOC_USB_SERIAL_JTAG_SUPPORTED && ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0) +#define UART_PHYSICAL_COUNT (SOC_UART_NUM + 1) ///< Number of physical UARTs on the system +#define UART_ID_SERIAL_USB_JTAG SOC_UART_NUM +#else #define UART_PHYSICAL_COUNT SOC_UART_NUM ///< Number of physical UARTs on the system -#define UART_COUNT SOC_UART_NUM ///< Number of UARTs on the system, virtual or otherwise +#endif + +#define UART_COUNT SOC_UART_NUM ///< Number of UARTs on the system, virtual or otherwise #include_next diff --git a/Sming/Arch/Esp32/Components/driver/pwm.rst b/Sming/Arch/Esp32/Components/driver/pwm.rst deleted file mode 100644 index 47df1eb558..0000000000 --- a/Sming/Arch/Esp32/Components/driver/pwm.rst +++ /dev/null @@ -1,21 +0,0 @@ -PWM: Pulse-Width Modulation -=========================== - -The driver interface is defined in the ESP8266 SDK. - -Build variables ---------------- - -.. envvar:: ENABLE_CUSTOM_PWM - - undefined - use the Espressif PWM driver - - 1 (default) - Use the *New PWM* driver, a drop-in replacement for the version provided in the Espressif SDK. - -API Documentation ------------------ - -.. doxygengroup:: pwm_driver - :content-only: diff --git a/Sming/Arch/Esp32/Components/driver/uart.cpp b/Sming/Arch/Esp32/Components/driver/uart.cpp index 3e03b60339..d608381f97 100644 --- a/Sming/Arch/Esp32/Components/driver/uart.cpp +++ b/Sming/Arch/Esp32/Components/driver/uart.cpp @@ -15,11 +15,22 @@ #include #include #include +#include #include #include #include #include +#if UART_ID_SERIAL_USB_JTAG +#include "hal/usb_serial_jtag_ll.h" +#include "hal/usb_fsls_phy_ll.h" +#if !SOC_RCC_IS_INDEPENDENT +#define USJ_RCC_ATOMIC() PERIPH_RCC_ATOMIC() +#else +#define USJ_RCC_ATOMIC() +#endif +#endif + namespace { // Ensure global values correspond to hardware values (may break when new variants added) @@ -161,15 +172,110 @@ __forceinline bool is_physical(smg_uart_t* uart) return uart != nullptr && is_physical(uart->uart_nr); } -/** @brief If given a virtual uart, obtain the related physical one +/** @brief Determine if the given uart is a standard UART */ -smg_uart_t* get_physical(smg_uart_t* uart) +__forceinline bool is_standard_uart(int uart_nr) { - return uart; + return (uart_nr >= 0) && (uart_nr < SOC_UART_NUM); +} + +__forceinline bool is_standard_uart(smg_uart_t* uart) +{ + return uart != nullptr && is_standard_uart(uart->uart_nr); } -/** @brief UART interrupt service routine - * @note both UARTS share the same ISR, although UART1 only supports transmit +/** @brief If given a virtual uart, obtain the related physical standard uart + */ +smg_uart_t* get_standard_uart(smg_uart_t* uart) +{ + return is_standard_uart(uart) ? uart : nullptr; +} + +#if UART_ID_SERIAL_USB_JTAG + +/** + * @brief Determine if the given uart is USB Serial JTAG + */ +__forceinline bool is_usb_serial_jtag(int uart_nr) +{ + return UART_ID_SERIAL_USB_JTAG && uart_nr == UART_ID_SERIAL_USB_JTAG; +} + +__forceinline bool is_usb_serial_jtag(smg_uart_t* uart) +{ + return uart != nullptr && is_usb_serial_jtag(uart->uart_nr); +} + +void IRAM_ATTR usb_serial_jtag_isr(smg_uart_instance_t* inst) +{ + if(inst == nullptr || inst->uart == nullptr) { + return; + } + + auto uart = inst->uart; + // Value passed to user callback + uint32_t status{0}; + + uint32_t usbjtag_intr_status = usb_serial_jtag_ll_get_intsts_mask(); + + if(usbjtag_intr_status & USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY) { + status |= UART_INTR_TXFIFO_EMPTY; + // Check if hardware fifo is available for writing + if(!usb_serial_jtag_ll_txfifo_writable()) { + usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY); + } else { + usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY); + + if(uart->tx_buffer != nullptr) { + void* queued_buff; + size_t queued_size = uart->tx_buffer->getReadData(queued_buff); + + usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY); + + if(queued_size != 0) { + size_t sent_size = usb_serial_jtag_ll_write_txfifo(static_cast(queued_buff), queued_size); + uart->tx_buffer->skipRead(sent_size); + usb_serial_jtag_ll_txfifo_flush(); + usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY); + } + } + } + } + + if(usbjtag_intr_status & USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT) { + // Read hardware FIFO into ring buffer + usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT); + uint8_t rx_data_buf[USB_SERIAL_JTAG_PACKET_SZ_BYTES]; + size_t space = uart->rx_buffer->getFreeSpace(); + size_t to_read = std::min(space, size_t(USB_SERIAL_JTAG_PACKET_SZ_BYTES)); + size_t read = usb_serial_jtag_ll_read_rxfifo(rx_data_buf, to_read); + space -= read; + auto ptr = rx_data_buf; + while(read-- != 0) { + uart->rx_buffer->writeChar(*ptr++); + } + + // Only invoke user callback when buffer is (almost) full + if(space <= uart->rx_headroom) { + status |= UART_INTR_RXFIFO_FULL; + } else { + // No hardware timeout available, we'd need to implement one + status |= UART_INTR_RXFIFO_TOUT; + } + } + + // Keep a note of persistent flags - cleared via uart_get_status() + uart->status |= status; + + if(status != 0 && uart->callback != nullptr) { + uart->callback(uart, status); + } +} + +#endif + +/* + * Standard UART interrupt service routine */ void IRAM_ATTR uart_isr(smg_uart_instance_t* inst) { @@ -320,7 +426,7 @@ size_t smg_uart_read(smg_uart_t* uart, void* buffer, size_t size) } // Top up from hardware FIFO - if(is_physical(uart)) { + if(is_standard_uart(uart)) { auto dev = getDevice(uart->uart_nr); auto len = std::min(uint32_t(size - read), uart_ll_get_rxfifo_len(dev)); uart_ll_read_rxfifo(dev, &buf[read], len); @@ -330,6 +436,12 @@ size_t smg_uart_read(smg_uart_t* uart, void* buffer, size_t size) uart_ll_clr_intsts_mask(dev, UART_INTR_RXFIFO_FULL | UART_INTR_RXFIFO_TOUT | UART_INTR_RXFIFO_OVF); uart_ll_ena_intr_mask(dev, UART_INTR_RXFIFO_FULL | UART_INTR_RXFIFO_TOUT | UART_INTR_RXFIFO_OVF); } +#if UART_ID_SERIAL_USB_JTAG + else if(is_usb_serial_jtag(uart)) { + auto len = usb_serial_jtag_ll_read_rxfifo(&buf[read], size - read); + read += len; + } +#endif return read; } @@ -342,8 +454,11 @@ size_t smg_uart_rx_available(smg_uart_t* uart) smg_uart_disable_interrupts(); - auto dev = getDevice(uart->uart_nr); - size_t avail = is_physical(uart) ? uart_ll_get_rxfifo_len(dev) : 0; + size_t avail = 0; + if(is_standard_uart(uart)) { + auto dev = getDevice(uart->uart_nr); + avail = uart_ll_get_rxfifo_len(dev); + } if(uart->rx_buffer != nullptr) { avail += uart->rx_buffer->available(); @@ -360,25 +475,40 @@ void smg_uart_start_isr(smg_uart_t* uart) return; } - uint32_t int_ena{0}; + int interrupt_source; + intr_handler_t interrupt_handler; - auto dev = getDevice(uart->uart_nr); - dev->conf1.val = 0; +#if UART_ID_SERIAL_USB_JTAG + if(is_usb_serial_jtag(uart)) { + usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY | + USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT); + usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY | + USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT); - if(smg_uart_rx_enabled(uart)) { - uart_ll_set_rxfifo_full_thr(dev, RX_FIFO_FULL_THRESHOLD); - uart_ll_set_rx_tout(dev, 10); + interrupt_source = ETS_USB_SERIAL_JTAG_INTR_SOURCE; + interrupt_handler = reinterpret_cast(usb_serial_jtag_isr); + } else +#endif + { + uint32_t int_ena{0}; + + auto dev = getDevice(uart->uart_nr); + dev->conf1.val = 0; + + if(smg_uart_rx_enabled(uart)) { + uart_ll_set_rxfifo_full_thr(dev, RX_FIFO_FULL_THRESHOLD); + uart_ll_set_rx_tout(dev, 10); - /* + /* * There is little benefit in generating interrupts on errors, instead these * should be cleared at the start of a transaction and checked at the end. * See uart_get_status(). */ - int_ena |= UART_INTR_RXFIFO_FULL | UART_INTR_RXFIFO_TOUT | UART_INTR_BRK_DET | UART_INTR_RXFIFO_OVF; - } + int_ena |= UART_INTR_RXFIFO_FULL | UART_INTR_RXFIFO_TOUT | UART_INTR_BRK_DET | UART_INTR_RXFIFO_OVF; + } - if(smg_uart_tx_enabled(uart)) { - /* + if(smg_uart_tx_enabled(uart)) { + /* * We can interrupt when TX FIFO is empty; at 1Mbit that gives us 800 CPU * cycles before the last character has actually gone over the wire. Even if * a gap occurs it is unlike to cause any problems. It also makes the callback @@ -386,17 +516,20 @@ void smg_uart_start_isr(smg_uart_t* uart) * transfer direction and begin waiting for a response. */ - // TX FIFO empty interrupt only gets enabled via uart_write function() - uart_ll_set_txfifo_empty_thr(dev, 10); - } + // TX FIFO empty interrupt only gets enabled via uart_write function() + uart_ll_set_txfifo_empty_thr(dev, 10); + } - dev->int_clr.val = 0x0007ffff; - dev->int_ena.val = int_ena; + dev->int_clr.val = 0x0007ffff; + dev->int_ena.val = int_ena; + + interrupt_source = uart_periph_signal[uart->uart_nr].irq; + interrupt_handler = reinterpret_cast(uart_isr); + } smg_uart_disable_interrupts(); auto& inst = uartInstances[uart->uart_nr]; - auto& conn = uart_periph_signal[uart->uart_nr]; - esp_intr_alloc(conn.irq, ESP_INTR_FLAG_IRAM, intr_handler_t(uart_isr), &inst, &inst.handle); + esp_intr_alloc(interrupt_source, ESP_INTR_FLAG_IRAM, interrupt_handler, &inst, &inst.handle); smg_uart_restore_interrupts(); bitSet(isrMask, uart->uart_nr); } @@ -411,12 +544,10 @@ size_t smg_uart_write(smg_uart_t* uart, const void* buffer, size_t size) auto buf = static_cast(buffer); - bool isPhysical = is_physical(uart); - while(written < size) { - if(isPhysical) { - // If TX buffer not in use or it's empty then write directly to hardware FIFO - if(uart->tx_buffer == nullptr || uart->tx_buffer->isEmpty()) { + // If TX buffer not in use or it's empty then write directly to hardware FIFO + if(uart->tx_buffer == nullptr || uart->tx_buffer->isEmpty()) { + if(is_standard_uart(uart)) { auto dev = getDevice(uart->uart_nr); auto len = std::min(size - written, uart_txfifo_free(dev)); uart_ll_write_txfifo(dev, &buf[written], len); @@ -425,6 +556,16 @@ size_t smg_uart_write(smg_uart_t* uart, const void* buffer, size_t size) uart_ll_clr_intsts_mask(dev, UART_INTR_TXFIFO_EMPTY); uart_ll_ena_intr_mask(dev, UART_INTR_TXFIFO_EMPTY); } +#if UART_ID_SERIAL_USB_JTAG + else if(is_usb_serial_jtag(uart)) { + usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY); + auto len = usb_serial_jtag_ll_write_txfifo(&buf[written], size - written); + written += len; + usb_serial_jtag_ll_txfifo_flush(); + // Enable TX FIFO EMPTY interrupt + usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY); + } +#endif } // Write any remaining data into transmit buffer @@ -452,7 +593,11 @@ size_t smg_uart_tx_free(smg_uart_t* uart) smg_uart_disable_interrupts(); - size_t space = is_physical(uart) ? uart_txfifo_free(getDevice(uart->uart_nr)) : 0; + size_t space = 0; + if(is_standard_uart(uart)) { + auto dev = getDevice(uart->uart_nr); + space = uart_txfifo_free(dev); + } if(uart->tx_buffer != nullptr) { space += uart->tx_buffer->getFreeSpace(); } @@ -476,16 +621,24 @@ void smg_uart_wait_tx_empty(smg_uart_t* uart) } } - if(is_physical(uart)) { + if(is_standard_uart(uart)) { auto dev = getDevice(uart->uart_nr); - while(uart_txfifo_count(dev) != 0) + while(uart_txfifo_count(dev) != 0) { + system_soft_wdt_feed(); + } + } +#if UART_ID_SERIAL_USB_JTAG + else if(is_usb_serial_jtag(uart)) { + while(!usb_serial_jtag_ll_txfifo_writable()) { system_soft_wdt_feed(); + } } +#endif } void smg_uart_set_break(smg_uart_t* uart, bool state) { - uart = get_physical(uart); + uart = get_standard_uart(uart); if(uart != nullptr) { auto dev = getDevice(uart->uart_nr); dev->conf0.txd_brk = state; @@ -501,7 +654,7 @@ uint8_t smg_uart_get_status(smg_uart_t* uart) status = uart->status & (UART_INTR_BRK_DET | UART_INTR_RXFIFO_OVF); uart->status = 0; // Read raw status register directly from real uart, masking out non-error bits - uart = get_physical(uart); + uart = get_standard_uart(uart); if(uart != nullptr) { auto dev = getDevice(uart->uart_nr); status |= dev->int_raw.val & @@ -533,7 +686,7 @@ void smg_uart_flush(smg_uart_t* uart, smg_uart_mode_t mode) uart->tx_buffer->clear(); } - if(is_physical(uart)) { + if(is_standard_uart(uart)) { auto dev = getDevice(uart->uart_nr); if(flushTx) { @@ -555,7 +708,7 @@ void smg_uart_flush(smg_uart_t* uart, smg_uart_mode_t mode) uint32_t smg_uart_set_baudrate_reg(int uart_nr, uint32_t baud_rate) { - if(!is_physical(uart_nr) || baud_rate == 0) { + if(!is_standard_uart(uart_nr) || baud_rate == 0) { return 0; } @@ -567,7 +720,11 @@ uint32_t smg_uart_set_baudrate_reg(int uart_nr, uint32_t baud_rate) uart_ll_set_baudrate(dev, baud_rate); return uart_ll_get_baudrate(dev); #else +#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 2, 0) uart_ll_set_sclk(dev, UART_SCLK_DEFAULT); +#else + uart_ll_set_sclk(dev, soc_module_clk_t(UART_SCLK_DEFAULT)); +#endif uart_ll_set_baudrate(dev, baud_rate, APB_CLK_FREQ); return uart_ll_get_baudrate(dev, APB_CLK_FREQ); #endif @@ -575,7 +732,7 @@ uint32_t smg_uart_set_baudrate_reg(int uart_nr, uint32_t baud_rate) uint32_t smg_uart_set_baudrate(smg_uart_t* uart, uint32_t baud_rate) { - uart = get_physical(uart); + uart = get_standard_uart(uart); if(uart == nullptr) { return 0; } @@ -588,7 +745,7 @@ uint32_t smg_uart_set_baudrate(smg_uart_t* uart, uint32_t baud_rate) uint32_t smg_uart_get_baudrate(smg_uart_t* uart) { - uart = get_physical(uart); + uart = get_standard_uart(uart); return (uart == nullptr) ? 0 : uart->baud_rate; } @@ -641,26 +798,41 @@ smg_uart_t* smg_uart_init_ex(const smg_uart_config_t& cfg) smg_uart_detach(cfg.uart_nr); smg_uart_set_pins(uart, tx_pin, rx_pin); - auto& conn = uart_periph_signal[cfg.uart_nr]; + if(is_standard_uart(uart)) { + auto& conn = uart_periph_signal[cfg.uart_nr]; - periph_module_enable(conn.module); + periph_module_enable(conn.module); - auto dev = getDevice(cfg.uart_nr); + auto dev = getDevice(cfg.uart_nr); // Workaround for ESP32C3: enable core reset before enabling uart module clock to prevent uart output garbage value. #if SOC_UART_REQUIRE_CORE_RESET - uart_ll_set_reset_core(dev, true); - periph_module_reset(conn.module); - uart_ll_set_reset_core(dev, false); + uart_ll_set_reset_core(dev, true); + periph_module_reset(conn.module); + uart_ll_set_reset_core(dev, false); #else - periph_module_reset(conn.module); + periph_module_reset(conn.module); #endif - uart_ll_set_mode(dev, UART_MODE_UART); - uart_ll_set_tx_idle_num(dev, 0); + uart_ll_set_mode(dev, UART_MODE_UART); + uart_ll_set_tx_idle_num(dev, 0); - // Bottom 8 bits identical to esp8266 - dev->conf0.val = (dev->conf0.val & 0xFFFFFF00) | cfg.format; + // Bottom 8 bits identical to esp8266 + dev->conf0.val = (dev->conf0.val & 0xFFFFFF00) | cfg.format; + } +#if UART_ID_SERIAL_USB_JTAG + else if(is_usb_serial_jtag(uart)) { + USJ_RCC_ATOMIC() + { + usb_serial_jtag_ll_enable_bus_clock(true); + } +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0) + usb_fsls_phy_ll_int_jtag_enable(&USB_SERIAL_JTAG); +#else + usb_phy_ll_int_jtag_enable(&USB_SERIAL_JTAG); +#endif + } +#endif smg_uart_set_baudrate(uart, cfg.baudrate); smg_uart_flush(uart); @@ -697,7 +869,7 @@ void smg_uart_uninit(smg_uart_t* uart) void smg_uart_set_format(smg_uart_t* uart, smg_uart_format_t format) { - uart = get_physical(uart); + uart = get_standard_uart(uart); if(uart == nullptr) { return; } @@ -710,7 +882,7 @@ void smg_uart_set_format(smg_uart_t* uart, smg_uart_format_t format) bool smg_uart_intr_config(smg_uart_t* uart, const smg_uart_intr_config_t* config) { - uart = get_physical(uart); + uart = get_standard_uart(uart); if(uart == nullptr || config == nullptr) { return false; } @@ -739,7 +911,7 @@ bool smg_uart_intr_config(smg_uart_t* uart, const smg_uart_intr_config_t* config return true; } -void smg_uart_swap(smg_uart_t* uart, int tx_pin) +void smg_uart_swap(smg_uart_t*, int) { // Not implemented } @@ -825,17 +997,26 @@ void smg_uart_detach(int uart_nr) bitClear(isrMask, uart_nr); } - auto dev = getDevice(uart_nr); - dev->conf1.val = 0; - dev->int_clr.val = 0x0007ffff; - dev->int_ena.val = 0; + if(is_standard_uart(uart_nr)) { + auto dev = getDevice(uart_nr); + dev->conf1.val = 0; + dev->int_clr.val = 0x0007ffff; + dev->int_ena.val = 0; + } +#if UART_ID_SERIAL_USB_JTAG + else if(is_usb_serial_jtag(uart_nr)) { + // NB. Don't disable module clock or usb_pad_enable since the "USJ stdout might still depends on it" ? + usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY | + USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT); + } +#endif smg_uart_restore_interrupts(); } void smg_uart_detach_all() { smg_uart_disable_interrupts(); - for(unsigned uart_nr = 0; uart_nr < UART_PHYSICAL_COUNT; ++uart_nr) { + for(unsigned uart_nr = 0; uart_nr < SOC_UART_NUM; ++uart_nr) { if(bitRead(isrMask, uart_nr)) { auto& inst = uartInstances[uart_nr]; esp_intr_free(inst.handle); diff --git a/Sming/Arch/Esp32/Components/driver/uart.rst b/Sming/Arch/Esp32/Components/driver/uart.rst index 851a7d7917..774ae9bc70 100644 --- a/Sming/Arch/Esp32/Components/driver/uart.rst +++ b/Sming/Arch/Esp32/Components/driver/uart.rst @@ -1,7 +1,23 @@ UART: Universal Asynchronous Receive/Transmit ============================================= -Custom asynchronous driver. +Custom asynchronous serial port driver. + +.. c:macro:: UART_ID_SERIAL_USB_JTAG + + Some SOC variants, such as esp32c3, have an integrated USB JTAG/Serial port. + If so, then this value defines the associated serial port number. + + Requires ESP-IDF version 5.2 or later. + + Example usage:: + + #ifdef UART_ID_SERIAL_USB_JTAG + Serial.setPort(UART_ID_SERIAL_USB_JTAG); + #endif + Serial.begin(...); + .. doxygengroup:: uart_driver :content-only: + :members: diff --git a/Sming/Arch/Esp32/Components/esp32/component.mk b/Sming/Arch/Esp32/Components/esp32/component.mk index 5a83cd1aa1..b7f21017a9 100644 --- a/Sming/Arch/Esp32/Components/esp32/component.mk +++ b/Sming/Arch/Esp32/Components/esp32/component.mk @@ -14,8 +14,21 @@ ifeq ($(CREATE_EVENT_TASK),1) COMPONENT_CPPFLAGS += -DCREATE_EVENT_TASK endif -IDF_VERSION := $(firstword $(subst -, ,$(IDF_VER))) -IDF_VERSION_4 := $(filter v4%,$(IDF_VERSION)) +ifneq (,$(filter v4.%,$(IDF_VERSION))) +IDF_VERSION_4x := 1 +ifneq (,$(filter v4.3%,$(IDF_VERSION))) +IDF_VERSION_43 := 1 +else ifneq (,$(filter v4.4%,$(IDF_VERSION))) +IDF_VERSION_44 := 1 +endif +else ifneq (,$(filter v5.%,$(IDF_VERSION))) +IDF_VERSION_5x := 1 +endif +ifneq (,$(filter v5.0%,$(IDF_VERSION))) +IDF_VERSION_50 := 1 +else ifneq (,$(filter v5.2%,$(IDF_VERSION))) +IDF_VERSION_52 := 1 +endif ifneq (,$(filter esp32s3-v4.3%,$(ESP_VARIANT)-$(IDF_VER))) $(error esp32s3 requires ESP IDF v4.4 or later) @@ -32,6 +45,7 @@ SDKCONFIG_H := $(SDK_BUILD_BASE)/config/sdkconfig.h SDK_LIBDIRS := \ esp_wifi/lib/$(ESP_VARIANT) \ + esp_coex/lib/$(ESP_VARIANT) \ esp_phy/lib/$(ESP_VARIANT) \ xtensa/$(ESP_VARIANT) \ hal/$(ESP_VARIANT) \ @@ -52,6 +66,21 @@ endif ESP32_COMPONENT_PATH := $(COMPONENT_PATH) SDK_DEFAULT_PATH := $(ESP32_COMPONENT_PATH)/sdk +SDK_PROJECT_PATH := $(ESP32_COMPONENT_PATH)/project/$(ESP_VARIANT)/$(BUILD_TYPE) +SDK_CONFIG_DEFAULTS := $(SDK_PROJECT_PATH)/sdkconfig.defaults + +SDKCONFIG_MAKEFILE := $(SDK_PROJECT_PATH)/sdkconfig +ifeq ($(MAKE_DOCS),) +-include $(SDKCONFIG_MAKEFILE) +endif +export SDKCONFIG_MAKEFILE # sub-makes (like bootloader) will reuse this path + +ifdef IDF_VERSION_52 +GLOBAL_CFLAGS += \ + -DSOC_XTAL_FREQ_MHZ=CONFIG_XTAL_FREQ \ + -DSOC_MMU_PAGE_SIZE=CONFIG_MMU_PAGE_SIZE +endif + LIBDIRS += \ $(SDK_COMPONENT_LIBDIR) \ $(SDK_BUILD_BASE)/esp-idf/mbedtls/mbedtls/library \ @@ -65,13 +94,10 @@ LIBDIRS += \ SDK_INCDIRS := \ app_update/include \ bootloader_support/include \ - bootloader_support/include_bootloader \ - driver/$(ESP_VARIANT)/include \ driver/include \ esp_pm/include \ esp_rom/include/$(ESP_VARIANT) \ esp_rom/include \ - $(ESP_VARIANT)/include \ esp_ringbuf/include \ esp_timer/include \ soc/include \ @@ -82,7 +108,6 @@ SDK_INCDIRS := \ nvs_flash/include \ esp_event/include \ lwip/lwip/src/include \ - lwip/port/esp32/include \ newlib/platform_include \ spi_flash/include \ wpa_supplicant/include \ @@ -90,19 +115,37 @@ SDK_INCDIRS := \ esp_hw_support/include \ esp_hw_support/include/soc \ hal/include \ - hal/platform_port/include \ hal/$(ESP_VARIANT)/include \ esp_system/include \ esp_common/include \ esp_netif/include \ esp_eth/include \ esp_wifi/include \ + lwip/include/apps/sntp + +ifdef IDF_VERSION_4x +SDK_INCDIRS += \ + $(ESP_VARIANT)/include +endif + +ifdef IDF_VERSION_43 +SDK_INCDIRS += \ esp_wifi/esp32/include \ - lwip/include/apps/sntp \ wpa_supplicant/include/esp_supplicant +else +SDK_INCDIRS += \ + hal/platform_port/include +endif + +ifndef IDF_VERSION_52 +SDK_INCDIRS += \ + driver/$(ESP_VARIANT)/include \ + lwip/port/esp32/include +endif -ifdef IDF_VERSION_4 +ifdef IDF_VERSION_4x SDK_INCDIRS += \ + bootloader_support/include_bootloader \ esp_adc_cal/include \ esp_ipc/include \ freertos/include \ @@ -119,13 +162,29 @@ SDK_INCDIRS += \ freertos/esp_additions/include/freertos \ driver/deprecated FREERTOS_PORTABLE := freertos/FreeRTOS-Kernel/portable +ifeq (v5.2,$(IDF_VERSION)) +SDK_INCDIRS += \ + driver/gpio/include \ + driver/ledc/include \ + driver/spi/include \ + lwip/port/include \ + lwip/port/freertos/include \ + lwip/port/esp32xx/include \ + esp_bootloader_format/include \ + esp_adc/$(ESP_VARIANT)/include \ + freertos/config/include \ + freertos/config/include/freertos +endif endif - - ifeq ($(ENABLE_BLUETOOTH),1) +ifeq (esp32s3,$(ESP_VARIANT)) +ESP_BT_VARIANT := esp32c3 +else +ESP_BT_VARIANT := $(ESP_VARIANT) +endif SDK_INCDIRS += \ - bt/include/$(ESP_VARIANT)/include \ + bt/include/$(ESP_BT_VARIANT)/include \ bt/common/api/include/api \ bt/common/btc/profile/esp/blufi/include \ bt/common/btc/profile/esp/include \ @@ -148,17 +207,31 @@ SDK_INCDIRS += \ bt/host/nimble/nimble/nimble/host/store/config/include \ bt/host/nimble/esp-hci/include \ bt/host/nimble/port/include +ifdef IDF_VERSION_52 +SDK_INCDIRS += \ + bt/host/nimble/nimble/nimble/transport/include +endif endif ifdef IDF_TARGET_ARCH_RISCV SDK_INCDIRS += \ $(FREERTOS_PORTABLE)/riscv/include \ + $(FREERTOS_PORTABLE)/riscv/include/freertos \ + freertos/config/riscv \ + freertos/config/riscv/include \ riscv/include else SDK_INCDIRS += \ xtensa/include \ xtensa/$(ESP_VARIANT)/include \ - $(FREERTOS_PORTABLE)/xtensa/include + $(FREERTOS_PORTABLE)/xtensa/include \ + $(FREERTOS_PORTABLE)/xtensa/include/freertos +ifdef IDF_VERSION_52 +SDK_INCDIRS += \ + freertos/config/xtensa \ + freertos/config/xtensa/include \ + xtensa/deprecated_include +endif endif @@ -193,13 +266,13 @@ SDK_COMPONENTS := \ soc \ spi_flash -ifneq (,$(filter v4.3%,$(IDF_VERSION))) +ifdef IDF_VERSION_43 SDK_COMPONENTS += $(ESP_VARIANT) else SDK_COMPONENTS += esp_phy endif -ifdef IDF_VERSION_4 +ifdef IDF_VERSION_4x SDK_COMPONENTS += \ esp_ipc \ esp_adc_cal @@ -210,6 +283,12 @@ SDK_COMPONENTS += \ esp_partition endif +ifeq (v5.2,$(IDF_VERSION)) +SDK_COMPONENTS += \ + esp_mm \ + esp_coex +endif + ifneq ($(DISABLE_NETWORK),1) SDK_COMPONENTS += \ @@ -280,14 +359,12 @@ LDFLAGS_esp32 := \ $(call LinkerScript,rom.newlib-funcs) \ $(call LinkerScript,rom.newlib-data) \ $(call LinkerScript,rom.syscalls) \ - $(call LinkerScript,rom.newlib-time) \ $(call LinkerScript,rom.eco3) LDFLAGS_esp32s2 := \ $(call LinkerScript,rom.newlib-funcs) \ $(call LinkerScript,rom.newlib-data) \ - $(call LinkerScript,rom.spiflash) \ - $(call LinkerScript,rom.newlib-time) \ + $(call LinkerScript,rom.spiflash) LDFLAGS_esp32c3 := \ $(call LinkerScript,rom.newlib) \ @@ -296,13 +373,11 @@ LDFLAGS_esp32c3 := \ LDFLAGS_esp32s3 := \ $(call LinkerScript,rom.newlib) \ - $(call LinkerScript,rom.version) \ - $(call LinkerScript,rom.newlib-time) + $(call LinkerScript,rom.version) LDFLAGS_esp32c2 := \ $(call LinkerScript,rom.newlib) \ $(call LinkerScript,rom.version) \ - $(call LinkerScript,rom.newlib-time) \ $(call LinkerScript,rom.heap) \ $(call LinkerScript,rom.mbedtls) @@ -329,7 +404,7 @@ EXTRA_LDFLAGS := \ $(call Undef,$(SDK_UNDEF_SYMBOLS)) \ $(call Wrap,$(SDK_WRAP_SYMBOLS)) -ifneq (,$(filter v4.3%,$(IDF_VERSION))) +ifdef IDF_VERSION_43 EXTRA_LDFLAGS += \ -T $(ESP_VARIANT)_out.ld \ $(call LinkerScript,project) @@ -339,15 +414,6 @@ EXTRA_LDFLAGS += \ -T sections.ld endif -SDK_PROJECT_PATH := $(ESP32_COMPONENT_PATH)/project/$(ESP_VARIANT)/$(BUILD_TYPE) -SDK_CONFIG_DEFAULTS := $(SDK_PROJECT_PATH)/sdkconfig.defaults - -SDKCONFIG_MAKEFILE := $(SDK_PROJECT_PATH)/sdkconfig -ifeq ($(MAKE_DOCS),) --include $(SDKCONFIG_MAKEFILE) -endif -export SDKCONFIG_MAKEFILE # sub-makes (like bootloader) will reuse this path - FLASH_BOOT_LOADER := $(SDK_BUILD_BASE)/bootloader/bootloader.bin FLASH_BOOT_CHUNKS := $(CONFIG_BOOTLOADER_OFFSET_IN_FLASH)=$(FLASH_BOOT_LOADER) @@ -440,3 +506,8 @@ sdk-help: ##Get SDK build options .PHONY: sdk sdk: ##Pass options to IDF builder, e.g. `make sdk -- --help` or `make sdk menuconfig` $(Q) $(SDK_BUILD) $(filter-out sdk,$(MAKECMDGOALS)) + + +.PHONY: check-incdirs +check-incdirs: ##Check IDF include paths and report any not found in this SDK version + $(Q) $(foreach d,$(SDK_INCDIRS),$(if $(wildcard $(SDK_COMPONENTS_PATH)/$d),,$(info $d))) diff --git a/Sming/Arch/Esp32/Components/esp32/sdk/config/common b/Sming/Arch/Esp32/Components/esp32/sdk/config/common index c893597df9..e5b5711631 100644 --- a/Sming/Arch/Esp32/Components/esp32/sdk/config/common +++ b/Sming/Arch/Esp32/Components/esp32/sdk/config/common @@ -23,6 +23,11 @@ CONFIG_ETH_USE_SPI_ETHERNET=y CONFIG_ETH_SPI_ETHERNET_W5500=y CONFIG_ETH_SPI_ETHERNET_DM9051=y +# WiFi +CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=n +CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=n +CONFIG_ESP_WIFI_SOFTAP_SAW_SUPPORT=n + # Bluetooth CONFIG_BT_ENABLED=y CONFIG_BT_BLUEDROID_ENABLED=n @@ -53,5 +58,8 @@ CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n # Don't change provided flash configuration information CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=n -#' We'll handle WDT initialisation ourselves thankyouverymuch +# We'll handle WDT initialisation ourselves thankyouverymuch CONFIG_ESP_TASK_WDT_INIT=n + +# Issues with dual-core CPU, see #2653 +CONFIG_FREERTOS_UNICORE=y diff --git a/Sming/Arch/Esp32/Components/esp32/sdk/esp_system.mk b/Sming/Arch/Esp32/Components/esp32/sdk/esp_system.mk index 1d7f1f8726..ec7f205e94 100644 --- a/Sming/Arch/Esp32/Components/esp32/sdk/esp_system.mk +++ b/Sming/Arch/Esp32/Components/esp32/sdk/esp_system.mk @@ -16,3 +16,6 @@ endif # linker will ignore panic_highint_hdl.S as it has no other files depending on any # symbols in it. SDK_UNDEF_SYMBOLS += ld_include_panic_highint_hdl + +# IDF 5.2 +SDK_WRAP_SYMBOLS += esp_newlib_init_global_stdio diff --git a/Sming/Arch/Esp32/Components/esp32/sdk/pthread.mk b/Sming/Arch/Esp32/Components/esp32/sdk/pthread.mk index c24e62cb1e..77f07fc36a 100644 --- a/Sming/Arch/Esp32/Components/esp32/sdk/pthread.mk +++ b/Sming/Arch/Esp32/Components/esp32/sdk/pthread.mk @@ -4,7 +4,10 @@ SDK_UNDEF_SYMBOLS += \ pthread_include_pthread_impl \ pthread_include_pthread_cond_impl \ - pthread_include_pthread_local_storage_impl + pthread_include_pthread_cond_var_impl \ + pthread_include_pthread_local_storage_impl \ + pthread_include_pthread_rwlock_impl \ + pthread_include_pthread_semaphore_impl ifdef CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP SDK_WRAP_SYMBOLS += vPortCleanUpTCB diff --git a/Sming/Arch/Esp32/Components/esp32/sdk/soc.mk b/Sming/Arch/Esp32/Components/esp32/sdk/soc.mk new file mode 100644 index 0000000000..276e5f6138 --- /dev/null +++ b/Sming/Arch/Esp32/Components/esp32/sdk/soc.mk @@ -0,0 +1,8 @@ +# +# soc +# + +ifeq (esp32,$(SMING_SOC)) + SDK_UNDEF_SYMBOLS += \ + esp_dport_access_reg_read +endif diff --git a/Sming/Arch/Esp32/Components/esp32/src/clk.c b/Sming/Arch/Esp32/Components/esp32/src/clk.c index 724f3def0e..5ca017c93a 100644 --- a/Sming/Arch/Esp32/Components/esp32/src/clk.c +++ b/Sming/Arch/Esp32/Components/esp32/src/clk.c @@ -2,10 +2,12 @@ #include #include +#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 2, 0) #define EXPAND(a) a #define CONCAT3a(a, b, c) a##b##c #define CONCAT3(a, b, c) CONCAT3a(a, b, c) -typedef CONCAT3(esp_pm_config_, SMING_SOC, _t) pm_config_t; +typedef CONCAT3(esp_pm_config_, SMING_SOC, _t) esp_pm_config_t; +#endif int esp_clk_cpu_freq(void); @@ -13,11 +15,11 @@ static esp_pm_lock_handle_t handle; bool system_update_cpu_freq(uint32_t freq) { - pm_config_t config = {}; + esp_pm_config_t config = {}; esp_err_t err = esp_pm_get_configuration(&config); if(err != ESP_OK) { debug_e("[PM] Failed to read PM config %u", err); - } else if(config.max_freq_mhz == freq) { + } else if((unsigned)config.max_freq_mhz == freq) { return true; } diff --git a/Sming/Arch/Esp32/Components/esp32/src/include/esp_clk.h b/Sming/Arch/Esp32/Components/esp32/src/include/esp_clk.h index 8579d2d67e..acf627a4e7 100644 --- a/Sming/Arch/Esp32/Components/esp32/src/include/esp_clk.h +++ b/Sming/Arch/Esp32/Components/esp32/src/include/esp_clk.h @@ -1,7 +1,11 @@ #pragma once #include +#if ESP_IDF_VERSION_MAJOR < 5 #include +#else +#include +#endif #include #include diff --git a/Sming/Arch/Esp32/Components/esp32/src/include/esp_event.h b/Sming/Arch/Esp32/Components/esp32/src/include/esp_event.h new file mode 100644 index 0000000000..c8d181404a --- /dev/null +++ b/Sming/Arch/Esp32/Components/esp32/src/include/esp_event.h @@ -0,0 +1,8 @@ +#pragma once + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include_next + +#pragma GCC diagnostic pop diff --git a/Sming/Arch/Esp32/Components/esp32/src/include/esp_systemapi.h b/Sming/Arch/Esp32/Components/esp32/src/include/esp_systemapi.h index 3637e3074a..4795d23f0a 100644 --- a/Sming/Arch/Esp32/Components/esp32/src/include/esp_systemapi.h +++ b/Sming/Arch/Esp32/Components/esp32/src/include/esp_systemapi.h @@ -23,12 +23,15 @@ #include "esp_tasks.h" #include #include -#include #include #include #include +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#include #include #include +#pragma GCC diagnostic pop #include #include diff --git a/Sming/Arch/Esp32/Components/esp32/src/include/esp_task.h b/Sming/Arch/Esp32/Components/esp32/src/include/esp_task.h new file mode 100644 index 0000000000..8075d25be0 --- /dev/null +++ b/Sming/Arch/Esp32/Components/esp32/src/include/esp_task.h @@ -0,0 +1,8 @@ +#pragma once + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include_next + +#pragma GCC diagnostic pop diff --git a/Sming/Arch/Esp32/Components/esp32/src/include/esp_task_wdt.h b/Sming/Arch/Esp32/Components/esp32/src/include/esp_task_wdt.h new file mode 100644 index 0000000000..2e75b237d5 --- /dev/null +++ b/Sming/Arch/Esp32/Components/esp32/src/include/esp_task_wdt.h @@ -0,0 +1,8 @@ +#pragma once + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include_next + +#pragma GCC diagnostic pop diff --git a/Sming/Arch/Esp32/Components/esp32/src/include/hal/gpio_ll.h b/Sming/Arch/Esp32/Components/esp32/src/include/hal/gpio_ll.h new file mode 100644 index 0000000000..d0331b31bf --- /dev/null +++ b/Sming/Arch/Esp32/Components/esp32/src/include/hal/gpio_ll.h @@ -0,0 +1,8 @@ +#pragma once + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#include_next + +#pragma GCC diagnostic pop diff --git a/Sming/Arch/Esp32/Components/esp32/src/startup.cpp b/Sming/Arch/Esp32/Components/esp32/src/startup.cpp index 47ea3f00f2..5ea2d72358 100644 --- a/Sming/Arch/Esp32/Components/esp32/src/startup.cpp +++ b/Sming/Arch/Esp32/Components/esp32/src/startup.cpp @@ -71,6 +71,10 @@ void main(void*) } // namespace +extern "C" void __wrap_esp_newlib_init_global_stdio(const char*) +{ +} + extern void sming_create_task(TaskFunction_t); extern "C" void app_main(void) diff --git a/Sming/Arch/Esp32/Components/esp32/src/system.cpp b/Sming/Arch/Esp32/Components/esp32/src/system.cpp index a3d3607e0b..a13039592f 100644 --- a/Sming/Arch/Esp32/Components/esp32/src/system.cpp +++ b/Sming/Arch/Esp32/Components/esp32/src/system.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include diff --git a/Sming/Arch/Esp32/Components/esp32/src/tasks.cpp b/Sming/Arch/Esp32/Components/esp32/src/tasks.cpp index 579275c86b..c265a30a94 100644 --- a/Sming/Arch/Esp32/Components/esp32/src/tasks.cpp +++ b/Sming/Arch/Esp32/Components/esp32/src/tasks.cpp @@ -10,9 +10,9 @@ os_task_t taskCallback; } // namespace -bool system_os_task(os_task_t callback, uint8_t prio, os_event_t* events, uint8_t qlen) +bool system_os_task(os_task_t callback, uint8_t prio, os_event_t*, uint8_t) { - auto handler = [](void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { + auto handler = [](void*, esp_event_base_t, int32_t event_id, void* event_data) { assert(taskCallback != nullptr); os_event_t ev{os_signal_t(event_id), 0}; diff --git a/Sming/Arch/Esp32/Components/gdbstub/README.rst b/Sming/Arch/Esp32/Components/gdbstub/README.rst index fc316ca478..9c0c4b7c7a 100644 --- a/Sming/Arch/Esp32/Components/gdbstub/README.rst +++ b/Sming/Arch/Esp32/Components/gdbstub/README.rst @@ -3,6 +3,4 @@ GDB Stub for Esp32 This defines the command line to use when ``make gdb`` is run. -Esp32 debugging is handled via JTAG interface. - -No additional code is required as serial debugging is not (currently) implemented. +See :doc:`/debugging/esp32/index`. diff --git a/Sming/Arch/Esp32/Components/gdbstub/gdbstub.c b/Sming/Arch/Esp32/Components/gdbstub/gdbstub.c index 4b22298076..1007759c86 100644 --- a/Sming/Arch/Esp32/Components/gdbstub/gdbstub.c +++ b/Sming/Arch/Esp32/Components/gdbstub/gdbstub.c @@ -17,13 +17,7 @@ void gdb_detach(void) { } - - unsigned __gdb_no_op(void) { return 0; } - -//#define NOOP __attribute__((weak, alias("__gdb_no_op"))) -// -//void gdb_on_attach(bool attached) NOOP; diff --git a/Sming/Arch/Esp32/Components/heap/README.rst b/Sming/Arch/Esp32/Components/heap/README.rst index a8ea0dac75..ce07f0d8f0 100644 --- a/Sming/Arch/Esp32/Components/heap/README.rst +++ b/Sming/Arch/Esp32/Components/heap/README.rst @@ -1,12 +1,4 @@ -Heap -==== +Esp32 Heap +========== -This Component implements heap-related housekeeping functions. Heap usage is tracked using :component:`malloc_count`. -This also provides some validation (using *sentinels* to detect if memory blocks are overwritten). - -.. envvar:: ENABLE_MALLOC_COUNT - - We require :component:`malloc_count` to keep track of heap usage for system_get_free_heap_size(). - It does this by hooking the memory allocation routines (malloc, free, etc.). - If you wish to disable this behaviour, set `ENABLE_MALLOC_COUNT=0`. - If using tools such as `Valgrind `__, this will provide a cleaner trace. +This Component supplements the actual heap implementation provided by the ESP IDF SDK. diff --git a/Sming/Arch/Esp32/Components/libc/src/include/sys/pgmspace.h b/Sming/Arch/Esp32/Components/libc/src/include/sys/pgmspace.h index a2c3294ebe..3a103d4a86 100644 --- a/Sming/Arch/Esp32/Components/libc/src/include/sys/pgmspace.h +++ b/Sming/Arch/Esp32/Components/libc/src/include/sys/pgmspace.h @@ -63,17 +63,17 @@ extern "C" { #define pgm_read_dword_far(addr) pgm_read_dword(addr) #define pgm_read_float_far(addr) pgm_read_float(addr) -#define memcpy_P(dest, src, num) memcpy(dest, src, num) -#define memcmp_P(a1, b1, len) memcmp(a1, b1, len) -#define strlen_P(a) strlen(a) -#define strcpy_P(dest, src) strcpy(dest, src) -#define strncpy_P(dest, src, size) strncpy(dest, src, size) -#define strcmp_P(a, b) strcmp(a, b) +#define memcpy_P(dest, src_P, num) memcpy(dest, src_P, num) +#define memcmp_P(buf1, buf2_P, len) memcmp(buf1, buf2_P, len) +#define strlen_P(str_P) strlen(str_P) +#define strcpy_P(dest, src_P) strcpy(dest, src_P) +#define strncpy_P(dest, src_P, size) strncpy(dest, src_P, size) +#define strcmp_P(str1, str2_P) strcmp(str1, str2_P) #define strncmp_P(str1, str2_P, size) strncmp(str1, str2_P, size) -#define strcasecmp_P(a, b) strcasecmp(a, b) -#define strcat_P(dest, src) strcat(dest, src) -#define strstr_P(a, b) strstr(a, b) -#define sprintf_P(s, f, ...) m_snprintf(s, 1024, f, ##__VA_ARGS__) +#define strcasecmp_P(str1, str2_P) strcasecmp(str1, str2_P) +#define strcat_P(dest, src_P) strcat(dest, src_P) +#define strstr_P(haystack, needle_P) strstr(haystack, needle_P) +#define sprintf_P(str, format_P, ...) m_snprintf(str, 1024, format_P, ##__VA_ARGS__) #ifdef __cplusplus } diff --git a/Sming/Arch/Esp32/Components/sming-arch/README.rst b/Sming/Arch/Esp32/Components/sming-arch/README.rst index 0b6d606f73..e91d1c0038 100644 --- a/Sming/Arch/Esp32/Components/sming-arch/README.rst +++ b/Sming/Arch/Esp32/Components/sming-arch/README.rst @@ -3,16 +3,3 @@ Sming (Esp32) This Component builds a library containing architecture-specific code, and defines dependencies for Sming to build for the Esp32. -Interactive debugging on the device ------------------------------------ - -.. envvar:: ENABLE_GDB - - In order to be able to debug live directly on the ESP8266 microcontroller you - should re-compile your application with ``ENABLE_GDB=1`` directive. - - undefined (default) - Compile normally - 1 - Compile with debugging support provided by :component-esp8266:`gdbstub`. - See also the :sample:`LiveDebug` sample. diff --git a/Sming/Arch/Esp32/Components/spi_flash/README.rst b/Sming/Arch/Esp32/Components/spi_flash/README.rst index 31b49e646b..56e9495129 100644 --- a/Sming/Arch/Esp32/Components/spi_flash/README.rst +++ b/Sming/Arch/Esp32/Components/spi_flash/README.rst @@ -1,4 +1,4 @@ -Esp8266 SPI Flash Support +Esp32 SPI Flash Support ========================= Provides functions for access to flash memory. diff --git a/Sming/Arch/Esp32/Components/spi_flash/flashmem.cpp b/Sming/Arch/Esp32/Components/spi_flash/flashmem.cpp index 0ae47b5c9c..87791b92a0 100644 --- a/Sming/Arch/Esp32/Components/spi_flash/flashmem.cpp +++ b/Sming/Arch/Esp32/Components/spi_flash/flashmem.cpp @@ -16,7 +16,7 @@ #include #include -uint32_t flashmem_write(const void* from, uint32_t toaddr, uint32_t size) +uint32_t flashmem_write(const void* from, flash_addr_t toaddr, uint32_t size) { esp_err_t r = esp_flash_write(esp_flash_default_chip, from, toaddr, size); if(r != ESP_OK) { @@ -27,7 +27,7 @@ uint32_t flashmem_write(const void* from, uint32_t toaddr, uint32_t size) return size; } -uint32_t flashmem_read(void* to, uint32_t fromaddr, uint32_t size) +uint32_t flashmem_read(void* to, flash_addr_t fromaddr, uint32_t size) { esp_err_t r = esp_flash_read(esp_flash_default_chip, to, fromaddr, size); if(r != ESP_OK) { @@ -38,7 +38,7 @@ uint32_t flashmem_read(void* to, uint32_t fromaddr, uint32_t size) return size; } -bool flashmem_erase_sector(uint32_t sector_id) +bool flashmem_erase_sector(flash_sector_t sector_id) { esp_task_wdt_reset(); @@ -61,36 +61,20 @@ SPIFlashInfo flashmem_get_info() return info; } -uint8_t flashmem_get_size_type() +SPIFlashSize flashmem_get_size_type() { return flashmem_get_info().size; } -uint32_t flashmem_get_size_bytes() +flash_addr_t flashmem_get_size_bytes() { return g_rom_flashchip.chip_size; } -uint16_t flashmem_get_size_sectors() +flash_addr_t flashmem_get_address(const void* memptr) { - return flashmem_get_size_bytes() / SPI_FLASH_SEC_SIZE; -} - -uint32_t flashmem_find_sector(uint32_t address, uint32_t* pstart, uint32_t* pend) -{ - // All the sectors in the flash have the same size, so just align the address - uint32_t sect_id = address / INTERNAL_FLASH_SECTOR_SIZE; - - if(pstart) - *pstart = sect_id * INTERNAL_FLASH_SECTOR_SIZE; - if(pend) - *pend = (sect_id + 1) * INTERNAL_FLASH_SECTOR_SIZE - 1; - return sect_id; -} - -uint32_t flashmem_get_sector_of_address(uint32_t addr) -{ - return flashmem_find_sector(addr, NULL, NULL); + auto phys = spi_flash_cache2phys(memptr); + return (phys == SPI_FLASH_CACHE2PHYS_FAIL) ? 0 : phys; } uint32_t spi_flash_get_id(void) diff --git a/Sming/Arch/Esp32/Components/spi_flash/include/esp_spi_flash.h b/Sming/Arch/Esp32/Components/spi_flash/include/esp_spi_flash.h index 439bd344ee..156de935d1 100644 --- a/Sming/Arch/Esp32/Components/spi_flash/include/esp_spi_flash.h +++ b/Sming/Arch/Esp32/Components/spi_flash/include/esp_spi_flash.h @@ -24,25 +24,7 @@ extern "C" { #endif -/** - * @defgroup flash Flash Memory Support - * @defgroup spi_flash SPI Flash API - * @ingroup flash - * @{ - */ - -/// Flash memory access must be aligned and in multiples of 4-byte words -#define INTERNAL_FLASH_WRITE_UNIT_SIZE 4 -#define INTERNAL_FLASH_READ_UNIT_SIZE 4 - -#define FLASH_TOTAL_SEC_COUNT (flashmem_get_size_sectors()) - -/// Number of flash sectors reserved for system parameters at start -#define SYS_PARAM_SEC_COUNT 4 -#define FLASH_WORK_SEC_COUNT (FLASH_TOTAL_SEC_COUNT - SYS_PARAM_SEC_COUNT) - #define INTERNAL_FLASH_SECTOR_SIZE SPI_FLASH_SEC_SIZE -#define INTERNAL_FLASH_SIZE ((FLASH_WORK_SEC_COUNT)*INTERNAL_FLASH_SECTOR_SIZE) typedef enum { MODE_QIO = ESP_IMAGE_SPI_MODE_QIO, @@ -69,96 +51,8 @@ typedef enum { SIZE_32MBIT = 0xFF, ///< Not listed } SPIFlashSize; -/** - * @brief SPI Flash memory information block. - * Copied from bootloader header. - * See `esp_image_header_t`. - */ -typedef struct { - SPIFlashMode mode; - SPIFlashSpeed speed; - SPIFlashSize size; -} SPIFlashInfo; - -/** @brief Obtain the flash memory address for a memory pointer - * @param memptr - * @retval uint32_t Offset from start of flash memory - * @note If memptr is not in valid flash memory it will return an offset which exceeds - * the internal flash memory size. - * @note The flash location is dependent on where rBoot has mapped the firmware. - */ -static inline uint32_t flashmem_get_address(const void* memptr) -{ - auto phys = spi_flash_cache2phys(memptr); - return (phys == SPI_FLASH_CACHE2PHYS_FAIL) ? 0 : phys; -} - -/** @brief Write a block of data to flash - * @param from Buffer to obtain data from - * @param toaddr Flash location to start writing - * @param size Number of bytes to write - * @retval uint32_t Number of bytes written - * @note None of the parameters need to be aligned - */ -uint32_t flashmem_write(const void* from, uint32_t toaddr, uint32_t size); - -/** @brief Read a block of data from flash - * @param to Buffer to store data - * @param fromaddr Flash location to start reading - * @param size Number of bytes to read - * @retval uint32_t Number of bytes written - * @note none of the parameters need to be aligned - */ -uint32_t flashmem_read(void* to, uint32_t fromaddr, uint32_t size); - -/** @brief Erase a single flash sector - * @param sector_id the sector to erase - * @retval true on success - */ -bool flashmem_erase_sector(uint32_t sector_id); - -/** @brief Get flash memory information block - * @retval SPIFlashInfo Information block - */ -SPIFlashInfo flashmem_get_info(); - -/** @brief Returns a number indicating the size of flash memory chip - * @retval uint8_t See SpiFlashInfo.size field for possible values - */ -uint8_t flashmem_get_size_type(); - -/** @brief get the total flash memory size - * @retval uint32_t Size in bytes - */ -uint32_t flashmem_get_size_bytes(); - -/** @brief Get the total number of flash sectors - * @retval uint16_t Sector count - */ -uint16_t flashmem_get_size_sectors(); - -/** @brief Helper function: find the flash sector in which an address resides - * @param address - * @param pstart OUT/OPTIONAL: Start of sector containing the given address - * @param pend OUT/OPTIONAL: Last address in sector - * @retval uint32_t Sector number for the given address - * @note Optional parameters may be null - */ -uint32_t flashmem_find_sector(uint32_t address, uint32_t* pstart, uint32_t* pend); - -/** @brief Get sector number containing the given address - * @param addr - * @retval uint32_t sector number - */ -uint32_t flashmem_get_sector_of_address(uint32_t addr); - -/* - * @brief Get unique 32-bit flash identification code - */ -uint32_t spi_flash_get_id(void); - -/** @} */ - #ifdef __cplusplus } #endif + +#include diff --git a/Sming/Arch/Esp32/Core/Digital.cpp b/Sming/Arch/Esp32/Core/Digital.cpp index b5c694018f..48015d79f3 100644 --- a/Sming/Arch/Esp32/Core/Digital.cpp +++ b/Sming/Arch/Esp32/Core/Digital.cpp @@ -15,6 +15,10 @@ #include #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED #include +#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 2, 0) +#define RTCIO_LL_FUNC_RTC RTCIO_FUNC_RTC +#define RTCIO_LL_FUNC_DIGITAL RTCIO_FUNC_DIGITAL +#endif #endif void pinMode(uint16_t pin, uint8_t mode) @@ -38,7 +42,7 @@ void pinMode(uint16_t pin, uint8_t mode) return; // Already in ADC mode } - rtcio_ll_function_select(rtc, RTCIO_FUNC_RTC); + rtcio_ll_function_select(rtc, RTCIO_LL_FUNC_RTC); rtcio_ll_input_disable(rtc); rtcio_ll_output_disable(rtc); rtcio_ll_pullup_disable(rtc); @@ -48,7 +52,7 @@ void pinMode(uint16_t pin, uint8_t mode) } if(rtc >= 0) { - rtcio_ll_function_select(rtc, RTCIO_FUNC_DIGITAL); + rtcio_ll_function_select(rtc, RTCIO_LL_FUNC_DIGITAL); rtcio_ll_pulldown_disable(rtc); if(mode == INPUT_PULLUP) { rtcio_ll_pullup_enable(rtc); diff --git a/Sming/Arch/Esp32/Core/Interrupts.cpp b/Sming/Arch/Esp32/Core/Interrupts.cpp index 280addb4bf..889a39219f 100644 --- a/Sming/Arch/Esp32/Core/Interrupts.cpp +++ b/Sming/Arch/Esp32/Core/Interrupts.cpp @@ -89,7 +89,7 @@ void attachInterrupt(uint8_t pin, InterruptDelegate delegateFunction, GPIO_INT_T return; // WTF o_O } gpioInterruptsList[pin] = nullptr; - delegateFunctionList[pin] = delegateFunction; + delegateFunctionList[pin] = std::move(delegateFunction); attachInterruptHandler(pin, type); } diff --git a/Sming/Arch/Esp32/Platform/RTC.cpp b/Sming/Arch/Esp32/Platform/RTC.cpp index b5b721f806..1913a9c4ab 100644 --- a/Sming/Arch/Esp32/Platform/RTC.cpp +++ b/Sming/Arch/Esp32/Platform/RTC.cpp @@ -9,6 +9,7 @@ ****/ #include +#include // #include extern "C" uint64_t esp_clk_rtc_time(void); @@ -23,9 +24,7 @@ uint64_t clockOffset; } // namespace -RtcClass::RtcClass() -{ -} +RtcClass::RtcClass() = default; uint64_t RtcClass::getRtcNanoseconds() { @@ -45,5 +44,10 @@ bool RtcClass::setRtcNanoseconds(uint64_t nanoseconds) bool RtcClass::setRtcSeconds(uint32_t seconds) { + struct timeval tv { + seconds + }; + settimeofday(&tv, nullptr); + return setRtcNanoseconds(uint64_t(seconds) * NS_PER_SECOND); } diff --git a/Sming/Arch/Esp32/README.rst b/Sming/Arch/Esp32/README.rst index bf575ce212..da97dc290f 100644 --- a/Sming/Arch/Esp32/README.rst +++ b/Sming/Arch/Esp32/README.rst @@ -6,13 +6,21 @@ Sming Esp32 Architecture Support building Sming for the Esp32 architecture. -Build variables ---------------- +Configuration Variables +----------------------- .. envvar:: IDF_PATH - This contains the base directory for the ESP-IDF toolchain used to build the framework. This variable is required and must be set accordingly. + Required. The full path to the ESP-IDF framework. + The standard location for this is ``/opt/esp-idf`` or ``C:\tools\esp-idf``, + which is a link to the versioned directory such as ``/opt/esp-idf-5.2``. + You can switch between installed versions by changing the link, + or by changing IDF_PATH. + +.. envvar:: IDF_TOOLS_PATH + + Required. The full path to the Esp32 tools directory, such as ``/opt/esp32``. .. envvar:: SDK_CUSTOM_CONFIG @@ -28,12 +36,12 @@ Build variables Requirements ------------ -In order to be able to compile for the ESP32 architecture you should have ESP-IDF v4.3 installed. -Some slight changes are required to enable code to compile correctly for C++, -so a fork has been created here https://github.com/mikee47/esp-idf/tree/sming/release/v4.3 -which you may clone. +Sming requires a slightly modified version of the Espressif SDK. +You can find the SDK here https://github.com/mikee47/esp-idf/tree/sming/release/v5.2. +See `idf_versions`_ below for further details. -The Sming installers do all this for you - see :doc:`/getting-started/index`. +Using the Sming installation scripts are the recommended way to install these SDK versions. +See :doc:`/getting-started/index`. You can find further details in the `ESP-IDF documentation `__. @@ -43,11 +51,15 @@ Building Make sure that the :envvar:`IDF_PATH` is set. Also make sure that the other ESP-IDF environmental variables are set. -In Linux this can be done using the following command:: +In Linux/MacOS this can be done using the following command:: source $SMING_HOME/Tools/export.sh -Build the framework and application as usual, specifying :envvar:`SMING_ARCH` =Esp32. For example:: +For Windows:: + + $SMING_HOME\Tools\export + +Build the framework and application as usual, specifying :envvar:`SMING_ARCH=Esp32 `. For example:: cd $SMING_HOME/../samples/Basic_Serial make SMING_ARCH=Esp32 @@ -63,15 +75,15 @@ SDK Sming comes with pre-compiled libraries and configuration files. If needed you can re-configure ESP-IDF using the command below:: - make SMING_ARCH=Esp32 sdk-menuconfig + make sdk-menuconfig -A re-compilation is required after the change of the configuration. This can be done with the following command:: +A re-compilation is required after the change of the configuration thus:: - make SMING_ARCH=Esp32 Sming-build all + make Sming-build all -If you want to revert to using the default SDK settings then issue the following command:: +If you want to revert to using the default SDK settings:: - make SMING_ARCH=Esp32 sdk-config-clean + make sdk-config-clean You can also configure per-project custom settings via :envvar:`SDK_CUSTOM_CONFIG`. @@ -79,49 +91,49 @@ You can also configure per-project custom settings via :envvar:`SDK_CUSTOM_CONFI SoC variants ------------ -Sming leverages the `ESP IDF HAL `__ +Sming leverages the `ESP IDF HAL `__ to support multiple processor variants. -This is still at an early stage of development however basic applications should build for the following variants: +A family of SoCs is supported, currently:: -- esp32 (default) +- esp32 - esp32s2 - esp32c3 - esp32s3 - esp32c2 -You can change variants like this: +You can change variants like this:: -``` -make SMING_SOC=esp32c3 -``` + make SMING_SOC=esp32c3 -Each variant uses a different build directory, e.g. ``out/Esp32/esp32c3/...`` to avoid conflicts. +Each variant uses a different build directory, e.g. ``out/Esp32/esp32c3/...``. See :component-esp32:`esp32` for further details. +.. _idf_versions: + IDF versions ------------ -Sming currently supports IDF versions 4.3, 4.4 and 5.0. +Sming currently supports IDF versions 4.3, 4.4, 5.0 and 5.2. +The recommended version is 5.2. +This is installed by default. -The default installed IDF version is 4.4. This can be changed as follows:: +A different version can be installed if necessary:: - INSTALL_IDF_VER=5.0 $SMING_HOME/../Tools/install.sh esp32 + INSTALL_IDF_VER=4.4 $SMING_HOME/../Tools/install.sh esp32 The installation script creates a soft-link in ``/opt/esp-idf`` pointing to the last version installed. Use the `IDF_PATH` environment variable or change the soft-link to select which one to use. -After switching versions, run `make clean components-clean` before re-compiling. - -.. note:: +After switching versions, run a full clean before re-compiling. +This must include SDK configuration:: - Currently, switching from version 4.x to 5.0 or vice-versa requires an additional step - as they use different versions of the 'pyparsing' Python library. + make sdk-config-clean clean components-clean - If moving from IDF 4.x to 5.0: ``python -m pip install --upgrade pyparsing`` - Moving from IDF 5.0 to 4.x: ``python -m pip install 'pyparsing<2.4'`` +See `ESP-IDF Versions `__ +for the IDF release schedule. Components diff --git a/Sming/Arch/Esp32/Services/Profiling/TaskStat.cpp b/Sming/Arch/Esp32/Services/Profiling/TaskStat.cpp index 97a69e98db..ddc127cd17 100644 --- a/Sming/Arch/Esp32/Services/Profiling/TaskStat.cpp +++ b/Sming/Arch/Esp32/Services/Profiling/TaskStat.cpp @@ -9,8 +9,11 @@ */ #include +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#pragma GCC diagnostic pop #include #include @@ -27,13 +30,11 @@ struct TaskStat::Info { TaskStat::TaskStat(Print& out) : out(out) { #if CONFIG_FREERTOS_USE_TRACE_FACILITY && CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS - taskInfo.reset(new Info[2]); + taskInfo = std::make_unique(2); #endif } -TaskStat::~TaskStat() -{ -} +TaskStat::~TaskStat() = default; bool TaskStat::update() { diff --git a/Sming/Arch/Esp32/Tools/ci/build.run.cmd b/Sming/Arch/Esp32/Tools/ci/build.run.cmd index 78de751535..b1d9c8d08e 100644 --- a/Sming/Arch/Esp32/Tools/ci/build.run.cmd +++ b/Sming/Arch/Esp32/Tools/ci/build.run.cmd @@ -1,7 +1,7 @@ REM Esp32 build.run.cmd %MAKE_PARALLEL% Basic_Blink Basic_Ethernet Basic_WiFi HttpServer_ConfigNetwork DEBUG_VERBOSE_LEVEL=3 STRICT=1 || goto :error -%MAKE_PARALLEL% Basic_Ssl ENABLE_SSL=Bearssl DEBUG_VERBOSE_LEVEL=3 STRICT=1 || goto :error +%MAKE_PARALLEL% Basic_Ssl ENABLE_SSL=Axtls DEBUG_VERBOSE_LEVEL=3 STRICT=1 || goto :error REM make sure that the Ota Library sample compiles for ESP32 %MAKE_PARALLEL% -C %SMING_HOME%\Libraries\OtaUpgradeMqtt\samples\Upgrade diff --git a/Sming/Arch/Esp32/Tools/idf_tools-4.3.lst b/Sming/Arch/Esp32/Tools/idf_tools-4.3.lst new file mode 100644 index 0000000000..8b49fd1b38 --- /dev/null +++ b/Sming/Arch/Esp32/Tools/idf_tools-4.3.lst @@ -0,0 +1,7 @@ +xtensa-esp32-elf +xtensa-esp32s2-elf +xtensa-esp32s3-elf +riscv32-esp-elf +esp32ulp-elf +esp32s2ulp-elf +openocd-esp32 diff --git a/Sming/Arch/Esp32/Tools/idf_tools-4.4.lst b/Sming/Arch/Esp32/Tools/idf_tools-4.4.lst new file mode 100644 index 0000000000..d0ea4bf7b2 --- /dev/null +++ b/Sming/Arch/Esp32/Tools/idf_tools-4.4.lst @@ -0,0 +1,8 @@ +xtensa-esp32-elf +xtensa-esp32s2-elf +xtensa-esp32s3-elf +riscv32-esp-elf +esp32ulp-elf +xtensa-esp-elf-gdb +riscv32-esp-elf-gdb +openocd-esp32 diff --git a/Sming/Arch/Esp32/Tools/idf_tools-5.0.lst b/Sming/Arch/Esp32/Tools/idf_tools-5.0.lst new file mode 100644 index 0000000000..33c5dcb00b --- /dev/null +++ b/Sming/Arch/Esp32/Tools/idf_tools-5.0.lst @@ -0,0 +1,9 @@ +xtensa-esp-elf-gdb +riscv32-esp-elf-gdb +xtensa-esp32-elf +xtensa-esp32s2-elf +xtensa-esp32s3-elf +riscv32-esp-elf +esp32ulp-elf +esp-rom-elfs +openocd-esp32 diff --git a/Sming/Arch/Esp32/Tools/idf_tools-5.2.lst b/Sming/Arch/Esp32/Tools/idf_tools-5.2.lst new file mode 100644 index 0000000000..e121b28480 --- /dev/null +++ b/Sming/Arch/Esp32/Tools/idf_tools-5.2.lst @@ -0,0 +1,7 @@ +xtensa-esp-elf-gdb +riscv32-esp-elf-gdb +xtensa-esp-elf +riscv32-esp-elf +esp32ulp-elf +esp-rom-elfs +openocd-esp32 diff --git a/Sming/Arch/Esp32/Tools/idf_tools.py b/Sming/Arch/Esp32/Tools/idf_tools.py index 8001e98652..38837cd032 100644 --- a/Sming/Arch/Esp32/Tools/idf_tools.py +++ b/Sming/Arch/Esp32/Tools/idf_tools.py @@ -9,19 +9,23 @@ def get_tool_info(soc): compiler_prefix = None compiler_version = None + gcc_path = gdb_path = None for tool in tools_info['tools']: - if soc in tool['supported_targets']: - desc = tool['description'] - if desc.startswith('Toolchain'): - compiler_prefix = tool['name'] - compiler_version = tool['versions'][0]['name'] - break - print(f"{compiler_prefix} {compiler_version}") - - # ESP32_COMPILER_PREFIX=compiler_prefix - # IDF_TARGET_ARCH_RISCV=is_riscv - - + if tool.get('install') != 'always': + continue + if soc not in tool['supported_targets']: + continue + desc = tool['description'].lower() + export_path = "/".join(tool['export_paths'][0]) + tool_name = tool['name'] + tool_version = tool['versions'][0]['name'] + path = f"{tool_name}/{tool_version}/{export_path}" + if 'gcc' in desc and not gcc_path: + gcc_path = path + if 'gdb' in desc and not gdb_path: + gdb_path = path + + print(gcc_path, gdb_path) if __name__ == '__main__': diff --git a/Sming/Arch/Esp32/Tools/install.cmd b/Sming/Arch/Esp32/Tools/install.cmd index 9f0122949b..8e8b5b42c6 100644 --- a/Sming/Arch/Esp32/Tools/install.cmd +++ b/Sming/Arch/Esp32/Tools/install.cmd @@ -1,19 +1,66 @@ REM Esp32 install.cmd -if "%IDF_PATH%"=="" goto :EOF -if "%IDF_TOOLS_PATH%"=="" goto :EOF +if "%IDF_PATH%"=="" goto :undefined +if "%IDF_TOOLS_PATH%"=="" goto :undefined + +if "%INSTALL_IDF_VER%"=="" set INSTALL_IDF_VER=5.2 + +echo. +echo ** Installing Esp32 IDF version %INSTALL_IDF_VER% +echo. + +for %%I in (%IDF_PATH%) do set IDF_CLONE_PATH=%%~dpIesp-idf-%INSTALL_IDF_VER% + +if exist "%IDF_CLONE_PATH%" goto :cloned if "%IDF_REPO%"=="" set IDF_REPO="https://github.com/mikee47/esp-idf.git" -if "%INSTALL_IDF_VER%"=="" set INSTALL_IDF_VER=4.4 set IDF_BRANCH="sming/release/v%INSTALL_IDF_VER%" -git clone -b %IDF_BRANCH% %IDF_REPO% %IDF_PATH% +if "%CI_BUILD_DIR%" NEQ "" ( + set IDF_INSTALL_OPTIONS=--depth 1 --recurse-submodules --shallow-submodules +) +git clone -b %IDF_BRANCH% %IDF_REPO% %IDF_CLONE_PATH% %IDF_INSTALL_OPTIONS% +if errorlevel 1 goto :EOF + +goto :setup + + +:undefined +echo. +echo ** Cannot install Esp32 tools: IDF_PATH or IDF_TOOLS_PATH not defined +echo. +goto :EOF + + +:cloned +echo. +echo ** Skipping ESP-IDF clone: '%IDF_CLONE_PATH%' exists +echo. +goto :setup + + +:setup + +@echo Create link from "%IDF_PATH%" to "%IDF_CLONE_PATH%" +if exist "%IDF_PATH%" rmdir /q %IDF_PATH% +mklink /j %IDF_PATH% %IDF_CLONE_PATH% + +REM Install IDF tools and packages (unless CI has restored from cache) +if "%CI_BUILD_DIR%" NEQ "" ( + if exist "%IDF_TOOLS_PATH%\tools" ( + echo Skipping IDF tools installation, "%IDF_TOOLS_PATH%\tools" exists + goto :EOF + ) +) -REM Install IDF tools and packages -python "%IDF_PATH%\tools\idf_tools.py" --non-interactive install -python -m pip install %SMINGTOOLS%/gevent-1.5.0-cp39-cp39-win_amd64.whl -set IDF_REQUIREMENTS="%IDF_PATH%\requirements.txt" -if not exist "%IDF_REQUIREMENTS%" set IDF_REQUIREMENTS="%IDF_PATH%\tools\requirements\requirements.core.txt" -python -m pip install -r "%IDF_REQUIREMENTS%" +REM Be specific about which tools we want to install for each IDF version +tr '\n' ' ' < "%~dp0idf_tools-%INSTALL_IDF_VER%.lst" > toolver.txt || goto :EOF +for /f "tokens=*" %%x in (toolver.txt) do set IDF_TOOL_PACKAGES=%%x +del toolver.txt +echo Install: %IDF_TOOL_PACKAGES% +python "%IDF_PATH%\tools\idf_tools.py" --non-interactive install %IDF_TOOL_PACKAGES% || goto :EOF +python "%IDF_PATH%\tools\idf_tools.py" --non-interactive install-python-env || goto :EOF -if "%INSTALL_IDF_VER%"=="5.0" python "%IDF_PATH%\tools\idf_tools.py" --non-interactive install-python-env +if "%CI_BUILD_DIR%" NEQ "" ( + del /q "%IDF_TOOLS_PATH%\dist\*" +) diff --git a/Sming/Arch/Esp32/Tools/install.sh b/Sming/Arch/Esp32/Tools/install.sh index 0667e28704..0a872db39d 100755 --- a/Sming/Arch/Esp32/Tools/install.sh +++ b/Sming/Arch/Esp32/Tools/install.sh @@ -5,17 +5,15 @@ if [ -n "$IDF_PATH" ] && [ -n "$IDF_TOOLS_PATH" ]; then PACKAGES=(\ - bison \ - ccache \ - dfu-util \ - flex \ - gperf \ - ninja-build \ + dfu-util ) case $DIST in debian) PACKAGES+=(\ + bison \ + flex \ + gperf \ libffi-dev \ libssl-dev \ ) @@ -23,12 +21,19 @@ case $DIST in fedora) PACKAGES+=(\ + bison \ + flex \ + gperf \ libffi-devel \ ) ;; + + darwin) + ;; + esac -$PKG_INSTALL ${PACKAGES[*]} +$PKG_INSTALL "${PACKAGES[@]}" # If directory exists and isn't a symlink then rename it if [ ! -L "$IDF_PATH" ] && [ -d "$IDF_PATH" ]; then @@ -36,33 +41,44 @@ if [ ! -L "$IDF_PATH" ] && [ -d "$IDF_PATH" ]; then mv "$IDF_PATH" "$IDF_PATH-old" fi -INSTALL_IDF_VER="${INSTALL_IDF_VER:=4.4}" -IDF_CLONE_PATH="$(readlink -m "$IDF_PATH/..")/esp-idf-${INSTALL_IDF_VER}" +INSTALL_IDF_VER="${INSTALL_IDF_VER:=5.2}" +IDF_CLONE_PATH="$(dirname "$IDF_PATH")/esp-idf-${INSTALL_IDF_VER}" IDF_REPO="${IDF_REPO:=https://github.com/mikee47/esp-idf.git}" IDF_BRANCH="sming/release/v${INSTALL_IDF_VER}" if [ -d "$IDF_CLONE_PATH" ]; then - printf "\n\n** Skipping ESP-IDF clone: '$IDF_CLONE_PATH' exists\n\n" + printf "\n\n** Skipping ESP-IDF clone: '%s' exists\n\n" "$IDF_CLONE_PATH" else + if [ -n "$CI_BUILD_DIR" ]; then + IDF_INSTALL_OPTIONS="--depth 1 --recurse-submodules --shallow-submodules" + fi echo "git clone -b $IDF_BRANCH $IDF_REPO $IDF_CLONE_PATH" - git clone -b "$IDF_BRANCH" "$IDF_REPO" "$IDF_CLONE_PATH" + git clone -b "$IDF_BRANCH" "$IDF_REPO" "$IDF_CLONE_PATH" $IDF_INSTALL_OPTIONS fi # Create link to clone rm -f "$IDF_PATH" ln -s "$IDF_CLONE_PATH" "$IDF_PATH" -# Install IDF tools and packages -python3 "$IDF_PATH/tools/idf_tools.py" --non-interactive install -python3 "$IDF_PATH/tools/idf_tools.py" --non-interactive install-python-env -IDF_REQUIREMENTS="$IDF_PATH/requirements.txt" -if [ ! -f "$IDF_REQUIREMENTS" ]; then - IDF_REQUIREMENTS="$IDF_PATH/tools/requirements/requirements.core.txt" -fi -python3 -m pip install --no-input -r "$IDF_REQUIREMENTS" -if [ -z "$KEEP_DOWNLOADS" ]; then - rm -rf "$IDF_TOOLS_PATH/dist" +# Install IDF tools and packages (unless CI has restored from cache) +if [ -n "$CI_BUILD_DIR" ] && [ -d "$IDF_TOOLS_PATH/tools" ]; then + printf "\n\n** Skipping IDF tools installation: '%s/tools' exists\n\n" "$IDF_TOOLS_PATH" +else + # Be specific about which tools we want to install for each IDF version + IDF_TOOL_PACKAGES=$(tr '\n' ' ' < "$SMING_HOME/Arch/Esp32/Tools/idf_tools-${INSTALL_IDF_VER}.lst") + echo "Install: $IDF_TOOL_PACKAGES" + python3 "$IDF_PATH/tools/idf_tools.py" --non-interactive install $IDF_TOOL_PACKAGES + if [ -n "$VIRTUAL_ENV" ]; then + unset VIRTUAL_ENV + unset VIRTUAL_ENV_PROMPT + export PATH="${PATH/$VIRTUAL_ENV\/bin:/}" + fi + python3 "$IDF_PATH/tools/idf_tools.py" --non-interactive install-python-env + + if [ -z "$KEEP_DOWNLOADS" ]; then + rm -rf "$IDF_TOOLS_PATH/dist" + fi fi fi diff --git a/Sming/Arch/Esp32/Tools/travis/build.run.sh b/Sming/Arch/Esp32/Tools/travis/build.run.sh deleted file mode 100755 index 16923e6086..0000000000 --- a/Sming/Arch/Esp32/Tools/travis/build.run.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -set -ex # exit with nonzero exit code if anything fails - -$MAKE_PARALLEL Basic_Blink Basic_WiFi HttpServer_ConfigNetwork DEBUG_VERBOSE_LEVEL=3 STRICT=1 -$MAKE_PARALLEL Basic_Ssl ENABLE_SSL=Bearssl DEBUG_VERBOSE_LEVEL=3 STRICT=1 diff --git a/Sming/Arch/Esp32/Tools/travis/build.setup.sh b/Sming/Arch/Esp32/Tools/travis/build.setup.sh deleted file mode 100755 index 98723973bf..0000000000 --- a/Sming/Arch/Esp32/Tools/travis/build.setup.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -set -ex # exit with nonzero exit code if anything fails - -export IDF_PATH=$TRAVIS_BUILD_DIR/opt/esp-idf diff --git a/Sming/Arch/Esp32/Tools/travis/install.sh b/Sming/Arch/Esp32/Tools/travis/install.sh deleted file mode 100755 index 384e489ee0..0000000000 --- a/Sming/Arch/Esp32/Tools/travis/install.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash -set -ex # exit with nonzero exit code if anything fails - -if [ "$TRAVIS_OS_NAME" == "linux" ]; then - sudo apt-get install -y git wget flex bison gperf \ - cmake ninja-build ccache libffi-dev libssl-dev dfu-util \ - python3 python3-pip python3-setuptools - sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 10 - mkdir -p $TRAVIS_BUILD_DIR/opt - cd $TRAVIS_BUILD_DIR/opt - git clone -b v4.1 --recursive https://github.com/espressif/esp-idf.git - export IDF_PATH=$TRAVIS_BUILD_DIR/opt/esp-idf - $IDF_PATH/install.sh - - python -m pip install -r $IDF_PATH/requirements.txt -fi diff --git a/Sming/Arch/Esp32/app.mk b/Sming/Arch/Esp32/app.mk index 42271785d1..f06d8165a6 100644 --- a/Sming/Arch/Esp32/app.mk +++ b/Sming/Arch/Esp32/app.mk @@ -9,9 +9,28 @@ LDFLAGS += \ -nostdlib \ -Wl,-static +ifeq ($(IDF_VERSION),v5.2) +LDFLAGS += \ + -Wl,--no-warn-rwx-segments +endif + +ifdef IDF_TARGET_ARCH_RISCV + LDFLAGS += \ + -nostartfiles \ + -march=$(ESP32_RISCV_ARCH) \ + --specs=nosys.specs +endif + .PHONY: application application: $(TARGET_BIN) +ifeq ($(IDF_VERSION),v4.3) + @printf "\033[47;1;31mWARNING! ESP-IDF 4.3 reached 'End of Life' in December 2023.\033[0m Upgrade to v5.2 recommended.\n" +else ifeq ($(IDF_VERSION),v4.4) + @printf "\033[47;1;31mWARNING! ESP-IDF 4.4 support ends August 2024!\033[0m Upgrade to v5.2 recommended.\n" +else ifeq ($(IDF_VERSION),v5.0) + @printf "\033[47;1;34mNOTE! ESP-IDF 5.0 not recommended for new designs.\033[0m Please consider upgrading to v5.2.\n" +endif $(TARGET_OUT): $(COMPONENTS_AR) $(info $(notdir $(PROJECT_DIR)): Linking $@) @@ -32,3 +51,11 @@ endif $(TARGET_BIN): $(TARGET_OUT) $(Q) $(ESPTOOL_CMDLINE) elf2image --min-rev $(CHIP_REV_MIN) --elf-sha256-offset 0xb0 $(ESPTOOL_EXTRA_ARGS) $(flashimageoptions) -o $@ $< + + +##@Flashing + +.PHONY: bootinfo +bootinfo: $(FLASH_BOOT_LOADER) ##Show bootloader information + $(info $(FLASH_BOOT_LOADER):) + $(Q) $(ESPTOOL_CMDLINE) image_info -v2 $(FLASH_BOOT_LOADER) diff --git a/Sming/Arch/Esp32/build.mk b/Sming/Arch/Esp32/build.mk index 32d9b6b38a..92e00a4171 100644 --- a/Sming/Arch/Esp32/build.mk +++ b/Sming/Arch/Esp32/build.mk @@ -10,14 +10,21 @@ endif export IDF_PATH := $(call FixPath,$(IDF_PATH)) -# By default, downloaded tools will be installed under $HOME/.espressif directory -# (%USERPROFILE%/.espressif on Windows). This path can be modified by setting -# IDF_TOOLS_PATH variable prior to running this tool. +# Extract IDF version +ifndef IDF_VER +# e.g. v5.2-beta1-265-g405b8b5512 or v5.0.5-173-g9d6770dfbb +IDF_VER := $(shell (cd $$IDF_PATH && git describe --always --tags --dirty) | cut -c 1-31) +endif +# Now just vmajor.minor +IDF_VERSION := $(subst ., ,$(firstword $(subst -, ,$(IDF_VER)))) +IDF_VERSION := $(firstword $(IDF_VERSION)).$(word 2,$(IDF_VERSION)) + +# Use default paths from standard install scripts. DEBUG_VARS += IDF_TOOLS_PATH ifeq ($(UNAME),Windows) -IDF_TOOLS_PATH ?= $(USERPROFILE)/.espressif +IDF_TOOLS_PATH ?= C:/tools/esp32 else -IDF_TOOLS_PATH ?= $(HOME)/.espressif +IDF_TOOLS_PATH ?= /opt/esp32 endif export IDF_TOOLS_PATH := $(call FixPath,$(IDF_TOOLS_PATH)) @@ -27,40 +34,46 @@ ESP_VARIANT := $(SMING_SOC) export ESP_VARIANT IDF_TOOL_INFO := $(shell $(PYTHON) $(ARCH_TOOLS)/idf_tools.py $(SMING_SOC)) -ESP32_COMPILER_PREFIX := $(word 1,$(IDF_TOOL_INFO)) -ESP32_COMPILER_VERSION := $(word 2,$(IDF_TOOL_INFO)) -IDF_TARGET_ARCH_RISCV := $(findstring riscv,$(ESP32_COMPILER_PREFIX)) +ESP32_GCC_PATH := $(word 1,$(IDF_TOOL_INFO)) +ESP32_GDB_PATH := $(word 2,$(IDF_TOOL_INFO)) +ESP32_COMPILER_PATH := $(IDF_TOOLS_PATH)/tools/$(ESP32_GCC_PATH) +ifneq (,$(filter xtensa%,$(ESP32_GCC_PATH))) +ESP32_COMPILER_PREFIX := xtensa-$(ESP_VARIANT)-elf +else +ESP32_COMPILER_PREFIX := riscv32-esp-elf +IDF_TARGET_ARCH_RISCV := 1 +# This is important as no hardware FPU is available on these SOCs +ifeq ($(IDF_VERSION),v5.2) +ESP32_RISCV_ARCH := rv32imc_zicsr_zifencei +else +ESP32_RISCV_ARCH := rv32imc +endif +endif -# $1 => Root directory -# $2 => Sub-directory +# $1 => Tool sub-path/name define FindTool -$(lastword $(sort $(wildcard $(IDF_TOOLS_PATH)/$1/*))$2) +$(lastword $(sort $(wildcard $(IDF_TOOLS_PATH)/$1*))) endef DEBUG_VARS += ESP32_COMPILER_PATH ESP32_ULP_PATH ESP32_OPENOCD_PATH ESP32_PYTHON_PATH -ifndef ESP32_COMPILER_PATH -ESP32_COMPILER_PATH := $(IDF_TOOLS_PATH)/tools/$(ESP32_COMPILER_PREFIX)/$(ESP32_COMPILER_VERSION)/$(ESP32_COMPILER_PREFIX) -endif - ifndef ESP32_ULP_PATH -ESP32_ULP_PATH := $(call FindTool,tools/$(ESP_VARIANT)ulp-elf) +ESP32_ULP_PATH := $(call FindTool,tools/$(ESP_VARIANT)ulp-elf/) endif ifndef ESP32_OPENOCD_PATH -ESP32_OPENOCD_PATH := $(call FindTool,tools/openocd-esp32) +ESP32_OPENOCD_PATH := $(call FindTool,tools/openocd-esp32/) endif ifndef ESP32_PYTHON_PATH -ESP32_PYTHON_PATH := $(call FindTool,python_env) -ifneq (,$(wildcard $(ESP32_PYTHON_PATH)/bin)) -ESP32_PYTHON_PATH := $(ESP32_PYTHON_PATH)/bin -else ifneq (,$(wildcard $(ESP32_PYTHON_PATH)/Scripts)) -ESP32_PYTHON_PATH := $(ESP32_PYTHON_PATH)/Scripts +ESP32_PYTHON_PATH := $(call FindTool,python_env/idf$(subst v,,$(IDF_VERSION))) +ifndef ESP32_PYTHON_PATH +ESP32_PYTHON_PATH := $(dir $(PYTHON)) +else ifeq ($(UNAME),Windows) +ESP32_PYTHON := $(ESP32_PYTHON_PATH)/Scripts/python else -$(error Failed to find ESP32 Python installation) +ESP32_PYTHON := $(ESP32_PYTHON_PATH)/bin/python endif -ESP32_PYTHON = $(ESP32_PYTHON_PATH)/python endif # Required by v4.2 SDK @@ -69,40 +82,20 @@ export IDF_PYTHON_ENV_PATH=$(ESP32_PYTHON_PATH) # Add ESP-IDF tools to PATH IDF_PATH_LIST := \ $(IDF_PATH)/tools \ - $(ESP32_COMPILER_PATH)/bin \ + $(ESP32_COMPILER_PATH) \ $(ESP32_ULP_PATH)/$(ESP_VARIANT)ulp-elf-binutils/bin \ - $(ESP32_OPENOCD_PATH)/openocd-esp32/bin \ - $(ESP32_PYTHON_PATH)/bin \ - $(IDF_PATH)/components/esptool_py/esptool \ - $(IDF_PATH)/components/espcoredump \ - $(IDF_PATH)/components/partition_table - -ifeq ($(UNAME),Windows) -DEBUG_VARS += ESP32_NINJA_PATH -ifndef ESP32_NINJA_PATH -ESP32_NINJA_PATH := $(call FindTool,tools/ninja) -endif -ifeq (,$(wildcard $(ESP32_NINJA_PATH)/ninja.exe)) -$(error Failed to find NINJA) -endif -IDF_PATH_LIST += $(ESP32_NINJA_PATH) + $(ESP32_OPENOCD_PATH)/openocd-esp32/bin -DEBUG_VARS += ESP32_IDFEXE_PATH -ifndef ESP32_IDFEXE_PATH -ESP32_IDFEXE_PATH := $(call FindTool,tools/idf-exe) -endif -IDF_PATH_LIST += $(ESP32_IDFEXE_PATH) +ifeq ($(ENABLE_CCACHE),1) +export IDF_CCACHE_ENABLE := 1 endif -DEBUG_VARS += NINJA -NINJA := $(if $(ESP32_NINJA_PATH),$(ESP32_NINJA_PATH)/,)ninja - empty:= space:= $(empty) $(empty) export PATH := $(subst $(space),:,$(IDF_PATH_LIST)):$(PATH) -TOOLSPEC := $(ESP32_COMPILER_PATH)/bin/$(ESP32_COMPILER_PREFIX) +TOOLSPEC := $(ESP32_COMPILER_PATH)/$(ESP32_COMPILER_PREFIX) AS := $(TOOLSPEC)-gcc CC := $(TOOLSPEC)-gcc CXX := $(TOOLSPEC)-g++ @@ -111,11 +104,14 @@ LD := $(TOOLSPEC)-gcc NM := $(TOOLSPEC)-nm OBJCOPY := $(TOOLSPEC)-objcopy OBJDUMP := $(TOOLSPEC)-objdump -GDB := $(TOOLSPEC)-gdb SIZE := $(TOOLSPEC)-size -# Extracting IDF version -IDF_VER := $(shell (cd $$IDF_PATH && git describe --always --tags --dirty) | cut -c 1-31) +ifeq (None,$(ESP32_GDB_PATH)) +GDB := $(TOOLSPEC)-gdb +else +GDB := $(IDF_TOOLS_PATH)/tools/$(ESP32_GDB_PATH)/$(ESP32_COMPILER_PREFIX)-gdb +endif + # [ Sming specific flags ] DEBUG_VARS += IDF_PATH IDF_VER @@ -144,7 +140,10 @@ export PROJECT_VER # Flags which control code generation and dependency generation, both for C and C++ CPPFLAGS += -Wno-frame-address -ifndef IDF_TARGET_ARCH_RISCV +ifdef IDF_TARGET_ARCH_RISCV +CPPFLAGS += \ + -march=$(ESP32_RISCV_ARCH) +else CPPFLAGS += \ -mlongcalls \ -mtext-section-literals diff --git a/Sming/Arch/Esp32/esp32-pindefs.txt b/Sming/Arch/Esp32/esp32-pindefs.txt index aeaa4b2bb0..5c809fe882 100644 --- a/Sming/Arch/Esp32/esp32-pindefs.txt +++ b/Sming/Arch/Esp32/esp32-pindefs.txt @@ -47,10 +47,10 @@ rtc gpio pad a0 a1 a2 f0 f1 notes 7 26 GPIO26 DAC_2 ADC2_CH9 - RTC_GPIO7 - 8 33 32K_XN XTAL_32K_N ADC1_CH5 TOUCH8 RTC_GPIO8 - 9 32 32K_XP XTAL_32K_P ADC1_CH4 TOUCH9 RTC_GPIO9 - -10 4 GPIO4 - ADC2_CH0 TOUCH0 RTC_GPIO10 I2C_SCL ∗ -11 0 GPIO0 - ADC2_CH1 TOUCH1 RTC_GPIO11 I2C_SDA ∗ -12 2 GPIO2 - ADC2_CH2 TOUCH2 RTC_GPIO12 I2C_SCL ∗ -13 15 MTDO - ADC2_CH3 TOUCH3 RTC_GPIO13 I2C_SDA ∗ +10 4 GPIO4 - ADC2_CH0 TOUCH0 RTC_GPIO10 I2C_SCL - +11 0 GPIO0 - ADC2_CH1 TOUCH1 RTC_GPIO11 I2C_SDA - +12 2 GPIO2 - ADC2_CH2 TOUCH2 RTC_GPIO12 I2C_SCL - +13 15 MTDO - ADC2_CH3 TOUCH3 RTC_GPIO13 I2C_SDA - 14 13 MTCK - ADC2_CH4 TOUCH4 RTC_GPIO14 - 15 12 MTDI - ADC2_CH5 TOUCH5 RTC_GPIO15 - 16 14 MTMS - ADC2_CH6 TOUCH6 RTC_GPIO16 - @@ -72,46 +72,46 @@ signal input default same output enable 11 HSPICS0_in 0 yes HSPICS0_out HSPICS0_oe 12 HSPIHD_in 0 yes HSPIHD_out HSPIHD_oe 13 HSPIWP_in 0 yes HSPIWP_out HSPIWP_oe -14 U0RXD_in 0 yes U0TXD_out 1’d1 -15 U0CTS_in 0 yes U0RTS_out 1’d1 -16 U0DSR_in 0 no U0DTR_out 1’d1 -17 U1RXD_in 0 yes U1TXD_out 1’d1 -18 U1CTS_in 0 yes U1RTS_out 1’d1 -23 I2S0O_BCK_in 0 no I2S0O_BCK_out 1’d1 -24 I2S1O_BCK_in 0 no I2S1O_BCK_out 1’d1 -25 I2S0O_WS_in 0 no I2S0O_WS_out 1’d1 -26 I2S1O_WS_in 0 no I2S1O_WS_out 1’d1 -27 I2S0I_BCK_in 0 no I2S0I_BCK_out 1’d1 -28 I2S0I_WS_in 0 no I2S0I_WS_out 1’d1 -29 I2CEXT0_SCL_in 1 no I2CEXT0_SCL_out 1’d1 -30 I2CEXT0_SDA_in 1 no I2CEXT0_SDA_out 1’d1 -31 pwm0_sync0_in 0 no sdio_tohost_int_out 1’d1 -32 pwm0_sync1_in 0 no pwm0_out0a 1’d1 -33 pwm0_sync2_in 0 no pwm0_out0b 1’d1 -34 pwm0_f0_in 0 no pwm0_out1a 1’d1 -35 pwm0_f1_in 0 no pwm0_out1b 1’d1 -36 pwm0_f2_in 0 no pwm0_out2a 1’d1 -37 - 0 no pwm0_out2b 1’d1 -39 pcnt_sig_ch0_in0 0 no - 1’d1 -40 pcnt_sig_ch1_in0 0 no - 1’d1 -41 pcnt_ctrl_ch0_in0 0 no - 1’d1 -42 pcnt_ctrl_ch1_in0 0 no - 1’d1 -43 pcnt_sig_ch0_in1 0 no - 1’d1 -44 pcnt_sig_ch1_in1 0 no - 1’d1 -45 pcnt_ctrl_ch0_in1 0 no - 1’d1 -46 pcnt_ctrl_ch1_in1 0 no - 1’d1 -47 pcnt_sig_ch0_in2 0 no - 1’d1 -48 pcnt_sig_ch1_in2 0 no - 1’d1 -49 pcnt_ctrl_ch0_in2 0 no - 1’d1 -50 pcnt_ctrl_ch1_in2 0 no - 1’d1 -51 pcnt_sig_ch0_in3 0 no - 1’d1 -52 pcnt_sig_ch1_in3 0 no - 1’d1 -53 pcnt_ctrl_ch0_in3 0 no - 1’d1 -54 pcnt_ctrl_ch1_in3 0 no - 1’d1 -55 pcnt_sig_ch0_in4 0 no - 1’d1 -56 pcnt_sig_ch1_in4 0 no - 1’d1 -57 pcnt_ctrl_ch0_in4 0 no - 1’d1 -58 pcnt_ctrl_ch1_in4 0 no - 1’d1 +14 U0RXD_in 0 yes U0TXD_out 1'd1 +15 U0CTS_in 0 yes U0RTS_out 1'd1 +16 U0DSR_in 0 no U0DTR_out 1'd1 +17 U1RXD_in 0 yes U1TXD_out 1'd1 +18 U1CTS_in 0 yes U1RTS_out 1'd1 +23 I2S0O_BCK_in 0 no I2S0O_BCK_out 1'd1 +24 I2S1O_BCK_in 0 no I2S1O_BCK_out 1'd1 +25 I2S0O_WS_in 0 no I2S0O_WS_out 1'd1 +26 I2S1O_WS_in 0 no I2S1O_WS_out 1'd1 +27 I2S0I_BCK_in 0 no I2S0I_BCK_out 1'd1 +28 I2S0I_WS_in 0 no I2S0I_WS_out 1'd1 +29 I2CEXT0_SCL_in 1 no I2CEXT0_SCL_out 1'd1 +30 I2CEXT0_SDA_in 1 no I2CEXT0_SDA_out 1'd1 +31 pwm0_sync0_in 0 no sdio_tohost_int_out 1'd1 +32 pwm0_sync1_in 0 no pwm0_out0a 1'd1 +33 pwm0_sync2_in 0 no pwm0_out0b 1'd1 +34 pwm0_f0_in 0 no pwm0_out1a 1'd1 +35 pwm0_f1_in 0 no pwm0_out1b 1'd1 +36 pwm0_f2_in 0 no pwm0_out2a 1'd1 +37 - 0 no pwm0_out2b 1'd1 +39 pcnt_sig_ch0_in0 0 no - 1'd1 +40 pcnt_sig_ch1_in0 0 no - 1'd1 +41 pcnt_ctrl_ch0_in0 0 no - 1'd1 +42 pcnt_ctrl_ch1_in0 0 no - 1'd1 +43 pcnt_sig_ch0_in1 0 no - 1'd1 +44 pcnt_sig_ch1_in1 0 no - 1'd1 +45 pcnt_ctrl_ch0_in1 0 no - 1'd1 +46 pcnt_ctrl_ch1_in1 0 no - 1'd1 +47 pcnt_sig_ch0_in2 0 no - 1'd1 +48 pcnt_sig_ch1_in2 0 no - 1'd1 +49 pcnt_ctrl_ch0_in2 0 no - 1'd1 +50 pcnt_ctrl_ch1_in2 0 no - 1'd1 +51 pcnt_sig_ch0_in3 0 no - 1'd1 +52 pcnt_sig_ch1_in3 0 no - 1'd1 +53 pcnt_ctrl_ch0_in3 0 no - 1'd1 +54 pcnt_ctrl_ch1_in3 0 no - 1'd1 +55 pcnt_sig_ch0_in4 0 no - 1'd1 +56 pcnt_sig_ch1_in4 0 no - 1'd1 +57 pcnt_ctrl_ch0_in4 0 no - 1'd1 +58 pcnt_ctrl_ch1_in4 0 no - 1'd1 61 HSPICS1_in 0 no HSPICS1_out HSPICS1_oe 62 HSPICS2_in 0 no HSPICS2_out HSPICS2_oe 63 VSPICLK_in 0 yes VSPICLK_out_mux VSPICLK_oe @@ -122,179 +122,179 @@ signal input default same output enable 68 VSPICS0_in 0 yes VSPICS0_out VSPICS0_oe 69 VSPICS1_in 0 no VSPICS1_out VSPICS1_oe 70 VSPICS2_in 0 no VSPICS2_out VSPICS2_oe -71 pcnt_sig_ch0_in5 0 no ledc_hs_sig_out0 1’d1 -72 pcnt_sig_ch1_in5 0 no ledc_hs_sig_out1 1’d1 -73 pcnt_ctrl_ch0_in5 0 no ledc_hs_sig_out2 1’d1 -74 pcnt_ctrl_ch1_in5 0 no ledc_hs_sig_out3 1’d1 -75 pcnt_sig_ch0_in6 0 no ledc_hs_sig_out4 1’d1 -76 pcnt_sig_ch1_in6 0 no ledc_hs_sig_out5 1’d1 -77 pcnt_ctrl_ch0_in6 0 no ledc_hs_sig_out6 1’d1 -78 pcnt_ctrl_ch1_in6 0 no ledc_hs_sig_out7 1’d1 -79 pcnt_sig_ch0_in7 0 no ledc_ls_sig_out0 1’d1 -80 pcnt_sig_ch1_in7 0 no ledc_ls_sig_out1 1’d1 -81 pcnt_ctrl_ch0_in7 0 no ledc_ls_sig_out2 1’d1 -82 pcnt_ctrl_ch1_in7 0 no ledc_ls_sig_out3 1’d1 -83 rmt_sig_in0 0 no ledc_ls_sig_out4 1’d1 -84 rmt_sig_in1 0 no ledc_ls_sig_out5 1’d1 -85 rmt_sig_in2 0 no ledc_ls_sig_out6 1’d1 -86 rmt_sig_in3 0 no ledc_ls_sig_out7 1’d1 -87 rmt_sig_in4 0 no rmt_sig_out0 1’d1 -88 rmt_sig_in5 0 no rmt_sig_out1 1’d1 -89 rmt_sig_in6 0 no rmt_sig_out2 1’d1 -90 rmt_sig_in7 0 no rmt_sig_out3 1’d1 -91 - - - rmt_sig_out4 1’d1 -92 - - - rmt_sig_out6 1’d1 -94 twai_rx 1 no rmt_sig_out7 1’d1 -95 I2CEXT1_SCL_in 1 no I2CEXT1_SCL_out 1’d1 -96 I2CEXT1_SDA_in 1 no I2CEXT1_SDA_out 1’d1 -97 host_card_detect_n_1 0 no host_ccmd_od_pullup_en_n 1’d1 -98 host_card_detect_n_2 0 no host_rst_n_1 1’d1 -99 host_card_write_prt_1 0 no host_rst_n_2 1’d1 -100 host_card_write_prt_2 0 no gpio_sd0_out 1’d1 -101 host_card_int_n_1 0 no gpio_sd1_out 1’d1 -102 host_card_int_n_2 0 no gpio_sd2_out 1’d1 -103 pwm1_sync0_in 0 no gpio_sd3_out 1’d1 -104 pwm1_sync1_in 0 no gpio_sd4_out 1’d1 -105 pwm1_sync2_in 0 no gpio_sd5_out 1’d1 -106 pwm1_f0_in 0 no gpio_sd6_out 1’d1 -107 pwm1_f1_in 0 no gpio_sd7_out 1’d1 -108 pwm1_f2_in 0 no pwm1_out0a 1’d1 -109 pwm0_cap0_in 0 no pwm1_out0b 1’d1 -110 pwm0_cap1_in 0 no pwm1_out1a 1’d1 -111 pwm0_cap2_in 0 no pwm1_out1b 1’d1 -112 pwm1_cap0_in 0 no pwm1_out2a 1’d1 -113 pwm1_cap1_in 0 no pwm1_out2b 1’d1 -114 pwm1_cap2_in 0 no pwm2_out1h 1’d1 -115 pwm2_flta 1 no pwm2_out1l 1’d1 -116 pwm2_fltb 1 no pwm2_out2h 1’d1 -117 pwm2_cap1_in 0 no pwm2_out2l 1’d1 -118 pwm2_cap2_in 0 no pwm2_out3h 1’d1 -119 pwm2_cap3_in 0 no pwm2_out3l 1’d1 -120 pwm3_flta 1 no pwm2_out4h 1’d1 -121 pwm3_fltb 1 no pwm2_out4l 1’d1 -122 pwm3_cap1_in 0 no - 1’d1 -123 pwm3_cap2_in 0 no twai_tx 1’d1 -124 pwm3_cap3_in 0 no twai_bus_off_on 1’d1 -125 - - - twai_clkout 1’d1 -140 I2S0I_DATA_in0 0 no I2S0O_DATA_out0 1’d1 -141 I2S0I_DATA_in1 0 no I2S0O_DATA_out1 1’d1 -142 I2S0I_DATA_in2 0 no I2S0O_DATA_out2 1’d1 -143 I2S0I_DATA_in3 0 no I2S0O_DATA_out3 1’d1 -144 I2S0I_DATA_in4 0 no I2S0O_DATA_out4 1’d1 -145 I2S0I_DATA_in5 0 no I2S0O_DATA_out5 1’d1 -146 I2S0I_DATA_in6 0 no I2S0O_DATA_out6 1’d1 -147 I2S0I_DATA_in7 0 no I2S0O_DATA_out7 1’d1 -148 I2S0I_DATA_in8 0 no I2S0O_DATA_out8 1’d1 -149 I2S0I_DATA_in9 0 no I2S0O_DATA_out9 1’d1 -150 I2S0I_DATA_in10 0 no I2S0O_DATA_out10 1’d1 -151 I2S0I_DATA_in11 0 no I2S0O_DATA_out11 1’d1 -152 I2S0I_DATA_in12 0 no I2S0O_DATA_out12 1’d1 -153 I2S0I_DATA_in13 0 no I2S0O_DATA_out13 1’d1 -154 I2S0I_DATA_in14 0 no I2S0O_DATA_out14 1’d1 -155 I2S0I_DATA_in15 0 no I2S0O_DATA_out15 1’d1 -156 - - - I2S0O_DATA_out16 1’d1 -157 - - - I2S0O_DATA_out17 1’d1 -158 - - - I2S0O_DATA_out18 1’d1 -159 - - - I2S0O_DATA_out19 1’d1 -160 - - - I2S0O_DATA_out20 1’d1 -161 - - - I2S0O_DATA_out21 1’d1 -162 - - - I2S0O_DATA_out22 1’d1 -163 - - - I2S0O_DATA_out23 1’d1 -164 I2S1I_BCK_in 0 no I2S1I_BCK_out 1’d1 -165 I2S1I_WS_in 0 no I2S1I_WS_out 1’d1 -166 I2S1I_DATA_in0 0 no I2S1O_DATA_out0 1’d1 -167 I2S1I_DATA_in1 0 no I2S1O_DATA_out1 1’d1 -168 I2S1I_DATA_in2 0 no I2S1O_DATA_out2 1’d1 -169 I2S1I_DATA_in3 0 no I2S1O_DATA_out3 1’d1 -170 I2S1I_DATA_in4 0 no I2S1O_DATA_out4 1’d1 -171 I2S1I_DATA_in5 0 no I2S1O_DATA_out5 1’d1 -172 I2S1I_DATA_in6 0 no I2S1O_DATA_out6 1’d1 -173 I2S1I_DATA_in7 0 no I2S1O_DATA_out7 1’d1 -174 I2S1I_DATA_in8 0 no I2S1O_DATA_out8 1’d1 -175 I2S1I_DATA_in9 0 no I2S1O_DATA_out9 1’d1 -121 pwm3_fltb 1 no pwm2_out4l 1’d1 -122 pwm3_cap1_in 0 no - 1’d1 -123 pwm3_cap2_in 0 no twai_tx 1’d1 -124 pwm3_cap3_in 0 no twai_bus_off_on 1’d1 -125 - - - twai_clkout 1’d1 -140 I2S0I_DATA_in0 0 no I2S0O_DATA_out0 1’d1 -141 I2S0I_DATA_in1 0 no I2S0O_DATA_out1 1’d1 -142 I2S0I_DATA_in2 0 no I2S0O_DATA_out2 1’d1 -143 I2S0I_DATA_in3 0 no I2S0O_DATA_out3 1’d1 -144 I2S0I_DATA_in4 0 no I2S0O_DATA_out4 1’d1 -145 I2S0I_DATA_in5 0 no I2S0O_DATA_out5 1’d1 -146 I2S0I_DATA_in6 0 no I2S0O_DATA_out6 1’d1 -147 I2S0I_DATA_in7 0 no I2S0O_DATA_out7 1’d1 -148 I2S0I_DATA_in8 0 no I2S0O_DATA_out8 1’d1 -149 I2S0I_DATA_in9 0 no I2S0O_DATA_out9 1’d1 -150 I2S0I_DATA_in10 0 no I2S0O_DATA_out10 1’d1 -151 I2S0I_DATA_in11 0 no I2S0O_DATA_out11 1’d1 -152 I2S0I_DATA_in12 0 no I2S0O_DATA_out12 1’d1 -153 I2S0I_DATA_in13 0 no I2S0O_DATA_out13 1’d1 -154 I2S0I_DATA_in14 0 no I2S0O_DATA_out14 1’d1 -155 I2S0I_DATA_in15 0 no I2S0O_DATA_out15 1’d1 -156 - - - I2S0O_DATA_out16 1’d1 -157 - - - I2S0O_DATA_out17 1’d1 -158 - - - I2S0O_DATA_out18 1’d1 -159 - - - I2S0O_DATA_out19 1’d1 -160 - - - I2S0O_DATA_out20 1’d1 -161 - - - I2S0O_DATA_out21 1’d1 -162 - - - I2S0O_DATA_out22 1’d1 -163 - - - I2S0O_DATA_out23 1’d1 -164 I2S1I_BCK_in 0 no I2S1I_BCK_out 1’d1 -165 I2S1I_WS_in 0 no I2S1I_WS_out 1’d1 -166 I2S1I_DATA_in0 0 no I2S1O_DATA_out0 1’d1 -167 I2S1I_DATA_in1 0 no I2S1O_DATA_out1 1’d1 -168 I2S1I_DATA_in2 0 no I2S1O_DATA_out2 1’d1 -169 I2S1I_DATA_in3 0 no I2S1O_DATA_out3 1’d1 -170 I2S1I_DATA_in4 0 no I2S1O_DATA_out4 1’d1 -171 I2S1I_DATA_in5 0 no I2S1O_DATA_out5 1’d1 -172 I2S1I_DATA_in6 0 no I2S1O_DATA_out6 1’d1 -173 I2S1I_DATA_in7 0 no I2S1O_DATA_out7 1’d1 -174 I2S1I_DATA_in8 0 no I2S1O_DATA_out8 1’d1 -175 I2S1I_DATA_in9 0 no I2S1O_DATA_out9 1’d1 -176 I2S1I_DATA_in10 0 no I2S1O_DATA_out10 1’d1 -177 I2S1I_DATA_in11 0 no I2S1O_DATA_out11 1’d1 -178 I2S1I_DATA_in12 0 no I2S1O_DATA_out12 1’d1 -179 I2S1I_DATA_in13 0 no I2S1O_DATA_out13 1’d1 -180 I2S1I_DATA_in14 0 no I2S1O_DATA_out14 1’d1 -181 I2S1I_DATA_in15 0 no I2S1O_DATA_out15 1’d1 -182 - - - I2S1O_DATA_out16 1’d1 -183 - - - I2S1O_DATA_out17 1’d1 -184 - - - I2S1O_DATA_out18 1’d1 -185 - - - I2S1O_DATA_out19 1’d1 -186 - - - I2S1O_DATA_out20 1’d1 -187 - - - I2S1O_DATA_out21 1’d1 -188 - - - I2S1O_DATA_out22 1’d1 -189 - - - I2S1O_DATA_out23 1’d1 -190 I2S0I_H_SYNC 0 no pwm3_out1h 1’d1 -191 I2S0I_V_SYNC 0 no pwm3_out1l 1’d1 -192 I2S0I_H_ENABLE 0 no pwm3_out2h 1’d1 -193 I2S1I_H_SYNC 0 no pwm3_out2l 1’d1 -194 I2S1I_V_SYNC 0 no pwm3_out3h 1’d1 -195 I2S1I_H_ENABLE 0 no pwm3_out3l 1’d1 -196 - - - pwm3_out4h 1’d1 -197 - - - pwm3_out4l 1’d1 -198 U2RXD_in 0 yes U2TXD_out 1’d1 -199 U2CTS_in 0 yes U2RTS_out 1’d1 +71 pcnt_sig_ch0_in5 0 no ledc_hs_sig_out0 1'd1 +72 pcnt_sig_ch1_in5 0 no ledc_hs_sig_out1 1'd1 +73 pcnt_ctrl_ch0_in5 0 no ledc_hs_sig_out2 1'd1 +74 pcnt_ctrl_ch1_in5 0 no ledc_hs_sig_out3 1'd1 +75 pcnt_sig_ch0_in6 0 no ledc_hs_sig_out4 1'd1 +76 pcnt_sig_ch1_in6 0 no ledc_hs_sig_out5 1'd1 +77 pcnt_ctrl_ch0_in6 0 no ledc_hs_sig_out6 1'd1 +78 pcnt_ctrl_ch1_in6 0 no ledc_hs_sig_out7 1'd1 +79 pcnt_sig_ch0_in7 0 no ledc_ls_sig_out0 1'd1 +80 pcnt_sig_ch1_in7 0 no ledc_ls_sig_out1 1'd1 +81 pcnt_ctrl_ch0_in7 0 no ledc_ls_sig_out2 1'd1 +82 pcnt_ctrl_ch1_in7 0 no ledc_ls_sig_out3 1'd1 +83 rmt_sig_in0 0 no ledc_ls_sig_out4 1'd1 +84 rmt_sig_in1 0 no ledc_ls_sig_out5 1'd1 +85 rmt_sig_in2 0 no ledc_ls_sig_out6 1'd1 +86 rmt_sig_in3 0 no ledc_ls_sig_out7 1'd1 +87 rmt_sig_in4 0 no rmt_sig_out0 1'd1 +88 rmt_sig_in5 0 no rmt_sig_out1 1'd1 +89 rmt_sig_in6 0 no rmt_sig_out2 1'd1 +90 rmt_sig_in7 0 no rmt_sig_out3 1'd1 +91 - - - rmt_sig_out4 1'd1 +92 - - - rmt_sig_out6 1'd1 +94 twai_rx 1 no rmt_sig_out7 1'd1 +95 I2CEXT1_SCL_in 1 no I2CEXT1_SCL_out 1'd1 +96 I2CEXT1_SDA_in 1 no I2CEXT1_SDA_out 1'd1 +97 host_card_detect_n_1 0 no host_ccmd_od_pullup_en_n 1'd1 +98 host_card_detect_n_2 0 no host_rst_n_1 1'd1 +99 host_card_write_prt_1 0 no host_rst_n_2 1'd1 +100 host_card_write_prt_2 0 no gpio_sd0_out 1'd1 +101 host_card_int_n_1 0 no gpio_sd1_out 1'd1 +102 host_card_int_n_2 0 no gpio_sd2_out 1'd1 +103 pwm1_sync0_in 0 no gpio_sd3_out 1'd1 +104 pwm1_sync1_in 0 no gpio_sd4_out 1'd1 +105 pwm1_sync2_in 0 no gpio_sd5_out 1'd1 +106 pwm1_f0_in 0 no gpio_sd6_out 1'd1 +107 pwm1_f1_in 0 no gpio_sd7_out 1'd1 +108 pwm1_f2_in 0 no pwm1_out0a 1'd1 +109 pwm0_cap0_in 0 no pwm1_out0b 1'd1 +110 pwm0_cap1_in 0 no pwm1_out1a 1'd1 +111 pwm0_cap2_in 0 no pwm1_out1b 1'd1 +112 pwm1_cap0_in 0 no pwm1_out2a 1'd1 +113 pwm1_cap1_in 0 no pwm1_out2b 1'd1 +114 pwm1_cap2_in 0 no pwm2_out1h 1'd1 +115 pwm2_flta 1 no pwm2_out1l 1'd1 +116 pwm2_fltb 1 no pwm2_out2h 1'd1 +117 pwm2_cap1_in 0 no pwm2_out2l 1'd1 +118 pwm2_cap2_in 0 no pwm2_out3h 1'd1 +119 pwm2_cap3_in 0 no pwm2_out3l 1'd1 +120 pwm3_flta 1 no pwm2_out4h 1'd1 +121 pwm3_fltb 1 no pwm2_out4l 1'd1 +122 pwm3_cap1_in 0 no - 1'd1 +123 pwm3_cap2_in 0 no twai_tx 1'd1 +124 pwm3_cap3_in 0 no twai_bus_off_on 1'd1 +125 - - - twai_clkout 1'd1 +140 I2S0I_DATA_in0 0 no I2S0O_DATA_out0 1'd1 +141 I2S0I_DATA_in1 0 no I2S0O_DATA_out1 1'd1 +142 I2S0I_DATA_in2 0 no I2S0O_DATA_out2 1'd1 +143 I2S0I_DATA_in3 0 no I2S0O_DATA_out3 1'd1 +144 I2S0I_DATA_in4 0 no I2S0O_DATA_out4 1'd1 +145 I2S0I_DATA_in5 0 no I2S0O_DATA_out5 1'd1 +146 I2S0I_DATA_in6 0 no I2S0O_DATA_out6 1'd1 +147 I2S0I_DATA_in7 0 no I2S0O_DATA_out7 1'd1 +148 I2S0I_DATA_in8 0 no I2S0O_DATA_out8 1'd1 +149 I2S0I_DATA_in9 0 no I2S0O_DATA_out9 1'd1 +150 I2S0I_DATA_in10 0 no I2S0O_DATA_out10 1'd1 +151 I2S0I_DATA_in11 0 no I2S0O_DATA_out11 1'd1 +152 I2S0I_DATA_in12 0 no I2S0O_DATA_out12 1'd1 +153 I2S0I_DATA_in13 0 no I2S0O_DATA_out13 1'd1 +154 I2S0I_DATA_in14 0 no I2S0O_DATA_out14 1'd1 +155 I2S0I_DATA_in15 0 no I2S0O_DATA_out15 1'd1 +156 - - - I2S0O_DATA_out16 1'd1 +157 - - - I2S0O_DATA_out17 1'd1 +158 - - - I2S0O_DATA_out18 1'd1 +159 - - - I2S0O_DATA_out19 1'd1 +160 - - - I2S0O_DATA_out20 1'd1 +161 - - - I2S0O_DATA_out21 1'd1 +162 - - - I2S0O_DATA_out22 1'd1 +163 - - - I2S0O_DATA_out23 1'd1 +164 I2S1I_BCK_in 0 no I2S1I_BCK_out 1'd1 +165 I2S1I_WS_in 0 no I2S1I_WS_out 1'd1 +166 I2S1I_DATA_in0 0 no I2S1O_DATA_out0 1'd1 +167 I2S1I_DATA_in1 0 no I2S1O_DATA_out1 1'd1 +168 I2S1I_DATA_in2 0 no I2S1O_DATA_out2 1'd1 +169 I2S1I_DATA_in3 0 no I2S1O_DATA_out3 1'd1 +170 I2S1I_DATA_in4 0 no I2S1O_DATA_out4 1'd1 +171 I2S1I_DATA_in5 0 no I2S1O_DATA_out5 1'd1 +172 I2S1I_DATA_in6 0 no I2S1O_DATA_out6 1'd1 +173 I2S1I_DATA_in7 0 no I2S1O_DATA_out7 1'd1 +174 I2S1I_DATA_in8 0 no I2S1O_DATA_out8 1'd1 +175 I2S1I_DATA_in9 0 no I2S1O_DATA_out9 1'd1 +121 pwm3_fltb 1 no pwm2_out4l 1'd1 +122 pwm3_cap1_in 0 no - 1'd1 +123 pwm3_cap2_in 0 no twai_tx 1'd1 +124 pwm3_cap3_in 0 no twai_bus_off_on 1'd1 +125 - - - twai_clkout 1'd1 +140 I2S0I_DATA_in0 0 no I2S0O_DATA_out0 1'd1 +141 I2S0I_DATA_in1 0 no I2S0O_DATA_out1 1'd1 +142 I2S0I_DATA_in2 0 no I2S0O_DATA_out2 1'd1 +143 I2S0I_DATA_in3 0 no I2S0O_DATA_out3 1'd1 +144 I2S0I_DATA_in4 0 no I2S0O_DATA_out4 1'd1 +145 I2S0I_DATA_in5 0 no I2S0O_DATA_out5 1'd1 +146 I2S0I_DATA_in6 0 no I2S0O_DATA_out6 1'd1 +147 I2S0I_DATA_in7 0 no I2S0O_DATA_out7 1'd1 +148 I2S0I_DATA_in8 0 no I2S0O_DATA_out8 1'd1 +149 I2S0I_DATA_in9 0 no I2S0O_DATA_out9 1'd1 +150 I2S0I_DATA_in10 0 no I2S0O_DATA_out10 1'd1 +151 I2S0I_DATA_in11 0 no I2S0O_DATA_out11 1'd1 +152 I2S0I_DATA_in12 0 no I2S0O_DATA_out12 1'd1 +153 I2S0I_DATA_in13 0 no I2S0O_DATA_out13 1'd1 +154 I2S0I_DATA_in14 0 no I2S0O_DATA_out14 1'd1 +155 I2S0I_DATA_in15 0 no I2S0O_DATA_out15 1'd1 +156 - - - I2S0O_DATA_out16 1'd1 +157 - - - I2S0O_DATA_out17 1'd1 +158 - - - I2S0O_DATA_out18 1'd1 +159 - - - I2S0O_DATA_out19 1'd1 +160 - - - I2S0O_DATA_out20 1'd1 +161 - - - I2S0O_DATA_out21 1'd1 +162 - - - I2S0O_DATA_out22 1'd1 +163 - - - I2S0O_DATA_out23 1'd1 +164 I2S1I_BCK_in 0 no I2S1I_BCK_out 1'd1 +165 I2S1I_WS_in 0 no I2S1I_WS_out 1'd1 +166 I2S1I_DATA_in0 0 no I2S1O_DATA_out0 1'd1 +167 I2S1I_DATA_in1 0 no I2S1O_DATA_out1 1'd1 +168 I2S1I_DATA_in2 0 no I2S1O_DATA_out2 1'd1 +169 I2S1I_DATA_in3 0 no I2S1O_DATA_out3 1'd1 +170 I2S1I_DATA_in4 0 no I2S1O_DATA_out4 1'd1 +171 I2S1I_DATA_in5 0 no I2S1O_DATA_out5 1'd1 +172 I2S1I_DATA_in6 0 no I2S1O_DATA_out6 1'd1 +173 I2S1I_DATA_in7 0 no I2S1O_DATA_out7 1'd1 +174 I2S1I_DATA_in8 0 no I2S1O_DATA_out8 1'd1 +175 I2S1I_DATA_in9 0 no I2S1O_DATA_out9 1'd1 +176 I2S1I_DATA_in10 0 no I2S1O_DATA_out10 1'd1 +177 I2S1I_DATA_in11 0 no I2S1O_DATA_out11 1'd1 +178 I2S1I_DATA_in12 0 no I2S1O_DATA_out12 1'd1 +179 I2S1I_DATA_in13 0 no I2S1O_DATA_out13 1'd1 +180 I2S1I_DATA_in14 0 no I2S1O_DATA_out14 1'd1 +181 I2S1I_DATA_in15 0 no I2S1O_DATA_out15 1'd1 +182 - - - I2S1O_DATA_out16 1'd1 +183 - - - I2S1O_DATA_out17 1'd1 +184 - - - I2S1O_DATA_out18 1'd1 +185 - - - I2S1O_DATA_out19 1'd1 +186 - - - I2S1O_DATA_out20 1'd1 +187 - - - I2S1O_DATA_out21 1'd1 +188 - - - I2S1O_DATA_out22 1'd1 +189 - - - I2S1O_DATA_out23 1'd1 +190 I2S0I_H_SYNC 0 no pwm3_out1h 1'd1 +191 I2S0I_V_SYNC 0 no pwm3_out1l 1'd1 +192 I2S0I_H_ENABLE 0 no pwm3_out2h 1'd1 +193 I2S1I_H_SYNC 0 no pwm3_out2l 1'd1 +194 I2S1I_V_SYNC 0 no pwm3_out3h 1'd1 +195 I2S1I_H_ENABLE 0 no pwm3_out3l 1'd1 +196 - - - pwm3_out4h 1'd1 +197 - - - pwm3_out4l 1'd1 +198 U2RXD_in 0 yes U2TXD_out 1'd1 +199 U2CTS_in 0 yes U2RTS_out 1'd1 200 emac_mdc_i 0 no emac_mdc_o emac_mdc_oe 201 emac_mdi_i 0 no emac_mdo_o emac_mdo_o_e 202 emac_crs_i 0 no emac_crs_o emac_crs_oe 203 emac_col_i 0 no emac_col_o emac_col_oe -204 pcmfsync_in 0 no bt_audio0_irq 1’d1 -205 pcmclk_in 0 no bt_audio1_irq 1’d1 -206 pcmdin 0 no bt_audio2_irq 1’d1 -207 - - - ble_audio0_irq 1’d1 -208 - - - ble_audio1_irq 1’d1 -209 - - - ble_audio2_irq 1’d1 +204 pcmfsync_in 0 no bt_audio0_irq 1'd1 +205 pcmclk_in 0 no bt_audio1_irq 1'd1 +206 pcmdin 0 no bt_audio2_irq 1'd1 +207 - - - ble_audio0_irq 1'd1 +208 - - - ble_audio1_irq 1'd1 +209 - - - ble_audio2_irq 1'd1 210 - - - pcmfsync_out pcmfsync_en 211 - - - pcmclk_out pcmclk_en 212 - - - pcmdout pcmdout_en -213 - - - ble_audio_sync0_p 1’d1 -214 - - - ble_audio_sync1_p 1’d1 -215 - - - ble_audio_sync2_p 1’d1 -224 - - - sig_in_func224 1’d1 -225 - - - sig_in_func225 1’d1 -226 - - - sig_in_func226 1’d1 -227 - - - sig_in_func227 1’d1 -228 - - - sig_in_func228 1’d1 +213 - - - ble_audio_sync0_p 1'd1 +214 - - - ble_audio_sync1_p 1'd1 +215 - - - ble_audio_sync2_p 1'd1 +224 - - - sig_in_func224 1'd1 +225 - - - sig_in_func225 1'd1 +226 - - - sig_in_func226 1'd1 +227 - - - sig_in_func227 1'd1 +228 - - - sig_in_func228 1'd1 diff --git a/Sming/Arch/Esp32/esp32c2-pindefs.txt b/Sming/Arch/Esp32/esp32c2-pindefs.txt index 12da455040..9580723c67 100644 --- a/Sming/Arch/Esp32/esp32c2-pindefs.txt +++ b/Sming/Arch/Esp32/esp32c2-pindefs.txt @@ -39,19 +39,19 @@ signal input default direct_in output enable direct_out 3 SPIWP_in 0 yes SPIWP_out SPIWP_oe yes 4 - - - SPICLK_out_mux SPICLK_oe yes 5 - - - SPICS0_out SPICS0_oe yes -6 U0RXD_in 0 yes U0TXD_out 1’d1 yes -7 U0CTS_in 0 no U0RTS_out 1’d1 no -8 U0DSR_in 0 no U0DTR_out 1’d1 no -9 U1RXD_in 0 no U1TXD_out 1’d1 no -10 U1CTS_in 0 no U1RTS_out 1’d1 no -11 U1DSR_in 0 no U1DTR_out 1’d1 no +6 U0RXD_in 0 yes U0TXD_out 1'd1 yes +7 U0CTS_in 0 no U0RTS_out 1'd1 no +8 U0DSR_in 0 no U0DTR_out 1'd1 no +9 U1RXD_in 0 no U1TXD_out 1'd1 no +10 U1CTS_in 0 no U1RTS_out 1'd1 no +11 U1DSR_in 0 no U1DTR_out 1'd1 no 12 - - - - - - 13 - - - - - - 14 - - - - - - -15 - - - SPIQ_monitor 1’d1 no -16 - - - SPID_monitor 1’d1 no -17 - - - SPIHD_monitor 1’d1 no -18 - - - SPIWP_monitor 1’d1 no +15 - - - SPIQ_monitor 1'd1 no +16 - - - SPID_monitor 1'd1 no +17 - - - SPIHD_monitor 1'd1 no +18 - - - SPIWP_monitor 1'd1 no 19 - - - SPICS1_out SPICS1_oe no 20 - - - - - - 21 - - - - - - @@ -78,12 +78,12 @@ signal input default direct_in output enable direct_out 42 - - - - - - 43 - - - - - - 44 - - - - - - -45 ext_adc_start 0 no ledc_ls_sig_out0 1’d1 no -46 - - - ledc_ls_sig_out1 1’d1 no -47 - - - ledc_ls_sig_out2 1’d1 no -48 - - - ledc_ls_sig_out3 1’d1 no -49 - - - ledc_ls_sig_out4 1’d1 no -50 - - - ledc_ls_sig_out5 1’d1 no +45 ext_adc_start 0 no ledc_ls_sig_out0 1'd1 no +46 - - - ledc_ls_sig_out1 1'd1 no +47 - - - ledc_ls_sig_out2 1'd1 no +48 - - - ledc_ls_sig_out3 1'd1 no +49 - - - ledc_ls_sig_out4 1'd1 no +50 - - - ledc_ls_sig_out5 1'd1 no 51 - - - - - - 52 - - - - - - 53 I2CEXT0_SCL_in 1 no I2CEXT0_SCL_out I2CEXT0_SCL_oe no @@ -122,18 +122,18 @@ signal input default direct_in output enable direct_out 86 - - - - - - 87 - - - - - - 88 - - - - - - -89 - - - ant_sel0 1’d1 no -90 - - - ant_sel1 1’d1 no -91 - - - ant_sel2 1’d1 no -92 - - - ant_sel3 1’d1 no -93 - - - ant_sel4 1’d1 no -94 - - - ant_sel5 1’d1 no -95 - - - ant_sel6 1’d1 no -96 - - - ant_sel7 1’d1 no -97 sig_in_func_97 0 no sig_in_func97 1’d1 no -98 sig_in_func_98 0 no sig_in_func98 1’d1 no -99 sig_in_func_99 0 no sig_in_func99 1’d1 no -100 sig_in_func_100 0 no sig_in_func100 1’d1 no +89 - - - ant_sel0 1'd1 no +90 - - - ant_sel1 1'd1 no +91 - - - ant_sel2 1'd1 no +92 - - - ant_sel3 1'd1 no +93 - - - ant_sel4 1'd1 no +94 - - - ant_sel5 1'd1 no +95 - - - ant_sel6 1'd1 no +96 - - - ant_sel7 1'd1 no +97 sig_in_func_97 0 no sig_in_func97 1'd1 no +98 sig_in_func_98 0 no sig_in_func98 1'd1 no +99 sig_in_func_99 0 no sig_in_func99 1'd1 no +100 sig_in_func_100 0 no sig_in_func100 1'd1 no 101 - - - - - - 102 - - - - - - 103 - - - - - - @@ -156,8 +156,8 @@ signal input default direct_in output enable direct_out 120 - - - - - - 121 - - - - - - 122 - - - - - - -123 - - - CLK_OUT_out1 1’d1 no -124 - - - CLK_OUT_out2 1’d1 no -125 - - - CLK_OUT_out3 1’d1 no +123 - - - CLK_OUT_out1 1'd1 no +124 - - - CLK_OUT_out2 1'd1 no +125 - - - CLK_OUT_out3 1'd1 no 126 - - - - - - 127 - - - - - - diff --git a/Sming/Arch/Esp32/esp32c3-pindefs.txt b/Sming/Arch/Esp32/esp32c3-pindefs.txt index b2cd8847ae..82073a5953 100644 --- a/Sming/Arch/Esp32/esp32c3-pindefs.txt +++ b/Sming/Arch/Esp32/esp32c3-pindefs.txt @@ -39,28 +39,28 @@ signal input default direct_in output enable direct_out 3 SPIWP_in 0 yes SPIWP_out SPIWP_oe yes 4 - - - SPICLK_out_mux SPICLK_oe yes 5 - - - SPICS0_out SPICS0_oe yes -6 U0RXD_in 0 yes U0TXD_out 1’d1 yes -7 U0CTS_in 0 yes U0RTS_out 1’d1 no -8 U0DSR_in 0 no U0DTR_out 1’d1 no -9 U1RXD_in 0 yes U1TXD_out 1’d1 no -10 U1CTS_in 0 yes U1RTS_out 1’d1 no -11 U1DSR_in 0 no U1DTR_out 1’d1 no -12 I2S_MCLK_in 0 no I2S_MCLK_out 1’d1 no -13 I2SO_BCK_in 0 no I2SO_BCK_out 1’d1 no -14 I2SO_WS_in 0 no I2SO_WS_out 1’d1 no -15 I2SI_SD_in 0 no I2SO_SD_out 1’d1 no -16 I2SI_BCK_in 0 no I2SI_BCK_out 1’d1 no -17 I2SI_WS_in 0 no I2SI_WS_out 1’d1 no -18 gpio_bt_priority 0 no gpio_wlan_prio 1’d1 no -19 gpio_bt_active 0 no gpio_wlan_active 1’d1 no -20 - - - - 1’d1 no -21 - - - - 1’d1 no -22 - - - - 1’d1 no -23 - - - - 1’d1 no -24 - - - - 1’d1 no -25 - - - - 1’d1 no -26 - - - - 1’d1 no -27 - - - - 1’d1 no +6 U0RXD_in 0 yes U0TXD_out 1'd1 yes +7 U0CTS_in 0 yes U0RTS_out 1'd1 no +8 U0DSR_in 0 no U0DTR_out 1'd1 no +9 U1RXD_in 0 yes U1TXD_out 1'd1 no +10 U1CTS_in 0 yes U1RTS_out 1'd1 no +11 U1DSR_in 0 no U1DTR_out 1'd1 no +12 I2S_MCLK_in 0 no I2S_MCLK_out 1'd1 no +13 I2SO_BCK_in 0 no I2SO_BCK_out 1'd1 no +14 I2SO_WS_in 0 no I2SO_WS_out 1'd1 no +15 I2SI_SD_in 0 no I2SO_SD_out 1'd1 no +16 I2SI_BCK_in 0 no I2SI_BCK_out 1'd1 no +17 I2SI_WS_in 0 no I2SI_WS_out 1'd1 no +18 gpio_bt_priority 0 no gpio_wlan_prio 1'd1 no +19 gpio_bt_active 0 no gpio_wlan_active 1'd1 no +20 - - - - 1'd1 no +21 - - - - 1'd1 no +22 - - - - 1'd1 no +23 - - - - 1'd1 no +24 - - - - 1'd1 no +25 - - - - 1'd1 no +26 - - - - 1'd1 no +27 - - - - 1'd1 no 28 cpu_gpio_in0 0 no cpu_gpio_out0 cpu_gpio_out_oen0 no 29 cpu_gpio_in1 0 no cpu_gpio_out1 cpu_gpio_out_oen1 no 30 cpu_gpio_in2 0 no cpu_gpio_out2 cpu_gpio_out_oen2 no @@ -69,33 +69,33 @@ signal input default direct_in output enable direct_out 33 cpu_gpio_in5 0 no cpu_gpio_out5 cpu_gpio_out_oen5 no 34 cpu_gpio_in6 0 no cpu_gpio_out6 cpu_gpio_out_oen6 no 35 cpu_gpio_in7 0 no cpu_gpio_out7 cpu_gpio_out_oen7 no -36 - - - usb_jtag_tck 1’d1 no -37 - - - usb_jtag_tms 1’d1 no -38 - - - usb_jtag_tdi 1’d1 no -39 - - - usb_jtag_tdo 1’d1 no -40 - - - - 1’d1 no -41 - - - - 1’d1 no -42 - - - - 1’d1 no -43 - - - - 1’d1 no -44 - - - - 1’d1 no -45 ext_adc_start 0 no ledc_ls_sig_out0 1’d1 no -46 - - - ledc_ls_sig_out1 1’d1 no -47 - - - ledc_ls_sig_out2 1’d1 no -48 - - - ledc_ls_sig_out3 1’d1 no -49 - - - ledc_ls_sig_out4 1’d1 no -50 - - - ledc_ls_sig_out5 1’d1 no -51 rmt_sig_in0 0 no rmt_sig_out0 1’d1 no -52 rmt_sig_in1 0 no rmt_sig_out1 1’d1 no +36 - - - usb_jtag_tck 1'd1 no +37 - - - usb_jtag_tms 1'd1 no +38 - - - usb_jtag_tdi 1'd1 no +39 - - - usb_jtag_tdo 1'd1 no +40 - - - - 1'd1 no +41 - - - - 1'd1 no +42 - - - - 1'd1 no +43 - - - - 1'd1 no +44 - - - - 1'd1 no +45 ext_adc_start 0 no ledc_ls_sig_out0 1'd1 no +46 - - - ledc_ls_sig_out1 1'd1 no +47 - - - ledc_ls_sig_out2 1'd1 no +48 - - - ledc_ls_sig_out3 1'd1 no +49 - - - ledc_ls_sig_out4 1'd1 no +50 - - - ledc_ls_sig_out5 1'd1 no +51 rmt_sig_in0 0 no rmt_sig_out0 1'd1 no +52 rmt_sig_in1 0 no rmt_sig_out1 1'd1 no 53 I2CEXT0_SCL_in 1 no I2CEXT0_SCL_out I2CEXT0_SCL_oe no 54 I2CEXT0_SDA_in 1 no I2CEXT0_SDA_out I2CEXT0_SDA_oe no -55 - - - gpio_sd0_out 1’d1 no -56 - - - gpio_sd1_out 1’d1 no -57 - - - gpio_sd2_out 1’d1 no -58 - - - gpio_sd3_out 1’d1 no -59 - - - I2SO_SD1_out 1’d1 no -60 - - - - 1’d1 no -61 - - - - 1’d1 no -62 - - - - 1’d1 no +55 - - - gpio_sd0_out 1'd1 no +56 - - - gpio_sd1_out 1'd1 no +57 - - - gpio_sd2_out 1'd1 no +58 - - - gpio_sd3_out 1'd1 no +59 - - - I2SO_SD1_out 1'd1 no +60 - - - - 1'd1 no +61 - - - - 1'd1 no +62 - - - - 1'd1 no 63 FSPICLK_in 0 yes FSPICLK_out_mux FSPICLK_oe yes 64 FSPIQ_in 0 yes FSPIQ_out FSPIQ_oe yes 65 FSPID_in 0 yes FSPID_out FSPID_oe yes @@ -107,57 +107,57 @@ signal input default direct_in output enable direct_out 71 - - - FSPICS3_out FSPICS3_oe no 72 - - - FSPICS4_out FSPICS4_oe no 73 - - - FSPICS5_out FSPICS5_oe no -74 twai_rx 1 no twai_tx 1’d1 no -75 - - - twai_bus_off_on 1’d1 no -76 - - - twai_clkout 1’d1 no -77 - - - - 1’d1 no -78 - - - - 1’d1 no -79 - - - - 1’d1 no -80 - - - - 1’d1 no -81 - - - - 1’d1 no -82 - - - - 1’d1 no -83 - - - - 1’d1 no -84 - - - - 1’d1 no -85 - - - - 1’d1 no -86 - - - - 1’d1 no -87 - - - - 1’d1 no -88 - - - - 1’d1 no -89 - - - ant_sel0 1’d1 no -90 - - - ant_sel1 1’d1 no -91 - - - ant_sel2 1’d1 no -92 - - - ant_sel3 1’d1 no -93 - - - ant_sel4 1’d1 no -94 - - - ant_sel5 1’d1 no -95 - - - ant_sel6 1’d1 no -96 - - - ant_sel7 1’d1 no -97 sig_in_func_97 0 no sig_in_func97 1’d1 no -98 sig_in_func_98 0 no sig_in_func98 1’d1 no -99 sig_in_func_99 0 no sig_in_func99 1’d1 no -100 sig_in_func_100 0 no sig_in_func100 1’d1 no -101 - - - - 1’d1 no -102 - - - - 1’d1 no -103 - - - - 1’d1 no -104 - - - - 1’d1 no -105 - - - - 1’d1 no -106 - - - - 1’d1 no -107 - - - - 1’d1 no -108 - - - - 1’d1 no -109 - - - - 1’d1 no -110 - - - - 1’d1 no -111 - - - - 1’d1 no -112 - - - - 1’d1 no -113 - - - - 1’d1 no -114 - - - - 1’d1 no -115 - - - - 1’d1 no -116 - - - - 1’d1 no -117 - - - - 1’d1 no -118 - - - - 1’d1 no -119 - - - - 1’d1 no -120 - - - - 1’d1 no -121 - - - - 1’d1 no -122 - - - - 1’d1 no -123 - - - CLK_OUT_out1 1’d1 no -124 - - - CLK_OUT_out2 1’d1 no -125 - - - CLK_OUT_out3 1’d1 no -126 - - - SPICS1_out 1’d1 no -127 - - - usb_jtag_trst 1’d1 no +74 twai_rx 1 no twai_tx 1'd1 no +75 - - - twai_bus_off_on 1'd1 no +76 - - - twai_clkout 1'd1 no +77 - - - - 1'd1 no +78 - - - - 1'd1 no +79 - - - - 1'd1 no +80 - - - - 1'd1 no +81 - - - - 1'd1 no +82 - - - - 1'd1 no +83 - - - - 1'd1 no +84 - - - - 1'd1 no +85 - - - - 1'd1 no +86 - - - - 1'd1 no +87 - - - - 1'd1 no +88 - - - - 1'd1 no +89 - - - ant_sel0 1'd1 no +90 - - - ant_sel1 1'd1 no +91 - - - ant_sel2 1'd1 no +92 - - - ant_sel3 1'd1 no +93 - - - ant_sel4 1'd1 no +94 - - - ant_sel5 1'd1 no +95 - - - ant_sel6 1'd1 no +96 - - - ant_sel7 1'd1 no +97 sig_in_func_97 0 no sig_in_func97 1'd1 no +98 sig_in_func_98 0 no sig_in_func98 1'd1 no +99 sig_in_func_99 0 no sig_in_func99 1'd1 no +100 sig_in_func_100 0 no sig_in_func100 1'd1 no +101 - - - - 1'd1 no +102 - - - - 1'd1 no +103 - - - - 1'd1 no +104 - - - - 1'd1 no +105 - - - - 1'd1 no +106 - - - - 1'd1 no +107 - - - - 1'd1 no +108 - - - - 1'd1 no +109 - - - - 1'd1 no +110 - - - - 1'd1 no +111 - - - - 1'd1 no +112 - - - - 1'd1 no +113 - - - - 1'd1 no +114 - - - - 1'd1 no +115 - - - - 1'd1 no +116 - - - - 1'd1 no +117 - - - - 1'd1 no +118 - - - - 1'd1 no +119 - - - - 1'd1 no +120 - - - - 1'd1 no +121 - - - - 1'd1 no +122 - - - - 1'd1 no +123 - - - CLK_OUT_out1 1'd1 no +124 - - - CLK_OUT_out2 1'd1 no +125 - - - CLK_OUT_out3 1'd1 no +126 - - - SPICS1_out 1'd1 no +127 - - - usb_jtag_trst 1'd1 no diff --git a/Sming/Arch/Esp32/esp32s2-pindefs.txt b/Sming/Arch/Esp32/esp32s2-pindefs.txt index 5b7ec005cf..360adee6b5 100644 --- a/Sming/Arch/Esp32/esp32s2-pindefs.txt +++ b/Sming/Arch/Esp32/esp32s2-pindefs.txt @@ -84,42 +84,42 @@ signal input default direct_in output enable 9 SPID6_in 0 yes SPID6_out SPID6_oe 10 SPID7_in 0 yes SPID7_out SPID7_oe 11 SPIDQS_in 0 yes SPIDQS_out SPIDQS_oe -14 U0RXD_in 0 yes U0TXD_out 1’d1 -15 U0CTS_in 0 yes U0RTS_out 1’d1 -16 U0DSR_in 0 no U0DTR_out 1’d1 -17 U1RXD_in 0 yes U1TXD_out 1’d1 -18 U1CTS_in 0 yes U1RTS_out 1’d1 -21 U1DSR_in 0 no U1DTR_out 1’d1 -23 I2S0O_BCK_in 0 no I2S0O_BCK_out 1’d1 -25 I2S0O_WS_in 0 no I2S0O_WS_out 1’d1 -27 I2S0I_BCK_in 0 no I2S0I_BCK_out 1’d1 -28 I2S0I_WS_in 0 no I2S0I_WS_out 1’d1 +14 U0RXD_in 0 yes U0TXD_out 1'd1 +15 U0CTS_in 0 yes U0RTS_out 1'd1 +16 U0DSR_in 0 no U0DTR_out 1'd1 +17 U1RXD_in 0 yes U1TXD_out 1'd1 +18 U1CTS_in 0 yes U1RTS_out 1'd1 +21 U1DSR_in 0 no U1DTR_out 1'd1 +23 I2S0O_BCK_in 0 no I2S0O_BCK_out 1'd1 +25 I2S0O_WS_in 0 no I2S0O_WS_out 1'd1 +27 I2S0I_BCK_in 0 no I2S0I_BCK_out 1'd1 +28 I2S0I_WS_in 0 no I2S0I_WS_out 1'd1 29 I2CEXT0_SCL_in 1 no I2CEXT0_SCL_out I2CEXT0_SCL_oe 30 I2CEXT0_SDA_in 1 no I2CEXT0_SDA_out I2CEXT0_SDA_oe -39 pcnt_sig_ch0_in0 0 no gpio_wlan_prio 1’d1 -40 pcnt_sig_ch1_in0 0 no gpio_wlan_active 1’d1 -41 pcnt_ctrl_ch0_in0 0 no - 1’d1 -42 pcnt_ctrl_ch1_in0 0 no - 1’d1 -43 pcnt_sig_ch0_in1 0 no - 1’d1 -44 pcnt_sig_ch1_in1 0 no - 1’d1 -45 pcnt_ctrl_ch0_in1 0 no - 1’d1 -46 pcnt_ctrl_ch1_in1 0 no - 1’d1 -47 pcnt_sig_ch0_in2 0 no - 1’d1 -48 pcnt_sig_ch1_in2 0 no - 1’d1 -49 pcnt_ctrl_ch0_in2 0 no - 1’d1 -50 pcnt_ctrl_ch1_in2 0 no - 1’d1 -51 pcnt_sig_ch0_in3 0 no - 1’d1 -52 pcnt_sig_ch1_in3 0 no - 1’d1 -53 pcnt_ctrl_ch0_in3 0 no - 1’d1 -54 pcnt_ctrl_ch1_in3 0 no - 1’d1 -64 usb_otg_iddig_in 0 no - 1’d1 -65 usb_otg_avalid_in 0 no - 1’d1 -66 usb_srp_bvalid_in 0 no usb_otg_idpullup 1’d1 -67 usb_otg_vbusvalid_in 0 no usb_otg_dppulldown 1’d1 -68 usb_srp_sessend_in 0 no usb_otg_dmpulldown 1’d1 -69 - - - usb_otg_drvvbus 1’d1 -70 - - - usb_srp_chrgvbus 1’d1 -71 - - - usb_srp_dischrgvbus 1’d1 +39 pcnt_sig_ch0_in0 0 no gpio_wlan_prio 1'd1 +40 pcnt_sig_ch1_in0 0 no gpio_wlan_active 1'd1 +41 pcnt_ctrl_ch0_in0 0 no - 1'd1 +42 pcnt_ctrl_ch1_in0 0 no - 1'd1 +43 pcnt_sig_ch0_in1 0 no - 1'd1 +44 pcnt_sig_ch1_in1 0 no - 1'd1 +45 pcnt_ctrl_ch0_in1 0 no - 1'd1 +46 pcnt_ctrl_ch1_in1 0 no - 1'd1 +47 pcnt_sig_ch0_in2 0 no - 1'd1 +48 pcnt_sig_ch1_in2 0 no - 1'd1 +49 pcnt_ctrl_ch0_in2 0 no - 1'd1 +50 pcnt_ctrl_ch1_in2 0 no - 1'd1 +51 pcnt_sig_ch0_in3 0 no - 1'd1 +52 pcnt_sig_ch1_in3 0 no - 1'd1 +53 pcnt_ctrl_ch0_in3 0 no - 1'd1 +54 pcnt_ctrl_ch1_in3 0 no - 1'd1 +64 usb_otg_iddig_in 0 no - 1'd1 +65 usb_otg_avalid_in 0 no - 1'd1 +66 usb_srp_bvalid_in 0 no usb_otg_idpullup 1'd1 +67 usb_otg_vbusvalid_in 0 no usb_otg_dppulldown 1'd1 +68 usb_srp_sessend_in 0 no usb_otg_dmpulldown 1'd1 +69 - - - usb_otg_drvvbus 1'd1 +70 - - - usb_srp_chrgvbus 1'd1 +71 - - - usb_srp_dischrgvbus 1'd1 72 SPI3_CLK_in 0 no SPI3_CLK_out_mux SPI3_CLK_oe 73 SPI3_Q_in 0 no SPI3_Q_out SPI3_Q_oe 74 SPI3_D_in 0 no SPI3_D_out SPI3_D_oe @@ -127,28 +127,28 @@ signal input default direct_in output enable 76 SPI3_CS0_in 0 no SPI3_CS0_out SPI3_CS0_oe 77 - - - SPI3_CS1_out SPI3_CS1_oe 78 - - - SPI3_CS2_out SPI3_CS2_oe -79 - - - ledc_ls_sig_out0 1’d1 -80 - - - ledc_ls_sig_out1 1’d1 -81 - - - ledc_ls_sig_out2 1’d1 -82 - - - ledc_ls_sig_out3 1’d1 -83 rmt_sig_in0 0 no ledc_ls_sig_out4 1’d1 -84 rmt_sig_in1 0 no ledc_ls_sig_out5 1’d1 -85 rmt_sig_in2 0 no ledc_ls_sig_out6 1’d1 -86 rmt_sig_in3 0 no ledc_ls_sig_out7 1’d1 -87 - - - rmt_sig_out0 1’d1 -88 - - - rmt_sig_out1 1’d1 -89 - - - rmt_sig_out2 1’d1 -90 - - - rmt_sig_out3 1’d1 +79 - - - ledc_ls_sig_out0 1'd1 +80 - - - ledc_ls_sig_out1 1'd1 +81 - - - ledc_ls_sig_out2 1'd1 +82 - - - ledc_ls_sig_out3 1'd1 +83 rmt_sig_in0 0 no ledc_ls_sig_out4 1'd1 +84 rmt_sig_in1 0 no ledc_ls_sig_out5 1'd1 +85 rmt_sig_in2 0 no ledc_ls_sig_out6 1'd1 +86 rmt_sig_in3 0 no ledc_ls_sig_out7 1'd1 +87 - - - rmt_sig_out0 1'd1 +88 - - - rmt_sig_out1 1'd1 +89 - - - rmt_sig_out2 1'd1 +90 - - - rmt_sig_out3 1'd1 95 I2CEXT1_SCL_in 1 no I2CEXT1_SCL_out I2CEXT1_SCL_oe 96 I2CEXT1_SDA_in 1 no I2CEXT1_SDA_out I2CEXT1_SDA_oe -100 - - - gpio_sd0_out 1’d1 -101 - - - gpio_sd1_out 1’d1 -102 - - - gpio_sd2_out 1’d1 -103 - - - gpio_sd3_out 1’d1 -104 - - - gpio_sd4_out 1’d1 -105 - - - gpio_sd5_out 1’d1 -106 - - - gpio_sd6_out 1’d1 -107 - - - gpio_sd7_out 1’d1 +100 - - - gpio_sd0_out 1'd1 +101 - - - gpio_sd1_out 1'd1 +102 - - - gpio_sd2_out 1'd1 +103 - - - gpio_sd3_out 1'd1 +104 - - - gpio_sd4_out 1'd1 +105 - - - gpio_sd5_out 1'd1 +106 - - - gpio_sd6_out 1'd1 +107 - - - gpio_sd7_out 1'd1 108 FSPICLK_in 0 yes FSPICLK_out_mux FSPICLK_oe 109 FSPIQ_in 0 yes FSPIQ_out FSPIQ_oe 110 FSPID_in 0 yes FSPID_out FSPID_oe @@ -164,9 +164,9 @@ signal input default direct_in output enable 120 - - - FSPICS3_out FSPICS3_oe 121 - - - FSPICS4_out FSPICS4_oe 122 - - - FSPICS5_out FSPICS5_oe -123 twai_rx 1 no twai_tx 1’d1 -124 - - - twai_bus_off_on 1’d1 -125 - - - twai_clkout 1’d1 +123 twai_rx 1 no twai_tx 1'd1 +124 - - - twai_bus_off_on 1'd1 +125 - - - twai_clkout 1'd1 126 - - - SUBSPICLK_out_mux SUBSPICLK_oe 127 SUBSPIQ_in 0 yes SUBSPIQ_out SUBSPIQ_oe 128 SUBSPID_in 0 yes SUBSPID_out SUBSPID_oe @@ -181,57 +181,57 @@ signal input default direct_in output enable 137 - - - FSPICD_out FSPICD_oe 139 - - - SPI3_CD_out SPI3_CD_oe 140 - - - SPI3_DQS_out SPI3_DQS_oe -143 I2S0I_DATA_in0 0 no I2S0O_DATA_out0 1’d1 -144 I2S0I_DATA_in1 0 no I2S0O_DATA_out1 1’d1 -145 I2S0I_DATA_in2 0 no I2S0O_DATA_out2 1’d1 -146 I2S0I_DATA_in3 0 no I2S0O_DATA_out3 1’d1 -147 I2S0I_DATA_in4 0 no I2S0O_DATA_out4 1’d1 -148 I2S0I_DATA_in5 0 no I2S0O_DATA_out5 1’d1 -149 I2S0I_DATA_in6 0 no I2S0O_DATA_out6 1’d1 -150 I2S0I_DATA_in7 0 no I2S0O_DATA_out7 1’d1 -151 I2S0I_DATA_in8 0 no I2S0O_DATA_out8 1’d1 -152 I2S0I_DATA_in9 0 no I2S0O_DATA_out9 1’d1 -153 I2S0I_DATA_in10 0 no I2S0O_DATA_out10 1’d1 -154 I2S0I_DATA_in11 0 no I2S0O_DATA_out11 1’d1 -155 I2S0I_DATA_in12 0 no I2S0O_DATA_out12 1’d1 -156 I2S0I_DATA_in13 0 no I2S0O_DATA_out13 1’d1 -157 I2S0I_DATA_in14 0 no I2S0O_DATA_out14 1’d1 -158 I2S0I_DATA_in15 0 no I2S0O_DATA_out15 1’d1 -159 - - - I2S0O_DATA_out16 1’d1 -160 - - - I2S0O_DATA_out17 1’d1 -161 - - - I2S0O_DATA_out18 1’d1 -162 - - - I2S0O_DATA_out19 1’d1 -163 - - - I2S0O_DATA_out20 1’d1 -164 - - - I2S0O_DATA_out21 1’d1 -165 - - - I2S0O_DATA_out22 1’d1 -166 - - - I2S0O_DATA_out23 1’d1 +143 I2S0I_DATA_in0 0 no I2S0O_DATA_out0 1'd1 +144 I2S0I_DATA_in1 0 no I2S0O_DATA_out1 1'd1 +145 I2S0I_DATA_in2 0 no I2S0O_DATA_out2 1'd1 +146 I2S0I_DATA_in3 0 no I2S0O_DATA_out3 1'd1 +147 I2S0I_DATA_in4 0 no I2S0O_DATA_out4 1'd1 +148 I2S0I_DATA_in5 0 no I2S0O_DATA_out5 1'd1 +149 I2S0I_DATA_in6 0 no I2S0O_DATA_out6 1'd1 +150 I2S0I_DATA_in7 0 no I2S0O_DATA_out7 1'd1 +151 I2S0I_DATA_in8 0 no I2S0O_DATA_out8 1'd1 +152 I2S0I_DATA_in9 0 no I2S0O_DATA_out9 1'd1 +153 I2S0I_DATA_in10 0 no I2S0O_DATA_out10 1'd1 +154 I2S0I_DATA_in11 0 no I2S0O_DATA_out11 1'd1 +155 I2S0I_DATA_in12 0 no I2S0O_DATA_out12 1'd1 +156 I2S0I_DATA_in13 0 no I2S0O_DATA_out13 1'd1 +157 I2S0I_DATA_in14 0 no I2S0O_DATA_out14 1'd1 +158 I2S0I_DATA_in15 0 no I2S0O_DATA_out15 1'd1 +159 - - - I2S0O_DATA_out16 1'd1 +160 - - - I2S0O_DATA_out17 1'd1 +161 - - - I2S0O_DATA_out18 1'd1 +162 - - - I2S0O_DATA_out19 1'd1 +163 - - - I2S0O_DATA_out20 1'd1 +164 - - - I2S0O_DATA_out21 1'd1 +165 - - - I2S0O_DATA_out22 1'd1 +166 - - - I2S0O_DATA_out23 1'd1 167 SUBSPID4_in 0 yes SUBSPID4_out SUBSPID4_oe 168 SUBSPID5_in 0 yes SUBSPID5_out SUBSPID5_oe 169 SUBSPID6_in 0 yes SUBSPID6_out SUBSPID6_oe 170 SUBSPID7_in 0 yes SUBSPID7_out SUBSPID7_oe 171 SUBSPIDQS_in 0 yes SUBSPIDQS_out SUBSPIDQS_oe -193 I2S0I_H_SYNC 0 no - 1’d1 -194 I2S0I_V_SYNC 0 no - 1’d1 -195 I2S0I_H_ENABLE 0 no - 1’d1 -215 - - - ant_sel0 1’d1 -216 - - - ant_sel1 1’d1 -217 - - - ant_sel2 1’d1 -218 - - - ant_sel3 1’d1 -219 - - - ant_sel4 1’d1 -220 - - - ant_sel5 1’d1 -221 - - - ant_sel6 1’d1 -222 - - - ant_sel7 1’d1 -223 sig_in_func_223 0 no sig_in_func223 1’d1 -224 sig_in_func_224 0 no sig_in_func224 1’d1 -225 sig_in_func_225 0 no sig_in_func225 1’d1 -226 sig_in_func_226 0 no sig_in_func226 1’d1 -227 sig_in_func_227 0 no sig_in_func227 1’d1 -235 pro_alonegpio_in0 0 no pro_alonegpio_out0 1’d1 -236 pro_alonegpio_in1 0 no pro_alonegpio_out1 1’d1 -237 pro_alonegpio_in2 0 no pro_alonegpio_out2 1’d1 -238 pro_alonegpio_in3 0 no pro_alonegpio_out3 1’d1 -239 pro_alonegpio_in4 0 no pro_alonegpio_out4 1’d1 -240 pro_alonegpio_in5 0 no pro_alonegpio_out5 1’d1 -241 pro_alonegpio_in6 0 no pro_alonegpio_out6 1’d1 -242 pro_alonegpio_in7 0 no pro_alonegpio_out7 1’d1 -251 - - - clk_i2s_mux 1’d1 +193 I2S0I_H_SYNC 0 no - 1'd1 +194 I2S0I_V_SYNC 0 no - 1'd1 +195 I2S0I_H_ENABLE 0 no - 1'd1 +215 - - - ant_sel0 1'd1 +216 - - - ant_sel1 1'd1 +217 - - - ant_sel2 1'd1 +218 - - - ant_sel3 1'd1 +219 - - - ant_sel4 1'd1 +220 - - - ant_sel5 1'd1 +221 - - - ant_sel6 1'd1 +222 - - - ant_sel7 1'd1 +223 sig_in_func_223 0 no sig_in_func223 1'd1 +224 sig_in_func_224 0 no sig_in_func224 1'd1 +225 sig_in_func_225 0 no sig_in_func225 1'd1 +226 sig_in_func_226 0 no sig_in_func226 1'd1 +227 sig_in_func_227 0 no sig_in_func227 1'd1 +235 pro_alonegpio_in0 0 no pro_alonegpio_out0 1'd1 +236 pro_alonegpio_in1 0 no pro_alonegpio_out1 1'd1 +237 pro_alonegpio_in2 0 no pro_alonegpio_out2 1'd1 +238 pro_alonegpio_in3 0 no pro_alonegpio_out3 1'd1 +239 pro_alonegpio_in4 0 no pro_alonegpio_out4 1'd1 +240 pro_alonegpio_in5 0 no pro_alonegpio_out5 1'd1 +241 pro_alonegpio_in6 0 no pro_alonegpio_out6 1'd1 +242 pro_alonegpio_in7 0 no pro_alonegpio_out7 1'd1 +251 - - - clk_i2s_mux 1'd1 diff --git a/Sming/Arch/Esp32/esp32s3-pindefs.txt b/Sming/Arch/Esp32/esp32s3-pindefs.txt index 7383d6dea8..0d60b85d27 100644 --- a/Sming/Arch/Esp32/esp32s3-pindefs.txt +++ b/Sming/Arch/Esp32/esp32s3-pindefs.txt @@ -110,60 +110,60 @@ signal input default direct_in output enable direct_out 9 SPID6_in 0 yes SPID6_out SPID6_oe yes 10 SPID7_in 0 yes SPID7_out SPID7_oe yes 11 SPIDQS_in 0 yes SPIDQS_out SPIDQS_oe yes -12 U0RXD_in 0 yes U0TXD_out 1’d1 yes -13 U0CTS_in 0 yes U0RTS_out 1’d1 yes -14 U0DSR_in 0 no U0DTR_out 1’d1 no -15 U1RXD_in 0 yes U1TXD_out 1’d1 yes -16 U1CTS_in 0 yes U1RTS_out 1’d1 yes -17 U1DSR_in 0 no U1DTR_out 1’d1 no -18 U2RXD_in 0 no U2TXD_out 1’d1 no -19 U2CTS_in 0 no U2RTS_out 1’d1 no -20 U2DSR_in 0 no U2DTR_out 1’d1 no -21 I2S1_MCLK_in 0 no I2S1_MCLK_out 1’d1 no -22 I2S0O_BCK_in 0 no I2S0O_BCK_out 1’d1 no -23 I2S0_MCLK_in 0 no I2S0_MCLK_out 1’d1 no -24 I2S0O_WS_in 0 no I2S0O_WS_out 1’d1 no -25 I2S0I_SD_in 0 no I2S0O_SD_out 1’d1 no -26 I2S0I_BCK_in 0 no I2S0I_BCK_out 1’d1 no -27 I2S0I_WS_in 0 no I2S0I_WS_out 1’d1 no -28 I2S1O_BCK_in 0 no I2S1O_BCK_out 1’d1 no -29 I2S1O_WS_in 0 no I2S1O_WS_out 1’d1 no -30 I2S1I_SD_in 0 no I2S1O_SD_out 1’d1 no -31 I2S1I_BCK_in 0 no I2S1I_BCK_out 1’d1 no -32 I2S1I_WS_in 0 no I2S1I_WS_out 1’d1 no -33 pcnt_sig_ch0_in0 0 no - 1’d1 no -34 pcnt_sig_ch1_in0 0 no - 1’d1 no -35 pcnt_ctrl_ch0_in0 0 no - 1’d1 - -36 pcnt_ctrl_ch1_in0 0 no - 1’d1 - -37 pcnt_sig_ch0_in1 0 no - 1’d1 - -38 pcnt_sig_ch1_in1 0 no - 1’d1 - -39 pcnt_ctrl_ch0_in1 0 no - 1’d1 - -40 pcnt_ctrl_ch1_in1 0 no - 1’d1 - -41 pcnt_sig_ch0_in2 0 no - 1’d1 - -42 pcnt_sig_ch1_in2 0 no - 1’d1 - -43 pcnt_ctrl_ch0_in2 0 no - 1’d1 - -44 pcnt_ctrl_ch1_in2 0 no - 1’d1 - -45 pcnt_sig_ch0_in3 0 no - 1’d1 - -46 pcnt_sig_ch1_in3 0 no - 1’d1 - -47 pcnt_ctrl_ch0_in3 0 no - 1’d1 - -48 pcnt_ctrl_ch1_in3 0 no - 1’d1 - -49 - - - - 1’d1 - -50 - - - - 1’d1 - -51 I2S0I_SD1_in 0 no - 1’d1 - -52 I2S0I_SD2_in 0 no - 1’d1 - -53 I2S0I_SD3_in 0 no - 1’d1 - -54 Core1_gpio_in7 0 no Core1_gpio_out7 1’d1 no -55 - - - - 1’d1 - -56 - - - - 1’d1 - -57 - - - - 1’d1 - -58 usb_otg_iddig_in 0 no - 1’d1 - -59 usb_otg_avalid_in 0 no - 1’d1 - -60 usb_srp_bvalid_in 0 no usb_otg_idpullup 1’d1 no -61 usb_otg_vbusvalid_in 0 no usb_otg_dppulldown 1’d1 no -62 usb_srp_sessend_in 0 no usb_otg_dmpulldown 1’d1 no -63 - - - usb_otg_drvvbus 1’d1 no -64 - - - usb_srp_chrgvbus 1’d1 no -65 - - - usb_srp_dischrgvbus 1’d1 no +12 U0RXD_in 0 yes U0TXD_out 1'd1 yes +13 U0CTS_in 0 yes U0RTS_out 1'd1 yes +14 U0DSR_in 0 no U0DTR_out 1'd1 no +15 U1RXD_in 0 yes U1TXD_out 1'd1 yes +16 U1CTS_in 0 yes U1RTS_out 1'd1 yes +17 U1DSR_in 0 no U1DTR_out 1'd1 no +18 U2RXD_in 0 no U2TXD_out 1'd1 no +19 U2CTS_in 0 no U2RTS_out 1'd1 no +20 U2DSR_in 0 no U2DTR_out 1'd1 no +21 I2S1_MCLK_in 0 no I2S1_MCLK_out 1'd1 no +22 I2S0O_BCK_in 0 no I2S0O_BCK_out 1'd1 no +23 I2S0_MCLK_in 0 no I2S0_MCLK_out 1'd1 no +24 I2S0O_WS_in 0 no I2S0O_WS_out 1'd1 no +25 I2S0I_SD_in 0 no I2S0O_SD_out 1'd1 no +26 I2S0I_BCK_in 0 no I2S0I_BCK_out 1'd1 no +27 I2S0I_WS_in 0 no I2S0I_WS_out 1'd1 no +28 I2S1O_BCK_in 0 no I2S1O_BCK_out 1'd1 no +29 I2S1O_WS_in 0 no I2S1O_WS_out 1'd1 no +30 I2S1I_SD_in 0 no I2S1O_SD_out 1'd1 no +31 I2S1I_BCK_in 0 no I2S1I_BCK_out 1'd1 no +32 I2S1I_WS_in 0 no I2S1I_WS_out 1'd1 no +33 pcnt_sig_ch0_in0 0 no - 1'd1 no +34 pcnt_sig_ch1_in0 0 no - 1'd1 no +35 pcnt_ctrl_ch0_in0 0 no - 1'd1 - +36 pcnt_ctrl_ch1_in0 0 no - 1'd1 - +37 pcnt_sig_ch0_in1 0 no - 1'd1 - +38 pcnt_sig_ch1_in1 0 no - 1'd1 - +39 pcnt_ctrl_ch0_in1 0 no - 1'd1 - +40 pcnt_ctrl_ch1_in1 0 no - 1'd1 - +41 pcnt_sig_ch0_in2 0 no - 1'd1 - +42 pcnt_sig_ch1_in2 0 no - 1'd1 - +43 pcnt_ctrl_ch0_in2 0 no - 1'd1 - +44 pcnt_ctrl_ch1_in2 0 no - 1'd1 - +45 pcnt_sig_ch0_in3 0 no - 1'd1 - +46 pcnt_sig_ch1_in3 0 no - 1'd1 - +47 pcnt_ctrl_ch0_in3 0 no - 1'd1 - +48 pcnt_ctrl_ch1_in3 0 no - 1'd1 - +49 - - - - 1'd1 - +50 - - - - 1'd1 - +51 I2S0I_SD1_in 0 no - 1'd1 - +52 I2S0I_SD2_in 0 no - 1'd1 - +53 I2S0I_SD3_in 0 no - 1'd1 - +54 Core1_gpio_in7 0 no Core1_gpio_out7 1'd1 no +55 - - - - 1'd1 - +56 - - - - 1'd1 - +57 - - - - 1'd1 - +58 usb_otg_iddig_in 0 no - 1'd1 - +59 usb_otg_avalid_in 0 no - 1'd1 - +60 usb_srp_bvalid_in 0 no usb_otg_idpullup 1'd1 no +61 usb_otg_vbusvalid_in 0 no usb_otg_dppulldown 1'd1 no +62 usb_srp_sessend_in 0 no usb_otg_dmpulldown 1'd1 no +63 - - - usb_otg_drvvbus 1'd1 no +64 - - - usb_srp_chrgvbus 1'd1 no +65 - - - usb_srp_dischrgvbus 1'd1 no 66 SPI3_CLK_in 0 no SPI3_CLK_out_mux SPI3_CLK_oe no 67 SPI3_Q_in 0 no SPI3_Q_out SPI3_Q_oe no 68 SPI3_D_in 0 no SPI3_D_out SPI3_D_oe no @@ -171,34 +171,34 @@ signal input default direct_in output enable direct_out 70 SPI3_WP_in 0 no SPI3_WP_out SPI3_WP_oe no 71 SPI3_CS0_in 0 no SPI3_CS0_out SPI3_CS0_oe no 72 - - - SPI3_CS1_out SPI3_CS1_oe no -73 ext_adc_start 0 no ledc_ls_sig_out0 1’d1 no -74 - - - ledc_ls_sig_out1 1’d1 no -75 - - - ledc_ls_sig_out2 1’d1 no -76 - - - ledc_ls_sig_out3 1’d1 no -77 - - - ledc_ls_sig_out4 1’d1 no -78 - - - ledc_ls_sig_out5 1’d1 no -79 - - - ledc_ls_sig_out6 1’d1 no -80 - - - ledc_ls_sig_out7 1’d1 no -81 rmt_sig_in0 0 no rmt_sig_out0 1’d1 no -82 rmt_sig_in1 0 no rmt_sig_out1 1’d1 no -83 rmt_sig_in2 0 no rmt_sig_out2 1’d1 no -84 rmt_sig_in3 0 no rmt_sig_out3 1’d1 no -85 - - - - 1’d1 - -86 - - - - 1’d1 - -87 - - - - 1’d1 - -88 - - - - 1’d1 - +73 ext_adc_start 0 no ledc_ls_sig_out0 1'd1 no +74 - - - ledc_ls_sig_out1 1'd1 no +75 - - - ledc_ls_sig_out2 1'd1 no +76 - - - ledc_ls_sig_out3 1'd1 no +77 - - - ledc_ls_sig_out4 1'd1 no +78 - - - ledc_ls_sig_out5 1'd1 no +79 - - - ledc_ls_sig_out6 1'd1 no +80 - - - ledc_ls_sig_out7 1'd1 no +81 rmt_sig_in0 0 no rmt_sig_out0 1'd1 no +82 rmt_sig_in1 0 no rmt_sig_out1 1'd1 no +83 rmt_sig_in2 0 no rmt_sig_out2 1'd1 no +84 rmt_sig_in3 0 no rmt_sig_out3 1'd1 no +85 - - - - 1'd1 - +86 - - - - 1'd1 - +87 - - - - 1'd1 - +88 - - - - 1'd1 - 89 I2CEXT0_SCL_in 1 no I2CEXT0_SCL_out I2CEXT0_SCL_oe no 90 I2CEXT0_SDA_in 1 no I2CEXT0_SDA_out I2CEXT0_SDA_oe no 91 I2CEXT1_SCL_in 1 no I2CEXT1_SCL_out I2CEXT1_SCL_oe no 92 I2CEXT1_SDA_in 1 no I2CEXT1_SDA_out I2CEXT1_SDA_oe no -93 - - - gpio_sd0_out 1’d1 no -94 - - - gpio_sd1_out 1’d1 no -95 - - - gpio_sd2_out 1’d1 no -96 - - - gpio_sd3_out 1’d1 no -97 - - - gpio_sd4_out 1’d1 no -98 - - - gpio_sd5_out 1’d1 no -99 - - - gpio_sd6_out 1’d1 no -100 - - - gpio_sd7_out 1’d1 no +93 - - - gpio_sd0_out 1'd1 no +94 - - - gpio_sd1_out 1'd1 no +95 - - - gpio_sd2_out 1'd1 no +96 - - - gpio_sd3_out 1'd1 no +97 - - - gpio_sd4_out 1'd1 no +98 - - - gpio_sd5_out 1'd1 no +99 - - - gpio_sd6_out 1'd1 no +100 - - - gpio_sd7_out 1'd1 no 101 FSPICLK_in 0 yes FSPICLK_out_mux FSPICLK_oe yes 102 FSPIQ_in 0 yes FSPIQ_out FSPIQ_oe yes 103 FSPID_in 0 yes FSPID_out FSPID_oe yes @@ -214,9 +214,9 @@ signal input default direct_in output enable direct_out 113 - - - FSPICS3_out FSPICS3_oe no 114 - - - FSPICS4_out FSPICS4_oe no 115 - - - FSPICS5_out FSPICS5_oe no -116 twai_rx 1 no twai_tx 1’d1 no -117 - - - twai_bus_off_on 1’d1 no -118 - - - twai_clkout 1’d1 no +116 twai_rx 1 no twai_tx 1'd1 no +117 - - - twai_bus_off_on 1'd1 no +118 - - - twai_clkout 1'd1 no 119 - - - SUBSPICLK_out_mux SUBSPICLK_oe no 120 SUBSPIQ_in 0 yes SUBSPIQ_out SUBSPIQ_oe yes 121 SUBSPID_in 0 yes SUBSPID_out SUBSPID_oe yes @@ -226,56 +226,56 @@ signal input default direct_in output enable direct_out 125 - - - SUBSPICS1_out SUBSPICS1_oe yes 126 - - - FSPIDQS_out FSPIDQS_oe yes 127 - - - SPI3_CS2_out SPI3_CS2_oe no -128 - - - I2S0O_SD1_out 1’d1 no -129 Core1_gpio_in0 0 no Core1_gpio_out0 1’d1 no -130 Core1_gpio_in1 0 no Core1_gpio_out1 1’d1 no -131 Core1_gpio_in2 0 no Core1_gpio_out2 1’d1 no -132 - - - LCD_CS 1’d1 no -133 CAM_DATA_in0 0 no LCD_DATA_out0 1’d1 no -134 CAM_DATA_in1 0 no LCD_DATA_out1 1’d1 no -135 CAM_DATA_in2 0 no LCD_DATA_out2 1’d1 no -136 CAM_DATA_in3 0 no LCD_DATA_out3 1’d1 no -137 CAM_DATA_in4 0 no LCD_DATA_out4 1’d1 no -138 CAM_DATA_in5 0 no LCD_DATA_out5 1’d1 no -139 CAM_DATA_in6 0 no LCD_DATA_out6 1’d1 no -140 CAM_DATA_in7 0 no LCD_DATA_out7 1’d1 no -141 CAM_DATA_in8 0 no LCD_DATA_out8 1’d1 no -142 CAM_DATA_in9 0 no LCD_DATA_out9 1’d1 no -143 CAM_DATA_in10 0 no LCD_DATA_out10 1’d1 no -144 CAM_DATA_in11 0 no LCD_DATA_out11 1’d1 no -145 CAM_DATA_in12 0 no LCD_DATA_out12 1’d1 no -146 CAM_DATA_in13 0 no LCD_DATA_out13 1’d1 no -147 CAM_DATA_in14 0 no LCD_DATA_out14 1’d1 no -148 CAM_DATA_in15 0 no LCD_DATA_out15 1’d1 no -149 CAM_PCLK 0 no CAM_CLK 1’d1 no -150 CAM_H_ENABLE 0 no LCD_H_ENABLE 1’d1 no -151 CAM_H_SYNC 0 no LCD_H_SYNC 1’d1 no -152 CAM_V_SYNC 0 no LCD_V_SYNC 1’d1 no -153 - - - LCD_DC 1’d1 no -154 - - - LCD_PCLK 1’d1 no +128 - - - I2S0O_SD1_out 1'd1 no +129 Core1_gpio_in0 0 no Core1_gpio_out0 1'd1 no +130 Core1_gpio_in1 0 no Core1_gpio_out1 1'd1 no +131 Core1_gpio_in2 0 no Core1_gpio_out2 1'd1 no +132 - - - LCD_CS 1'd1 no +133 CAM_DATA_in0 0 no LCD_DATA_out0 1'd1 no +134 CAM_DATA_in1 0 no LCD_DATA_out1 1'd1 no +135 CAM_DATA_in2 0 no LCD_DATA_out2 1'd1 no +136 CAM_DATA_in3 0 no LCD_DATA_out3 1'd1 no +137 CAM_DATA_in4 0 no LCD_DATA_out4 1'd1 no +138 CAM_DATA_in5 0 no LCD_DATA_out5 1'd1 no +139 CAM_DATA_in6 0 no LCD_DATA_out6 1'd1 no +140 CAM_DATA_in7 0 no LCD_DATA_out7 1'd1 no +141 CAM_DATA_in8 0 no LCD_DATA_out8 1'd1 no +142 CAM_DATA_in9 0 no LCD_DATA_out9 1'd1 no +143 CAM_DATA_in10 0 no LCD_DATA_out10 1'd1 no +144 CAM_DATA_in11 0 no LCD_DATA_out11 1'd1 no +145 CAM_DATA_in12 0 no LCD_DATA_out12 1'd1 no +146 CAM_DATA_in13 0 no LCD_DATA_out13 1'd1 no +147 CAM_DATA_in14 0 no LCD_DATA_out14 1'd1 no +148 CAM_DATA_in15 0 no LCD_DATA_out15 1'd1 no +149 CAM_PCLK 0 no CAM_CLK 1'd1 no +150 CAM_H_ENABLE 0 no LCD_H_ENABLE 1'd1 no +151 CAM_H_SYNC 0 no LCD_H_SYNC 1'd1 no +152 CAM_V_SYNC 0 no LCD_V_SYNC 1'd1 no +153 - - - LCD_DC 1'd1 no +154 - - - LCD_PCLK 1'd1 no 155 SUBSPID4_in 0 yes SUBSPID4_out SUBSPID4_oe no 156 SUBSPID5_in 0 yes SUBSPID5_out SUBSPID5_oe no 157 SUBSPID6_in 0 yes SUBSPID6_out SUBSPID6_oe no 158 SUBSPID7_in 0 yes SUBSPID7_out SUBSPID7_oe no 159 SUBSPIDQS_in 0 yes SUBSPIDQS_out SUBSPIDQS_oe no -160 pwm0_sync0_in 0 no pwm0_out0a 1’d1 no -161 pwm0_sync1_in 0 no pwm0_out0b 1’d1 no -162 pwm0_sync2_in 0 no pwm0_out1a 1’d1 no -163 pwm0_f0_in 0 no pwm0_out1b 1’d1 no -164 pwm0_f1_in 0 no pwm0_out2a 1’d1 no -165 pwm0_f2_in 0 no pwm0_out2b 1’d1 no -166 pwm0_cap0_in 0 no pwm1_out0a 1’d1 no -167 pwm0_cap1_in 0 no pwm1_out0b 1’d1 no -168 pwm0_cap2_in 0 no pwm1_out1a 1’d1 no -169 pwm1_sync0_in 0 no pwm1_out1b 1’d1 no -170 pwm1_sync1_in 0 no pwm1_out2a 1’d1 no -171 pwm1_sync2_in 0 no pwm1_out2b 1’d1 no -172 pwm1_f0_in 0 no sdhost_cclk_out_1 1’d1 no -173 pwm1_f1_in 0 no sdhost_cclk_out_2 1’d1 no -174 pwm1_f2_in 0 no sdhost_rst_n_1 1’d1 no -175 pwm1_cap0_in 0 no sdhost_rst_n_2 1’d1 no -176 pwm1_cap1_in 0 no sdhost_ccmd_od_pullup_en_n 1’d1 no -177 pwm1_cap2_in 0 no sdio_tohost_int_out 1’d1 no +160 pwm0_sync0_in 0 no pwm0_out0a 1'd1 no +161 pwm0_sync1_in 0 no pwm0_out0b 1'd1 no +162 pwm0_sync2_in 0 no pwm0_out1a 1'd1 no +163 pwm0_f0_in 0 no pwm0_out1b 1'd1 no +164 pwm0_f1_in 0 no pwm0_out2a 1'd1 no +165 pwm0_f2_in 0 no pwm0_out2b 1'd1 no +166 pwm0_cap0_in 0 no pwm1_out0a 1'd1 no +167 pwm0_cap1_in 0 no pwm1_out0b 1'd1 no +168 pwm0_cap2_in 0 no pwm1_out1a 1'd1 no +169 pwm1_sync0_in 0 no pwm1_out1b 1'd1 no +170 pwm1_sync1_in 0 no pwm1_out2a 1'd1 no +171 pwm1_sync2_in 0 no pwm1_out2b 1'd1 no +172 pwm1_f0_in 0 no sdhost_cclk_out_1 1'd1 no +173 pwm1_f1_in 0 no sdhost_cclk_out_2 1'd1 no +174 pwm1_f2_in 0 no sdhost_rst_n_1 1'd1 no +175 pwm1_cap0_in 0 no sdhost_rst_n_2 1'd1 no +176 pwm1_cap1_in 0 no sdhost_ccmd_od_pullup_en_n 1'd1 no +177 pwm1_cap2_in 0 no sdio_tohost_int_out 1'd1 no 178 sdhost_ccmd_in_1 1 no sdhost_ccmd_out_1 sdhost_ccmd_out_en_1 no 179 sdhost_ccmd_in_2 1 no sdhost_ccmd_out_2 sdhost_ccmd_out_en_2 no 180 sdhost_cdata_in_10 1 no sdhost_cdata_out_10 sdhost_cdata_out_en_10 no @@ -286,31 +286,31 @@ signal input default direct_in output enable direct_out 185 sdhost_cdata_in_15 1 no sdhost_cdata_out_15 sdhost_cdata_out_en_15 no 186 sdhost_cdata_in_16 1 no sdhost_cdata_out_16 sdhost_cdata_out_en_16 no 187 sdhost_cdata_in_17 1 no sdhost_cdata_out_17 sdhost_cdata_out_en_17 no -188 - - - - 1’d1 - -189 - - - - 1’d1 - -190 - - - - 1’d1 - -191 - - - - 1’d1 - -192 sdhost_data_strobe_1 0 no - 1’d1 - -193 sdhost_data_strobe_2 0 no - 1’d1 - -194 sdhost_card_detect_n_1 0 no - 1’d1 - -195 sdhost_card_detect_n_2 0 no - 1’d1 - -196 sdhost_card_write_prt_1 0 no - 1’d1 - -197 sdhost_card_write_prt_2 0 no - 1’d1 - -198 sdhost_card_int_n_1 0 no - 1’d1 - -199 sdhost_card_int_n_2 0 no - 1’d1 - -200 - - - - 1’d1 no -201 - - - - 1’d1 no -202 - - - - 1’d1 no -203 - - - - 1’d1 no -204 - - - - 1’d1 no -205 - - - - 1’d1 no -206 - - - - 1’d1 no -207 - - - - 1’d1 no -208 sig_in_func_208 0 no sig_in_func208 1’d1 no -209 sig_in_func_209 0 no sig_in_func209 1’d1 no -210 sig_in_func_210 0 no sig_in_func210 1’d1 no -211 sig_in_func_211 0 no sig_in_func211 1’d1 no -212 sig_in_func_212 0 no sig_in_func212 1’d1 no +188 - - - - 1'd1 - +189 - - - - 1'd1 - +190 - - - - 1'd1 - +191 - - - - 1'd1 - +192 sdhost_data_strobe_1 0 no - 1'd1 - +193 sdhost_data_strobe_2 0 no - 1'd1 - +194 sdhost_card_detect_n_1 0 no - 1'd1 - +195 sdhost_card_detect_n_2 0 no - 1'd1 - +196 sdhost_card_write_prt_1 0 no - 1'd1 - +197 sdhost_card_write_prt_2 0 no - 1'd1 - +198 sdhost_card_int_n_1 0 no - 1'd1 - +199 sdhost_card_int_n_2 0 no - 1'd1 - +200 - - - - 1'd1 no +201 - - - - 1'd1 no +202 - - - - 1'd1 no +203 - - - - 1'd1 no +204 - - - - 1'd1 no +205 - - - - 1'd1 no +206 - - - - 1'd1 no +207 - - - - 1'd1 no +208 sig_in_func_208 0 no sig_in_func208 1'd1 no +209 sig_in_func_209 0 no sig_in_func209 1'd1 no +210 sig_in_func_210 0 no sig_in_func210 1'd1 no +211 sig_in_func_211 0 no sig_in_func211 1'd1 no +212 sig_in_func_212 0 no sig_in_func212 1'd1 no 213 sdhost_cdata_in_20 1 no sdhost_cdata_out_20 sdhost_cdata_out_en_20 no 214 sdhost_cdata_in_21 1 no sdhost_cdata_out_21 sdhost_cdata_out_en_21 no 215 sdhost_cdata_in_22 1 no sdhost_cdata_out_22 sdhost_cdata_out_en_22 no @@ -319,38 +319,38 @@ signal input default direct_in output enable direct_out 218 sdhost_cdata_in_25 1 no sdhost_cdata_out_25 sdhost_cdata_out_en_25 no 219 sdhost_cdata_in_26 1 no sdhost_cdata_out_26 sdhost_cdata_out_en_26 no 220 sdhost_cdata_in_27 1 no sdhost_cdata_out_27 sdhost_cdata_out_en_27 no -221 pro_alonegpio_in0 0 no pro_alonegpio_out0 1’d1 no -222 pro_alonegpio_in1 0 no pro_alonegpio_out1 1’d1 no -223 pro_alonegpio_in2 0 no pro_alonegpio_out2 1’d1 no -224 pro_alonegpio_in3 0 no pro_alonegpio_out3 1’d1 no -225 pro_alonegpio_in4 0 no pro_alonegpio_out4 1’d1 no -226 pro_alonegpio_in5 0 no pro_alonegpio_out5 1’d1 no -227 pro_alonegpio_in6 0 no pro_alonegpio_out6 1’d1 no -228 pro_alonegpio_in7 0 no pro_alonegpio_out7 1’d1 no -229 - - - - 1’d1 - -230 - - - - 1’d1 - -231 - - - - 1’d1 - -232 - - - - 1’d1 - -233 - - - - 1’d1 - -234 - - - - 1’d1 - -235 - - - - 1’d1 - -236 - - - - 1’d1 - -237 - - - - 1’d1 - -238 - - - - 1’d1 - -239 - - - - 1’d1 - -240 - - - - 1’d1 - -241 - - - - 1’d1 - -242 - - - - 1’d1 - -243 - - - - 1’d1 - -244 - - - - 1’d1 - -245 - - - - 1’d1 - -246 - - - - 1’d1 - -247 - - - - 1’d1 - -248 - - - - 1’d1 - -249 - - - - 1’d1 - -250 - - - - 1’d1 - -251 usb_jtag_tdo_bridge 0 no usb_jtag_trst 1’d1 no -252 Core1_gpio_in3 0 no Core1_gpio_out3 1’d1 no -253 Core1_gpio_in4 0 no Core1_gpio_out4 1’d1 no -254 Core1_gpio_in5 0 no Core1_gpio_out5 1’d1 no -255 Core1_gpio_in6 0 no Core1_gpio_out6 1’d1 no +221 pro_alonegpio_in0 0 no pro_alonegpio_out0 1'd1 no +222 pro_alonegpio_in1 0 no pro_alonegpio_out1 1'd1 no +223 pro_alonegpio_in2 0 no pro_alonegpio_out2 1'd1 no +224 pro_alonegpio_in3 0 no pro_alonegpio_out3 1'd1 no +225 pro_alonegpio_in4 0 no pro_alonegpio_out4 1'd1 no +226 pro_alonegpio_in5 0 no pro_alonegpio_out5 1'd1 no +227 pro_alonegpio_in6 0 no pro_alonegpio_out6 1'd1 no +228 pro_alonegpio_in7 0 no pro_alonegpio_out7 1'd1 no +229 - - - - 1'd1 - +230 - - - - 1'd1 - +231 - - - - 1'd1 - +232 - - - - 1'd1 - +233 - - - - 1'd1 - +234 - - - - 1'd1 - +235 - - - - 1'd1 - +236 - - - - 1'd1 - +237 - - - - 1'd1 - +238 - - - - 1'd1 - +239 - - - - 1'd1 - +240 - - - - 1'd1 - +241 - - - - 1'd1 - +242 - - - - 1'd1 - +243 - - - - 1'd1 - +244 - - - - 1'd1 - +245 - - - - 1'd1 - +246 - - - - 1'd1 - +247 - - - - 1'd1 - +248 - - - - 1'd1 - +249 - - - - 1'd1 - +250 - - - - 1'd1 - +251 usb_jtag_tdo_bridge 0 no usb_jtag_trst 1'd1 no +252 Core1_gpio_in3 0 no Core1_gpio_out3 1'd1 no +253 Core1_gpio_in4 0 no Core1_gpio_out4 1'd1 no +254 Core1_gpio_in5 0 no Core1_gpio_out5 1'd1 no +255 Core1_gpio_in6 0 no Core1_gpio_out6 1'd1 no diff --git a/Sming/Arch/Esp8266/Components/driver/hw_timer.cpp b/Sming/Arch/Esp8266/Components/driver/hw_timer.cpp index b7a8641980..3d15c4525a 100644 --- a/Sming/Arch/Esp8266/Components/driver/hw_timer.cpp +++ b/Sming/Arch/Esp8266/Components/driver/hw_timer.cpp @@ -36,6 +36,28 @@ static void IRAM_ATTR nmi_handler() nmi_callback.func(nmi_callback.arg); } +/* + * The `ETS_FRC_TIMER1_NMI_INTR_ATTACH` macro calls SDK `NmiTimSetFunc` which + * doesn't actually disable NMI (a known bug). + * If we subsequently enable FRC interrupts, the timer won't work so we need to properly + * disable NMI manually. + * + * The NmiTimSetFunc code looks like this: + * + * uint32_t value = REG_READ(NMI_INT_ENABLE_REG); + * value &= ~0x1f; + * value |= 0x0f; + * REG_WRITE(NMI_INT_ENABLE_REG, value); + * + * Note that there is no published documentation for this register. + * Clearing it to zero appears to work but may have unintended side-effects. + */ +static void IRAM_ATTR hw_timer1_disable_nmi() +{ + auto value = REG_READ(NMI_INT_ENABLE_REG); + REG_WRITE(NMI_INT_ENABLE_REG, value & ~0x1f); +} + void hw_timer1_attach_interrupt(hw_timer_source_type_t source_type, hw_timer_callback_t callback, void* arg) { if(source_type == TIMER_NMI_SOURCE) { @@ -47,10 +69,18 @@ void hw_timer1_attach_interrupt(hw_timer_source_type_t source_type, hw_timer_cal ETS_FRC_TIMER1_NMI_INTR_ATTACH(nmi_handler); } } else { + hw_timer1_disable_nmi(); ETS_FRC_TIMER1_INTR_ATTACH(callback, arg); } } +void IRAM_ATTR hw_timer1_detach_interrupt(void) +{ + hw_timer1_disable(); + hw_timer1_disable_nmi(); + ETS_FRC_TIMER1_INTR_ATTACH(NULL, NULL); +} + void hw_timer_init(void) { constexpr uint32_t FRC2_ENABLE_TIMER = BIT7; diff --git a/Sming/Arch/Esp8266/Components/driver/include/driver/hw_timer.h b/Sming/Arch/Esp8266/Components/driver/include/driver/hw_timer.h index 069f8dafc1..04395c83c7 100644 --- a/Sming/Arch/Esp8266/Components/driver/include/driver/hw_timer.h +++ b/Sming/Arch/Esp8266/Components/driver/include/driver/hw_timer.h @@ -80,7 +80,12 @@ void IRAM_ATTR hw_timer1_attach_interrupt(hw_timer_source_type_t source_type, hw * @brief Enable the timer * @param div * @param intr_type - * @param auto_load + * @param auto_load true for repeating timer, false for one-shot + * + * Note: With one-shot timer application callback must stop the timer when it is no longer required. + * This is to reduce callback latency. + * If this is not done, timer will trigger again when timer counter wraps around to 0. + * For /16 divisor this is only 1.7s. */ inline void IRAM_ATTR hw_timer1_enable(hw_timer_clkdiv_t div, hw_timer_intr_type_t intr_type, bool auto_load) { @@ -118,12 +123,7 @@ __forceinline void IRAM_ATTR hw_timer1_disable(void) /** * @brief Detach interrupt from the timer */ -__forceinline void IRAM_ATTR hw_timer1_detach_interrupt(void) -{ - hw_timer1_disable(); - ETS_FRC_TIMER1_NMI_INTR_ATTACH(NULL); - ETS_FRC_TIMER1_INTR_ATTACH(NULL, NULL); -} +void hw_timer1_detach_interrupt(void); /** * @brief Get timer1 count diff --git a/Sming/Arch/Esp8266/Components/driver/new-pwm/pwm.c b/Sming/Arch/Esp8266/Components/driver/new-pwm/pwm.c index 9fc9188e60..356f7865a1 100644 --- a/Sming/Arch/Esp8266/Components/driver/new-pwm/pwm.c +++ b/Sming/Arch/Esp8266/Components/driver/new-pwm/pwm.c @@ -115,6 +115,7 @@ static struct timer_regs* timer = (struct timer_regs*)(0x60000600); static void IRAM_ATTR pwm_intr_handler(void* param) { + (void)param; if ((pwm_state.current_set[pwm_state.current_phase].off_mask == 0) && (pwm_state.current_set[pwm_state.current_phase].on_mask == 0)) { pwm_state.current_set = pwm_state.next_set; diff --git a/Sming/Arch/Esp8266/Components/driver/pwm.rst b/Sming/Arch/Esp8266/Components/driver/pwm.rst index a4e87d5259..fdcdbcb2f6 100644 --- a/Sming/Arch/Esp8266/Components/driver/pwm.rst +++ b/Sming/Arch/Esp8266/Components/driver/pwm.rst @@ -3,8 +3,8 @@ PWM: Pulse-Width Modulation The driver interface is defined in the ESP8266 SDK. -Build variables ---------------- +Configuration Variables +----------------------- .. envvar:: ENABLE_CUSTOM_PWM diff --git a/Sming/Arch/Esp8266/Components/driver/uart.cpp b/Sming/Arch/Esp8266/Components/driver/uart.cpp index be211390ba..046fae03bd 100644 --- a/Sming/Arch/Esp8266/Components/driver/uart.cpp +++ b/Sming/Arch/Esp8266/Components/driver/uart.cpp @@ -246,7 +246,7 @@ void IRAM_ATTR handle_uart_interrupt(uint8_t uart_nr, smg_uart_t* uart) /** @brief UART interrupt service routine * @note both UARTS share the same ISR, although UART1 only supports transmit */ -void IRAM_ATTR uart_isr(void* arg) +void IRAM_ATTR uart_isr(void*) { handle_uart_interrupt(UART0, uartInstances[UART0]); handle_uart_interrupt(UART1, uartInstances[UART1]); diff --git a/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/app/dhcpserver.h b/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/app/dhcpserver.h index b6f7a0b321..c84c4b79b3 100644 --- a/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/app/dhcpserver.h +++ b/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/app/dhcpserver.h @@ -5,7 +5,7 @@ typedef struct dhcps_state{ sint16_t state; } dhcps_state; -// ����dhcpclient�Զ����һ��DHCP msg�ṹ�� +// dhcpclient DHCP msg typedef struct dhcps_msg { uint8_t op, htype, hlen, hops; uint8_t xid[4]; diff --git a/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/app/espconn.h b/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/app/espconn.h index 992a06a57e..162b2ed0f0 100644 --- a/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/app/espconn.h +++ b/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/app/espconn.h @@ -228,7 +228,7 @@ extern sint8 espconn_create(struct espconn *espconn); /****************************************************************************** * FunctionName : espconn_tcp_get_max_con - * Description : get the number of simulatenously active TCP connections + * Description : get the number of simultaneously active TCP connections * Parameters : none * Returns : none *******************************************************************************/ @@ -237,7 +237,7 @@ extern uint8 espconn_tcp_get_max_con(void); /****************************************************************************** * FunctionName : espconn_tcp_set_max_con - * Description : set the number of simulatenously active TCP connections + * Description : set the number of simultaneously active TCP connections * Parameters : num -- total number * Returns : none *******************************************************************************/ @@ -245,7 +245,7 @@ extern uint8 espconn_tcp_get_max_con(void); extern sint8 espconn_tcp_set_max_con(uint8 num); /****************************************************************************** * FunctionName : espconn_tcp_get_max_con_allow - * Description : get the count of simulatenously active connections on the server + * Description : get the count of simultaneously active connections on the server * Parameters : espconn -- espconn to get the count * Returns : result *******************************************************************************/ @@ -254,7 +254,7 @@ extern sint8 espconn_tcp_get_max_con_allow(struct espconn *espconn); /****************************************************************************** * FunctionName : espconn_tcp_set_max_con_allow - * Description : set the count of simulatenously active connections on the server + * Description : set the count of simultaneously active connections on the server * Parameters : espconn -- espconn to set the count * Returns : result *******************************************************************************/ diff --git a/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/icmp.h b/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/icmp.h index 9bcb7bc439..62f0ae1908 100644 --- a/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/icmp.h +++ b/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/icmp.h @@ -74,9 +74,6 @@ enum icmp_te_type { * is splitted to two u16_t like ICMP echo needs it. * This header is also used for other ICMP types that do not * use the data part. - * ICMPײṹ - * ICMPײкܴԣ - * ýṹͬICMPġ */ PACK_STRUCT_BEGIN struct icmp_echo_hdr { @@ -91,11 +88,11 @@ PACK_STRUCT_END # include "arch/epstruct.h" #endif -//ȡICMPײֶ +// ICMP #define ICMPH_TYPE(hdr) ((hdr)->type) #define ICMPH_CODE(hdr) ((hdr)->code) -/** Combines type and code to an u16_t ICMPײֶдӦֵ*/ +/** Combines type and code to an u16_t ICMP */ #define ICMPH_TYPE_SET(hdr, t) ((hdr)->type = (t)) #define ICMPH_CODE_SET(hdr, c) ((hdr)->code = (c)) diff --git a/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/netif.h b/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/netif.h index 8bf1375210..eb1cda3f03 100644 --- a/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/netif.h +++ b/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/netif.h @@ -143,15 +143,15 @@ struct netif { ip_addr_t gw; /** This function is called by the network device driver - * to pass a packet up the TCP/IP stack. IPݰ*/ + * to pass a packet up the TCP/IP stack. */ netif_input_fn input; /** This function is called by the IP module when it wants * to send a packet on the interface. This function typically - * first resolves the hardware address, then sends the packet. IPݰ*/ + * first resolves the hardware address, then sends the packet. */ netif_output_fn output; /** This function is called by the ARP module when it wants * to send a packet on the interface. This function outputs - * the pbuf as-is on the link medium. ײݰ*/ + * the pbuf as-is on the link medium. */ netif_linkoutput_fn linkoutput; #if LWIP_NETIF_STATUS_CALLBACK /** This function is called when the netif state is set to up or down @@ -164,7 +164,7 @@ struct netif { netif_status_callback_fn link_callback; #endif /* LWIP_NETIF_LINK_CALLBACK */ /** This field can be set by the device driver and could point - * to state information for the device. ֶΣָײ豸Ϣ*/ + * to state information for the device. */ void *state; #if LWIP_DHCP /** the DHCP client state information for this netif */ @@ -178,17 +178,17 @@ struct netif { /* the hostname for this netif, NULL is a valid value */ char* hostname; #endif /* LWIP_NETIF_HOSTNAME */ - /** maximum transfer unit (in bytes) ýӿݰȣ1500*/ + /** maximum transfer unit (in bytes) 1500*/ u16_t mtu; - /** number of bytes used in hwaddrýӿַ */ + /** number of bytes used in hwaddr */ u8_t hwaddr_len; - /** link level hardware address of this interface ýӿַ*/ + /** link level hardware address of this interface */ u8_t hwaddr[NETIF_MAX_HWADDR_LEN]; - /** flags (see NETIF_FLAG_ above) ýӿ״ֶ̬*/ + /** flags (see NETIF_FLAG_ above) */ u8_t flags; - /** descriptive abbreviation ýӿڵ*/ + /** descriptive abbreviation */ char name[2]; - /** number of this interface ýӿڵı*/ + /** number of this interface */ u8_t num; #if LWIP_SNMP /** link type (from "snmp_ifType" enum from snmp.h) */ @@ -216,9 +216,9 @@ struct netif { u8_t *addr_hint; #endif /* LWIP_NETIF_HWADDRHINT */ #if ENABLE_LOOPBACK - /* List of packets to be queued for ourselves. ָ͸Լݰpbuf*/ - struct pbuf *loop_first;//һ - struct pbuf *loop_last;//һ + /* List of packets to be queued for ourselves. */ + struct pbuf *loop_first; + struct pbuf *loop_last; #if LWIP_LOOPBACK_MAX_PBUFS u16_t loop_cnt_current; #endif /* LWIP_LOOPBACK_MAX_PBUFS */ diff --git a/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/opt.h b/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/opt.h index 8240363ae6..3713821306 100644 --- a/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/opt.h +++ b/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/opt.h @@ -244,7 +244,7 @@ #endif /** - * MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections. + * MEMP_NUM_TCP_PCB: the number of simultaneously active TCP connections. * (requires the LWIP_TCP option) */ #ifndef MEMP_NUM_TCP_PCB diff --git a/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/sys.h b/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/sys.h index 9536aa82d5..1278836687 100644 --- a/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/sys.h +++ b/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/sys.h @@ -165,7 +165,7 @@ void sys_msleep(u32_t ms); /* only has a (close to) 1 jiffy resolution. */ /** Create a new mbox of specified size * @param mbox pointer to the mbox to create - * @param size (miminum) number of messages in this mbox + * @param size (minimum) number of messages in this mbox * @return ERR_OK if successful, another err_t otherwise */ err_t sys_mbox_new(sys_mbox_t *mbox, int size); /** Post a message to an mbox - may not fail diff --git a/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/tcp_impl.h b/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/tcp_impl.h index e9e3c7096d..1857dba6de 100644 --- a/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/tcp_impl.h +++ b/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/tcp_impl.h @@ -156,14 +156,14 @@ u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb)ICACHE_FLASH_ATTR; #endif PACK_STRUCT_BEGIN struct tcp_hdr { - PACK_STRUCT_FIELD(u16_t src); //Դ�˿� - PACK_STRUCT_FIELD(u16_t dest); //Ŀ�Ķ˿� - PACK_STRUCT_FIELD(u32_t seqno); //��� - PACK_STRUCT_FIELD(u32_t ackno); //Ӧ����� - PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags);//�ײ�����+����λ+��־λ - PACK_STRUCT_FIELD(u16_t wnd); //���ڴ�С - PACK_STRUCT_FIELD(u16_t chksum); //У��� - PACK_STRUCT_FIELD(u16_t urgp); //����ָ�� + PACK_STRUCT_FIELD(u16_t src); + PACK_STRUCT_FIELD(u16_t dest); + PACK_STRUCT_FIELD(u32_t seqno); + PACK_STRUCT_FIELD(u32_t ackno); + PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags); + PACK_STRUCT_FIELD(u16_t wnd); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u16_t urgp); } PACK_STRUCT_STRUCT; PACK_STRUCT_END #ifdef PACK_STRUCT_USE_INCLUDES diff --git a/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/udp.h b/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/udp.h index cb53d33e70..0872a75528 100644 --- a/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/udp.h +++ b/Sming/Arch/Esp8266/Components/esp-lwip/include/lwip/udp.h @@ -115,7 +115,7 @@ struct udp_pcb { /** user-supplied argument for the recv callback */ void *recv_arg; }; -/* udp_pcbs export for exernal reference (e.g. SNMP agent) */ +/* udp_pcbs export for external reference (e.g. SNMP agent) */ extern struct udp_pcb *udp_pcbs; /* The following functions is the application layer interface to the diff --git a/Sming/Arch/Esp8266/Components/esp-lwip/mem_manager.h b/Sming/Arch/Esp8266/Components/esp-lwip/mem_manager.h index d3007fd043..3e1f6ae515 100644 --- a/Sming/Arch/Esp8266/Components/esp-lwip/mem_manager.h +++ b/Sming/Arch/Esp8266/Components/esp-lwip/mem_manager.h @@ -13,7 +13,7 @@ #include -/*------------------------��������------------------------*/ +/*------------------------------------------------*/ #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE #ifndef IOT_SIP_MODE @@ -71,7 +71,7 @@ static const unsigned short heapSTRUCT_SIZE = ( sizeof( xBlockLink ) + portBYTE_ //static size_t xFreeBytesRemaining = ( ( size_t ) configADJUSTED_HEAP_SIZE ) & ( ( size_t ) ~portBYTE_ALIGNMENT_MASK ); -/*------------------------��������-----------------------------------*/ +/*-----------------------------------------------------------*/ //static void prvInsertBlockIntoFreeList( xBlockLink *pxBlockToInsert ) ;//ICACHE_FLASH_ATTR; diff --git a/Sming/Arch/Esp8266/Components/esp-open-lwip/esp-open-lwip.patch b/Sming/Arch/Esp8266/Components/esp-open-lwip/esp-open-lwip.patch index 574453dd21..8857c5d95d 100644 --- a/Sming/Arch/Esp8266/Components/esp-open-lwip/esp-open-lwip.patch +++ b/Sming/Arch/Esp8266/Components/esp-open-lwip/esp-open-lwip.patch @@ -190,7 +190,7 @@ index 1e46ee5..cfc10f8 100644 ipaddr != NULL ? ip4_addr2_16(ipaddr) : 0, \ ipaddr != NULL ? ip4_addr3_16(ipaddr) : 0, \ diff --git a/lwip/app/dhcpserver.c b/lwip/app/dhcpserver.c -index ddb5984..ed8f912 100644 +index ddb5984..631bd34 100644 --- a/lwip/app/dhcpserver.c +++ b/lwip/app/dhcpserver.c @@ -1,5 +1,5 @@ @@ -263,7 +263,31 @@ index ddb5984..ed8f912 100644 m->op = DHCP_REPLY; m->htype = DHCP_HTYPE_ETHERNET; -@@ -485,7 +478,7 @@ static uint8_t ICACHE_FLASH_ATTR parse_options(uint8_t *optptr, sint16_t len) +@@ -325,6 +318,7 @@ static void ICACHE_FLASH_ATTR send_offer(struct dhcps_msg *m) + return; + } + SendOffer_err_t = udp_sendto( pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT ); ++ (void)SendOffer_err_t; + #if DHCPS_DEBUG + os_printf("dhcps: send_offer>>udp_sendto result %x\n",SendOffer_err_t); + #endif +@@ -391,6 +385,7 @@ static void ICACHE_FLASH_ATTR send_nak(struct dhcps_msg *m) + return; + } + SendNak_err_t = udp_sendto( pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT ); ++ (void)SendNak_err_t; + #if DHCPS_DEBUG + os_printf("dhcps: send_nak>>udp_sendto result %x\n",SendNak_err_t); + #endif +@@ -458,6 +453,7 @@ static void ICACHE_FLASH_ATTR send_ack(struct dhcps_msg *m) + return; + } + SendAck_err_t = udp_sendto( pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT ); ++ (void)SendAck_err_t; + #if DHCPS_DEBUG + os_printf("dhcps: send_ack>>udp_sendto result %x\n",SendAck_err_t); + #endif +@@ -485,7 +481,7 @@ static uint8_t ICACHE_FLASH_ATTR parse_options(uint8_t *optptr, sint16_t len) bool is_dhcp_parse_end = false; struct dhcps_state s; @@ -272,7 +296,7 @@ index ddb5984..ed8f912 100644 u8_t *end = optptr + len; u16_t type = 0; -@@ -573,7 +566,7 @@ static uint8_t ICACHE_FLASH_ATTR parse_options(uint8_t *optptr, sint16_t len) +@@ -573,7 +569,7 @@ static uint8_t ICACHE_FLASH_ATTR parse_options(uint8_t *optptr, sint16_t len) /////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////// static sint16_t ICACHE_FLASH_ATTR parse_msg(struct dhcps_msg *m, u16_t len) @@ -281,6 +305,25 @@ index ddb5984..ed8f912 100644 if(os_memcmp((char *)m->options, &magic_cookie, sizeof(magic_cookie)) == 0){ +@@ -744,6 +740,10 @@ static void ICACHE_FLASH_ATTR handle_dhcp(void *arg, + struct ip_addr *addr, + uint16_t port) + { ++ (void)arg; ++ (void)pcb; ++ (void)addr; ++ (void)port; + struct dhcps_msg *pmsg_dhcps = NULL; + sint16_t tlen = 0; + u16_t i = 0; +@@ -1087,7 +1087,6 @@ void ICACHE_FLASH_ATTR dhcps_coarse_tmr(void) + bool ICACHE_FLASH_ATTR wifi_softap_set_dhcps_offer_option(uint8 level, void* optarg) + { + bool offer_flag = true; +- uint8 option = 0; + if (optarg == NULL && wifi_softap_dhcps_status() == false) + return false; + --- a/include/lwip/tcp_impl.h +++ b/include/lwip/tcp_impl.h @@ -130,7 +130,7 @@ u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb)ICACHE_FLASH_ATTR; @@ -490,7 +533,7 @@ index 77ef471..0e4936a 100644 static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; #endif diff --git a/lwip/core/dhcp.c b/lwip/core/dhcp.c -index 342543e..92ad15b 100644 +index 342543e..cd7d0c3 100644 --- a/lwip/core/dhcp.c +++ b/lwip/core/dhcp.c @@ -137,6 +137,9 @@ u8_t dhcp_rx_options_given[DHCP_OPTION_IDX_MAX]; @@ -503,6 +546,15 @@ index 342543e..92ad15b 100644 /* DHCP client state machine functions */ static err_t dhcp_discover(struct netif *netif); +@@ -586,7 +589,7 @@ dhcp_handle_ack(struct netif *netif) + #if LWIP_DNS + /* DNS servers */ + n = 0; +- while(dhcp_option_given(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n) && (n < DNS_MAX_SERVERS)) { ++ while((n < DNS_MAX_SERVERS) && dhcp_option_given(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n)) { + ip_addr_t dns_addr; + ip4_addr_set_u32(&dns_addr, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n))); + dns_setserver(n, &dns_addr); diff --git a/lwip/core/ipv4/ip_addr.c b/lwip/core/ipv4/ip_addr.c index 81db807..dd6964e 100644 --- a/lwip/core/ipv4/ip_addr.c @@ -568,10 +620,20 @@ index 52cd0b0..0ea6ab0 100644 espconn_msg *pdelete_msg = NULL; struct tcp_pcb *pcb = NULL; diff --git a/lwip/core/sntp.c b/lwip/core/sntp.c -index 677de93..b645772 100644 +index 677de93..73a0dcf 100644 --- a/lwip/core/sntp.c +++ b/lwip/core/sntp.c -@@ -295,7 +295,6 @@ static ip_addr_t sntp_last_server_address; +@@ -268,7 +268,9 @@ struct sntp_server { + }; + static struct sntp_server sntp_servers[SNTP_MAX_SERVERS]; + ++#if SNTP_GET_SERVERS_FROM_DHCP + static u8_t sntp_set_servers_from_dhcp; ++#endif + #if SNTP_SUPPORT_MULTIPLE_SERVERS + /** The currently used server (initialized to 0) */ + static u8_t sntp_current_server; +@@ -295,7 +297,6 @@ static ip_addr_t sntp_last_server_address; * to compare against in response */ static u32_t sntp_last_timestamp_sent[2]; #endif /* SNTP_CHECK_RESPONSE >= 2 */ @@ -579,7 +641,14 @@ index 677de93..b645772 100644 //uint32 current_stamp_1 = 0; //uint32 current_stamp_2 = 0; uint32 realtime_stamp = 0; - +@@ -361,7 +362,6 @@ sntp_mktm_r(const time_t * tim_p ,struct tm *res ,int is_gmtime) + { + long days, rem; + time_t lcltime; +- int i; + int y; + int yleap; + const int *ip; diff --git a/include/lwip/sntp.h b/include/lwip/sntp.h index 14e802e..61d36de 100644 --- a/include/lwip/sntp.h @@ -618,3 +687,30 @@ index e2f8e9a..8f4d170 100644 pos += oversize_used; oversize -= oversize_used; space -= oversize_used; +diff --git a/include/lwip/debug.h b/include/lwip/debug.h +index d8359ea..344e274 100644 +--- a/include/lwip/debug.h ++++ b/include/lwip/debug.h +@@ -62,8 +62,8 @@ + #define LWIP_DBG_HALT 0x08U + + #ifndef LWIP_NOASSERT +-#define LWIP_ASSERT(message, assertion) do { if(!(assertion)) \ +- LWIP_PLATFORM_ASSERT(message); } while(0) ++#define LWIP_ASSERT(message, assertion) do { if(!(assertion)) {\ ++ LWIP_PLATFORM_ASSERT(message); }} while(0) + #else /* LWIP_NOASSERT */ + #define LWIP_ASSERT(message, assertion) + #endif /* LWIP_NOASSERT */ +diff --git a/lwip/core/pbuf.c b/lwip/core/pbuf.c +index 6196784..6fd0eb9 100644 +--- a/lwip/core/pbuf.c ++++ b/lwip/core/pbuf.c +@@ -103,6 +103,7 @@ static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; + void ICACHE_FLASH_ATTR + pbuf_free_ooseq_new(void* arg) + { ++ (void)arg; + struct tcp_pcb* pcb; + struct tcp_seg *head = NULL; + struct tcp_seg *seg1 = NULL; diff --git a/Sming/Arch/Esp8266/Components/esp8266/README.rst b/Sming/Arch/Esp8266/Components/esp8266/README.rst index 37fa9c0e7b..1466bcdefb 100644 --- a/Sming/Arch/Esp8266/Components/esp8266/README.rst +++ b/Sming/Arch/Esp8266/Components/esp8266/README.rst @@ -8,3 +8,47 @@ support code. Sming uses libraries from the ESP8266 NON-OS SDK version 3, imported as a submodule. The header and linker files are provided by this Component. + + +Configuration variables +----------------------- + +.. envvar:: ENABLE_CUSTOM_PHY + + Default: undefined (off) + + The ``phy_init`` partition contains data which the ESP8266 SDK uses to initialise WiFi hardware at startup. + + You may want to change settings for a certain ROM on the device without changing it for all ROMs on the device. + To do this, build with ``ENABLE_CUSTOM_PHY=1`` and add code to your application:: + + #include + + void customPhyInit(PhyInitData data) + { + // Use methods of `data` to modify as required + data.set_vdd33_const(0xff); + } + + See :cpp:struct:`PhyInitData` for further details. + + +.. envvar:: FLASH_INIT_DATA + + Read-only. This is the path to the default PHY data written to the ``phy_init`` partition. + It is provided by the SDK. + + +.. envvar:: FLASH_INIT_DATA_VCC + + Read-only. This is the path to a modified version of the default PHY data selected + by the ``vdd`` hardware configuration option. See :doc:`/information/tips-n-tricks`. + + The modification is equivalent to calling :cpp:func:`PhyInitData::set_vdd33_const` with ``0xff``. + + +API reference +------------- + +.. doxygenstruct:: PhyInitData + :members: diff --git a/Sming/Arch/Esp8266/Components/esp8266/component.mk b/Sming/Arch/Esp8266/Components/esp8266/component.mk index a62bfe2fef..a977b3e0a8 100644 --- a/Sming/Arch/Esp8266/Components/esp8266/component.mk +++ b/Sming/Arch/Esp8266/Components/esp8266/component.mk @@ -13,6 +13,15 @@ ifeq ($(DISABLE_WIFI),1) COMPONENT_DEPENDS += esp-lwip endif + +COMPONENT_RELINK_VARS += ENABLE_CUSTOM_PHY +ENABLE_CUSTOM_PHY ?= 0 +ifeq ($(ENABLE_CUSTOM_PHY),1) + COMPONENT_CXXFLAGS += -DENABLE_CUSTOM_PHY=1 + LDFLAGS += $(call Wrap,register_chipv6_phy) +endif + + $(FLASH_INIT_DATA): $(SDK_BASE)/.submodule $(Q) cp -f $(@D)/esp_init_data_default_v08.bin $@ @@ -29,7 +38,8 @@ export SDK_LIBDIR COMPONENT_DOXYGEN_INPUT := \ include/gpio.h \ - include/pwm.h + include/pwm.h \ + include/esp_phy.h # Crash handler hooks this so debugger can be invoked EXTRA_LDFLAGS := $(call Wrap,system_restart_local) diff --git a/Sming/Arch/Esp8266/Components/esp8266/crash_handler.c b/Sming/Arch/Esp8266/Components/esp8266/crash_handler.c index 324a314ded..7db2f4d777 100644 --- a/Sming/Arch/Esp8266/Components/esp8266/crash_handler.c +++ b/Sming/Arch/Esp8266/Components/esp8266/crash_handler.c @@ -25,6 +25,9 @@ extern void __real_system_restart_local(); extern void __custom_crash_callback( struct rst_info * rst_info, uint32_t stack, uint32_t stack_end ) { + (void)rst_info; + (void)stack; + (void)stack_end; } extern void custom_crash_callback( struct rst_info * rst_info, uint32_t stack, uint32_t stack_end ) __attribute__ ((weak, alias("__custom_crash_callback"))); diff --git a/Sming/Arch/Esp8266/Components/esp8266/esp8266_phy.cpp b/Sming/Arch/Esp8266/Components/esp8266/esp8266_phy.cpp new file mode 100644 index 0000000000..361ab79ed1 --- /dev/null +++ b/Sming/Arch/Esp8266/Components/esp8266/esp8266_phy.cpp @@ -0,0 +1,43 @@ +/* + Adapted from Arduino for Sming. + Original copyright note is kept below. + + phy.c - ESP8266 PHY initialization data + Copyright (c) 2015 Ivan Grokhotkov. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +// #ifdef ENABLE_CUSTOM_PHY + +#include "include/esp_phy.h" +#include +#include +#include +#include + +extern "C" { +extern int __wrap_register_chipv6_phy(uint8_t* initData); +extern int __real_register_chipv6_phy(uint8_t* initData); +} + +int ICACHE_RAM_ATTR __wrap_register_chipv6_phy(uint8_t* initData) +{ + if(initData != NULL) { + PhyInitData data{initData}; + customPhyInit(data); + } + return __real_register_chipv6_phy(initData); +} + +// #endif /* ENABLE_CUSTOM_PHY */ diff --git a/Sming/Arch/Esp8266/Components/esp8266/include/esp_phy.h b/Sming/Arch/Esp8266/Components/esp8266/include/esp_phy.h new file mode 100644 index 0000000000..d750da229b --- /dev/null +++ b/Sming/Arch/Esp8266/Components/esp8266/include/esp_phy.h @@ -0,0 +1,394 @@ +/* + Adapted from Arduino for Sming. + Original copyright note is kept below. + + phy.c - ESP8266 PHY initialization data + Copyright (c) 2015 Ivan Grokhotkov. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +/** + * @brief Structure to manage low-level adjustment of PHY data + * Does not contain the data but a reference to it. + * The data should not be accessed directly. + * @see For further details, see the following PDF documents: + * - ESP8266 Phy Init Bin Parameter Configuration Guide + * - ESP8266 Non-OS SDK API Reference (Final version is version 4) + */ +struct PhyInitData { + /** + * @brief Index for configurable power level, from 0-5. See `PhyInitData::set_txpwr_dqb`. + */ + using txpwr_index_t = uint8_t; + + uint8_t* data; // [128] + + /** + * @brief PHY data version number. Currently version 8. + */ + uint8_t get_version() const + { + return data[1]; + } + + /** + * @brief Ordinal 26-29 + * + * These values are poorly defined. + * + * - [26] = 225, // spur_freq_cfg, spur_freq=spur_freq_cfg/spur_freq_cfg_div + * - [27] = 10, // spur_freq_cfg_div + * + * Each bit for 1 channel, 1 to select the spur_freq if in band, else 40 + * + * - [28] = 0xff, // spur_freq_en_h + * - [29] = 0xff, // spur_freq_en_l + */ + void undocumented_26_29() + { + } + + /** + * @brief Configure the maximum TX powers for channels 1, 11, 13 and 14. + * @param chan1 Limit for channel 1 + * @param chan11 Limit for channel 11 + * @param chan13 Limit for channel 13 + * @param chan14 Limit for channel 14 + */ + void set_power_limits(txpwr_index_t chan1, txpwr_index_t chan11, txpwr_index_t chan13, txpwr_index_t chan14) + { + data[78] = 2; // Enable bytes 30-33 to set maximum TX power + data[30] = chan1; + data[31] = chan11; + data[32] = chan13; + data[33] = chan14; + } + + /** + * @brief Disable power limits on channels 1, 11, 13 and 14 + */ + void disable_power_limits() + { + data[78] = 0; // disable bytes 30-33 + } + + /** + * @brief Set TX power level. + * TX power can be switched between six levels. + * Level 0 represents the maximum TX power, level 5 the minimum. + * @param level Index from 0-5 + * @param value Power level in 0.25dB increments + * @note Defaults are: + * - 0: 78/4 = 19.5dBm + * - 1: 74/4 = 18.5dBm + * - 2: 70/4 = 17.5dBm + * - 3: 64/4 = 16dBm + * - 4: 60/4 = 15dBm + * - 5: 56/4 = 14dBm + * + * @see See ESP8266 Non-OS SDK API Reference: + * - system_phy_set_max_tpw + */ + void set_txpwr_dqb(txpwr_index_t level, uint8_t value) + { + if(level < 6) { + data[34 + level] = value; + } + } + + /** + * @brief Select target power level for specific data rate according to Modulation Coding Scheme (MCS) + * @param mcs_index Modulation Coding Scheme (MCS) index, from 0-7 + * @param txpwr_qdb Power level 0-5. See `PhyInitData::set_txpwr_dqb`. + * + * @note The defaults are: + * - MCS0: qdb_0 1 Mbit/s, 2 Mbit/s, 5.5 Mbit/s, 11 Mbit/s, 6 Mbit/s, 9 Mbit/s) + * - MCS1: qdb_0 12 Mbit/s) + * - MCS2: qdb_1 18 Mbit/s) + * - MCS3: qdb_1 24 Mbit/s + * - MCS4: qdb_2 36 Mbit/s + * - MCS5: qdb_3 48 Mbit/s + * - MCS6: qdb_4 54 Mbit/s + * - MCS7: qdb_5 + */ + void set_txpwr(uint8_t mcs_index, txpwr_index_t txpwr_qdb) + { + if(mcs_index < 8 && txpwr_qdb < 6) { + data[40 + mcs_index] = txpwr_qdb; + } + } + + /** + * @brief Select crystal frequency + * @param value Values are: + * - 0: 40MHz + * - 1: 26MHz + * - 2: 24MHz + */ + void set_crystal_freq(uint8_t value = 1) + { + data[48] = value; + } + + /** + * @brief Configure SDIO behaviour + * @param value Values are: + * - 0: Auto by pin strapping + * - 1: SDIO data output is at negative edges (SDIO V1.1) + * - 2: SDIO data output is at positive edges (SDIO V2.0) + */ + void set_sdio_configure(uint8_t value = 0) + { + data[50] = value; + } + + /** + * @brief Configure bluetooth + * @param value Values are: + * - 0: None,no bluetooth + * - 1: Enable, pins are: + * - GPIO0 -> WLAN_ACTIVE/ANT_SEL_WIFI + * - MTMS -> BT_ACTIVE + * - MTCK -> BT_PRIORITY + * - U0RXD -> ANT_SEL_BT + * - 2: None, have bluetooth + * - 3: Enable, pins are: + * - GPIO0 -> WLAN_ACTIVE/ANT_SEL_WIFI + * - MTMS -> BT_PRIORITY + * - MTCK -> BT_ACTIVE + * - U0RXD -> ANT_SEL_BT + */ + void set_bt_configure(uint8_t value = 0) + { + data[51] = value; + } + + /** + * @brief Configure Bluetooth protocol + * @param value Values are: + * - 0: WiFi-BT are not enabled. Antenna is for WiFi + * - 1: WiFi-BT are not enabled. Antenna is for BT + * - 2: WiFi-BT 2-wire are enabled, (only use BT_ACTIVE), independent ant + * - 3: WiFi-BT 3-wire are enabled, (when BT_ACTIVE = 0, BT_PRIORITY must be 0), independent ant + * - 4: WiFi-BT 2-wire are enabled, (only use BT_ACTIVE), share ant + * - 5: WiFi-BT 3-wire are enabled, (when BT_ACTIVE = 0, BT_PRIORITY must be 0), share ant + */ + void set_bt_protocol(uint8_t value = 0) + { + data[52] = value; + } + + /** + * @brief Configure dual antenna arrangement + * @param value Values are: + * - 0: None + * - 1: dual_ant (antenna diversity for WiFi-only): GPIO0 + U0RXD + * - 2: T/R switch for External PA/LNA: GPIO0 is high and U0RXD is low during Tx + * - 3: T/R switch for External PA/LNA: GPIO0 is low and U0RXD is high during Tx + */ + void set_dual_ant_configure(uint8_t value = 0) + { + data[53] = value; + } + + /** + * @brief Set Crystal state during sleep mode + * This option is to share crystal clock for BT + * @param value The state of Crystal during sleeping: + * - 0: Off + * - 1: Forcibly On + * - 2: Automatically On according to XPD_DCDC + * - 3: Automatically On according to GPIO2 + */ + void set_share_xtal(uint8_t value = 0) + { + data[55] = value; + } + + /** + * @brief Ordinal 64-73 + * + * These values are poorly defined. + * + * - [64] = 225, // spur_freq_cfg_2, spur_freq_2=spur_freq_cfg_2/spur_freq_cfg_div_2 + * - [65] = 10, // spur_freq_cfg_div_2 + * - [66] = 0, // spur_freq_en_h_2 + * - [67] = 0, // spur_freq_en_l_2 + * - [68] = 0, // spur_freq_cfg_msb + * - [69] = 0, // spur_freq_cfg_2_msb + * - [70] = 0, // spur_freq_cfg_3_low + * - [71] = 0, // spur_freq_cfg_3_high + * - [72] = 0, // spur_freq_cfg_4_low + * - [73] = 0, // spur_freq_cfg_4_high + */ + void undocumented_64_73() + { + } + + /** + * @brief Configure low-power mode + * @param value Values are: + * - 0: disable low power mode + * - 1: enable low power mode + */ + void set_low_power_en(uint8_t value = 0) + { + data[93] = value; + } + + /** + * @brief Set attenuation of RF gain stage 0 and 1 + * @param value Values are: + * - 0x0f: 0dB + * - 0x0e: -2.5dB + * - 0x0d: -6dB + * - 0x09: -8.5dB + * - 0x0c: -11.5dB + * - 0x08: -14dB + * - 0x04: -17.5dB + * - 0x00: -23dB + */ + void set_lp_rf_stg10(uint8_t value = 0) + { + data[94] = value; + } + + /** + * @brief Set attenuation of BB gain + * @param value Attenuation in 0.25dB steps. Max valve is 24 (-6dB): + * - 0: 0dB + * - 1: -0.25dB + * - 2: -0.5dB + * - 3: -0.75dB + * - 4: -1dB + * - 5: -1.25dB + * - 6: -1.5dB + * - 7: -1.75dB + * - 8: -2dB + * etc. + */ + void set_lp_bb_att_ext(uint8_t value = 0) + { + data[95] = value; + } + + /** + * @brief Set power limits for 802.11b to default, + * which is same as MCS0 and 6Mbits/s modes. See `PhyInitData::set_txpwr`. + */ + void set_default_power_limits_11b() + { + data[96] = 0; + } + + /** + * @brief Configure 802.11b power limits + * @param txpwr_index_11b_0 Power level for 1Mbit/s and 2Mbit/s modes + * @param txpwr_index_11b_1 Power level for 5.5Mbits/s and 11Mbits/s modes + */ + void set_power_limits_11b(txpwr_index_t txpwr_index_11b_0, txpwr_index_t txpwr_index_11b_1) + { + data[96] = 1; + data[97] = txpwr_index_11b_0; + data[98] = txpwr_index_11b_1; + } + + /** + * @brief Set PA_VDD voltage + * @param value Values are: + * - 0xff: Can measure VDD33 + * - 18 <= value <= 36: use input voltage, where `value = voltage * 10`, so 33 is 3.3V, 30 is 3.0V, etc. + * - value < 18, value > 36: default voltage is 3.3V + * + * The value of this byte depends on the TOUT pin usage: + * - analogRead function: `system_adc_read()` + * - Only available when wire TOUT pin 17 to external circuitry, Input Voltage Range restricted to 0 ~ 1.0V. + * - For this function the vdd33_const must be set as real power voltage of VDD3P3 pin 3 and 4 + * - The range of operating voltage of ESP8266 is 1.8V ~ 3.6V, + * the unit of vdd33_const is 0.1V, so effective value range of vdd33_const is [18, 36]. + * - getVcc function: `system_get_vdd33()` + * - Only available when TOUT pin 17 is suspended (floating), this function measure the power voltage of VDD3P3 pin 3 and 4 + * - For this function the vdd33_const must be set to 255 (0xFF). + * + * @see See ESP8266 Non-OS SDK API Reference: + * - system_get_vdd33 + * - system_adc_read + * - system_adc_read_fast + */ + void set_vdd33_const(uint8_t value = 33) + { + data[107] = value; + } + + /** + * @brief Disable RF calibration for certain number of times + * @param value Number of times to disable RF calibration + * @see See ESP8266 Non-OS SDK API Reference: + * - system_deep_sleep_set_option + * - system_phy_set_rfoption + */ + void set_rf_cal_disable(uint8_t value = 0) + { + data[108] = value; + } + + /** + * @brief Enable frequency correction + * @param mode Correction mode: + * - 0x00: do not correct frequency offset + * - 0x01: auto-correct, bbpll 168M, can correct positive and negative offsets + * - 0x03: auto-correct, bbpll 160M, can only correct positive offsets + * - 0x05: Correct using `force_freq_offset`, bbpll 168M, offset can be any value + * - 0x07: Correct using `force_freq_offset`, bbpll 160M, offset must >= 0 + * @param force_freq_offset Correction figure in 8kHz steps, signed + * + * Bits are defined as follows: + * - bit 0 + * - 0: do not correct frequency offset + * - 1: correct frequency offset + * - bit 1 + * - 0: bbpll is 168M, it can correct + and - frequency offset + * - 1: bbpll is 160M, it only can correct + frequency offset + * - bit 2 + * - 0: auto measure frequency offset and correct it + * - 1: use force_freq_offset to correct frequency offset + */ + void set_freq_correct(uint8_t bbpll = 3, int8_t force_freq_offset = 0) + { + data[112] = bbpll; + data[113] = uint8_t(force_freq_offset); + } + + /** + * @brief RF_calibration + * @param value Values are: + * - 0: RF init no RF CAL, using all RF CAL data in flash, it takes about 2ms for RF init + * - 1: RF init only do TX power control CAL, others using RF CAL data in flash, it takes about 20ms for RF init + * - 2: RF init no RF CAL, using all RF CAL data in flash, it takes about 2ms for RF init (same as 0?!) + * - 3: RF init do all RF CAL, it takes about 200ms for RF init + * @note To ensure better RF performance, it is recommend to set RF_calibration to 3, otherwise the RF performance may become poor. + * @see See ESP8266 Non-OS SDK API Reference: + * - system_phy_set_powerup_option + */ + void set_rf_calibration(uint8_t value = 1) + { + data[114] = value; + } +}; + +extern void customPhyInit(PhyInitData data); diff --git a/Sming/Arch/Esp8266/Components/esp8266/include/esp_wifi.h b/Sming/Arch/Esp8266/Components/esp8266/include/esp_wifi.h index 093eeb9c07..8d59b7b293 100644 --- a/Sming/Arch/Esp8266/Components/esp8266/include/esp_wifi.h +++ b/Sming/Arch/Esp8266/Components/esp8266/include/esp_wifi.h @@ -29,7 +29,7 @@ #pragma once #include "os_type.h" -#include "lwip/ip_addr.h" +#include "ipv4_addr.h" #include "../sdk/include/queue.h" #include "gpio.h" @@ -227,13 +227,13 @@ struct station_info { STAILQ_ENTRY(station_info) next; uint8_t bssid[6]; - struct ip_addr ip; + struct ipv4_addr ip; }; struct dhcps_lease { bool enable; - struct ip_addr start_ip; - struct ip_addr end_ip; + struct ipv4_addr start_ip; + struct ipv4_addr end_ip; }; enum dhcps_offer_option { @@ -244,7 +244,7 @@ enum dhcps_offer_option { uint8_t wifi_softap_get_station_num(void); struct station_info* wifi_softap_get_station_info(void); -bool wifi_softap_set_station_info (uint8_t* mac, struct ip_addr*); +bool wifi_softap_set_station_info (uint8_t* mac, struct ipv4_addr*); void wifi_softap_free_station_info(void); bool wifi_softap_dhcps_start(void); @@ -375,9 +375,9 @@ typedef struct { } Event_StaMode_AuthMode_Change_t; typedef struct { - struct ip_addr ip; - struct ip_addr mask; - struct ip_addr gw; + struct ipv4_addr ip; + struct ipv4_addr mask; + struct ipv4_addr gw; } Event_StaMode_Got_IP_t; typedef struct { @@ -387,7 +387,7 @@ typedef struct { typedef struct { uint8_t mac[6]; - struct ip_addr ip; + struct ipv4_addr ip; uint8_t aid; } Event_SoftAPMode_Distribute_Sta_IP_t; diff --git a/Sming/Arch/Esp8266/Components/esp8266/include/espinc/eagle_soc.h b/Sming/Arch/Esp8266/Components/esp8266/include/espinc/eagle_soc.h index fcb72fcc97..99244138f1 100644 --- a/Sming/Arch/Esp8266/Components/esp8266/include/espinc/eagle_soc.h +++ b/Sming/Arch/Esp8266/Components/esp8266/include/espinc/eagle_soc.h @@ -126,6 +126,7 @@ //}} //Interrupt remap control registers define{{ +#define NMI_INT_ENABLE_REG (PERIPHS_DPORT_BASEADDR) #define EDGE_INT_ENABLE_REG (PERIPHS_DPORT_BASEADDR + 0x04) #define WDT_EDGE_INT_ENABLE() SET_PERI_REG_MASK(EDGE_INT_ENABLE_REG, BIT0) #define TM1_EDGE_INT_ENABLE() SET_PERI_REG_MASK(EDGE_INT_ENABLE_REG, BIT1) diff --git a/Sming/Arch/Esp8266/Components/esp8266/include/ets_sys.h b/Sming/Arch/Esp8266/Components/esp8266/include/ets_sys.h index 4d9eb1109c..c2673186f8 100644 --- a/Sming/Arch/Esp8266/Components/esp8266/include/ets_sys.h +++ b/Sming/Arch/Esp8266/Components/esp8266/include/ets_sys.h @@ -73,8 +73,8 @@ typedef void (*ets_isr_t)(void*); void ets_intr_lock(void); void ets_intr_unlock(void); void ets_isr_attach(int i, ets_isr_t func, void* arg); -void ets_isr_mask(uint32 mask); -void ets_isr_unmask(uint32 unmask); +void ets_isr_mask(uint32_t mask); +void ets_isr_unmask(uint32_t unmask); void NmiTimSetFunc(void (*func)(void)); diff --git a/Sming/Arch/Esp8266/Components/esp8266/include/ipv4_addr.h b/Sming/Arch/Esp8266/Components/esp8266/include/ipv4_addr.h new file mode 100644 index 0000000000..aea46425b6 --- /dev/null +++ b/Sming/Arch/Esp8266/Components/esp8266/include/ipv4_addr.h @@ -0,0 +1,76 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2016 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is 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 __IPV4_ADDR_H__ +#define __IPV4_ADDR_H__ + +struct ip_info; + +#include + +#ifdef LWIP14GLUE + +#define ipv4_addr ip_addr + +#else + +#ifdef __LWIP_IP_ADDR_H__ + +#define ipv4_addr ip_addr + +#else + +#include + +// ipv4_addr is necessary for lwIP-v2 because +// - espressif binary firmware is IPv4 only, under the name of ip_addr/_t +// - ip_addr/_t is different when IPv6 is enabled with lwIP-v2 +// hence ipv4_addr/t is IPv4 version/copy of IPv4 ip_addr/_t +// when IPv6 is enabled so we can deal with IPv4 use from firmware API. + +#define ipv4_addr ip4_addr +#define ipv4_addr_t ip4_addr_t + +// official lwIP's definitions +#if LWIP_VERSION_MAJOR == 1 +struct ip4_addr { uint32_t addr; }; +typedef struct ip4_addr ip4_addr_t; +#else + +#include + +// defined in lwip-v1.4 sources only, used in fw +struct ip_info { + struct ipv4_addr ip; + struct ipv4_addr netmask; + struct ipv4_addr gw; +}; + +#endif + +#endif // __LWIP_IP_ADDR_H__ + +#endif // LWIP14GLUE + +#endif // __IPV4_ADDR_H__ diff --git a/Sming/Arch/Esp8266/Components/esp8266/include/sdk/mem.h b/Sming/Arch/Esp8266/Components/esp8266/include/sdk/mem.h index df1950df4a..6d3cb37d3d 100644 --- a/Sming/Arch/Esp8266/Components/esp8266/include/sdk/mem.h +++ b/Sming/Arch/Esp8266/Components/esp8266/include/sdk/mem.h @@ -6,10 +6,10 @@ extern "C" { #endif -void* pvPortMalloc(size_t xWantedSize, const char* file, uint32 line); +void* pvPortMalloc(size_t xWantedSize, const char* file, uint32_t line); void* pvPortCalloc(size_t count, size_t size, const char*, unsigned); -void* pvPortZalloc(size_t xWantedSize, const char* file, uint32 line); -void vPortFree(void* ptr, const char* file, uint32 line); +void* pvPortZalloc(size_t xWantedSize, const char* file, uint32_t line); +void vPortFree(void* ptr, const char* file, uint32_t line); void* vPortMalloc(size_t xWantedSize); void pvPortFree(void* ptr); diff --git a/Sming/Arch/Esp8266/Components/esp8266/startup.cpp b/Sming/Arch/Esp8266/Components/esp8266/startup.cpp index 79d1d9794b..f8f6aa807d 100644 --- a/Sming/Arch/Esp8266/Components/esp8266/startup.cpp +++ b/Sming/Arch/Esp8266/Components/esp8266/startup.cpp @@ -18,6 +18,7 @@ extern void init(); extern void cpp_core_initialize(); +// Normal entry point for user application code from SDK extern "C" void user_init(void) { // Initialise hardware timers @@ -39,12 +40,20 @@ extern "C" void user_init(void) gdb_init(); + /* + * Load partition information. + * Normally this is done in user_pre_init() but if building without WiFi + * (via esp_no_wifi Component) then user_pre_init() is not called as none of the + * SDK-related partitions are required. + * Calling this a second time is a no-op. + */ Storage::initialize(); init(); // User code init } -extern "C" void ICACHE_FLASH_ATTR WEAK_ATTR user_pre_init(void) +// SDK 3+ calls this method to configure partitions +extern "C" void user_pre_init(void) { Storage::initialize(); diff --git a/Sming/Arch/Esp8266/Components/esp_no_wifi/README.rst b/Sming/Arch/Esp8266/Components/esp_no_wifi/README.rst index a81ca6fc75..2127075d74 100644 --- a/Sming/Arch/Esp8266/Components/esp_no_wifi/README.rst +++ b/Sming/Arch/Esp8266/Components/esp_no_wifi/README.rst @@ -24,6 +24,12 @@ The SDKnoWiFi implements the startup code and some system functions but contains which is provided by the SDK and in other parts of the Sming framework. We need to provide replacement functions to interoperate correctly with the remaining SDK code. +Advantages +---------- + +- Reduces code image size when networking/WiFi is not required +- Eliminates need for SDK-specific partitions (rf_cal, phy_init, sys_param) + Process ------- diff --git a/Sming/Arch/Esp8266/Components/esp_no_wifi/component.mk b/Sming/Arch/Esp8266/Components/esp_no_wifi/component.mk index 3a7b21c311..b545090127 100644 --- a/Sming/Arch/Esp8266/Components/esp_no_wifi/component.mk +++ b/Sming/Arch/Esp8266/Components/esp_no_wifi/component.mk @@ -23,6 +23,7 @@ EXTRA_OBJ := extra.o $(COMPONENT_RULE)$(EXTRA_OBJ): sdk/user_interface.o $(Q) $(OBJCOPY) \ -j *UND* \ + -j .sdk.version.* \ $(addprefix -j .text.,$(NOWIFI_SYMS)) \ $(foreach f,$(NOWIFI_SYMS),--rename-section .text.$f=.iram.text) \ $< $@ @@ -40,7 +41,10 @@ endef LIBMAIN_COMMANDS += $(NOWIFI_LIBMAIN_COMMANDS) LIBDIRS += $(COMPONENT_PATH) -EXTRA_LDFLAGS := -Tno.wifi.ld -u call_user_start_local +EXTRA_LDFLAGS := \ + -Tno.wifi.ld \ + -u call_user_start_local \ + -u SDK_VERSION ## diff --git a/Sming/Arch/Esp8266/Components/esp_no_wifi/user_interface.c b/Sming/Arch/Esp8266/Components/esp_no_wifi/user_interface.c index 8bbf3e0e2f..e5cf764c8d 100644 --- a/Sming/Arch/Esp8266/Components/esp_no_wifi/user_interface.c +++ b/Sming/Arch/Esp8266/Components/esp_no_wifi/user_interface.c @@ -1,6 +1,7 @@ #include #include #include +#include bool protect_flag; bool timer2_ms_flag; @@ -337,3 +338,15 @@ int os_printf_plus(const char* format, ...) return n; } + +const char* system_get_sdk_version() +{ + extern char SDK_VERSION[]; + return SDK_VERSION; +} + +uint32_t system_get_chip_id() +{ + // from chip_id() method in esptool.py + return (MAC0 >> 24) | ((MAC1 & 0x00ffffff) << 8); +} diff --git a/Sming/Arch/Esp8266/Components/gdbstub/README.rst b/Sming/Arch/Esp8266/Components/gdbstub/README.rst index 6ca13e1e46..56adc75b56 100644 --- a/Sming/Arch/Esp8266/Components/gdbstub/README.rst +++ b/Sming/Arch/Esp8266/Components/gdbstub/README.rst @@ -9,16 +9,15 @@ This is a rewrite of gdbstub based on the To use the GNU Debugger (GDB) with Sming requires your application to include some code (``gdbstub``) which communicates via the serial port. -On the ESP8266 only UART0 may be used for this as UART1 is -transmit-only. +On the ESP8266 only UART0 may be used for this as UART1 is transmit-only. -The gdbstub code will only be built if you specify :envvar:`ENABLE_GDB` -=1 when compiling your application. At startup, before your init() +The gdbstub code will only be built if you specify :envvar:`ENABLE_GDB=1 ` +when compiling your application. At startup, before your init() function is called, it will claim UART0 so your application will be unable to use it directly. Therefore, the default port for ``Serial`` is changed to ``UART2``. -UART2 is a ‘virtual’ serial port to enable serial communications to work +UART2 is a 'virtual' serial port to enable serial communications to work correctly when GDB-enabled. Read/write calls and serial callbacks are handled via gdbstub. Baud rate changes affect UART0 directly. @@ -29,30 +28,13 @@ Refer to the official `GDB documentation `__ for further details. -GDB ---- - -This is the application which runs on your development system and talks -to ``gdbstub``. - -- Linux: A version of this should be available in - ``$ESP_HOME/xtensa-lx106-elf/bin/xtensa-lx106-elf-gdb`` - -- Windows: At time of writing, UDK doesn’t provide a GDB application - - Download and run the executable installer at `SysProgs `__ - - - Copy the - ``C:\SysGCC\esp8266\opt\xtensa-lx106-elf\bin\xtensa-lx106-elf-gdb.exe`` - to a suitable location. - -- Mac: ? Usage ----- - Configure gdbstub by editing ``gdbstub-cfg.h`` as required. You can also configure the options by setting ::envvar:`USER_CFLAGS` in - your project’s ``component.mk`` file. e.g + your project's ``component.mk`` file. e.g ``USER_CFLAGS=-DGDBSTUB_BREAK_ON_INIT=0``. - Optional: Add ``gdb_do_break()`` statements to your application. - Run ``make clean``, then ``make ENABLE_GDB=1 flash`` to build and @@ -91,6 +73,8 @@ To run manually, see the following variables which you can inspect using ``make .. envvar:: GDB Path to the GDB executable being used. + This is the application which runs on your development system and talks to ``gdbstub``. + It is provided in the standard toolchain. .. _useful-gdb-commands: @@ -146,8 +130,7 @@ Eclipse Windows: - Ensure ``Use external console for inferior`` is checked. -- In connection settings, specify COM port like with leading /, - e.g. \ ``/COM4`` +- In connection settings, specify COM port like with leading /, e.g. ``/COM4`` Problems connecting? @@ -166,7 +149,7 @@ example reading input from the GDB command prompt. See the :sample:`LiveDebug` sample for a demonstration. Note that system calls are disabled in the default configuration, so set -:c:macro:`GDBSTUB_ENABLE_SYSCALL` =1 to use this feature with your +:c:macro:`GDBSTUB_ENABLE_SYSCALL=1 ` to use this feature with your application. Known Issues and Limitations @@ -185,17 +168,17 @@ Known Issues and Limitations data while the debugger has stopped the CPU, it is bound to crash. This will happen mostly when working with UDP and/or ICMP; TCP-connections in general will not send much more data when the - other side doesn’t send any ACKs. + other side doesn't send any ACKs. - Solution: In such situations avoid pausing the debugger for extended periods -- Software breakpoints/watchpoints (‘break’ and ‘watch’) don’t work on flash code +- Software breakpoints/watchpoints ('break' and 'watch') don't work on flash code - Cause: GDB handles these by replacing code with a debugging instruction, therefore the code must be in RAM. - - Solution: Use hardware breakpoint (‘hbreak’) or use + - Solution: Use hardware breakpoint ('hbreak') or use :c:macro:`GDB_IRAM_ATTR` for code which requires testing -- If hardware breakpoint is set, single-stepping won’t work unless code is in RAM. +- If hardware breakpoint is set, single-stepping won't work unless code is in RAM. - Cause: GDB reverts to software breakpoints if no hardware breakpoints are available - Solution: Delete hardware breakpoint before single-stepping @@ -206,32 +189,32 @@ Known Issues and Limitations - Solution: Use the timer in non-maskable mode, or enable :c:macro:`GDBSTUB_PAUSE_HARDWARE_TIMER` option -- If gdbstub isn’t initialised then UART2 won’t work, though initialisation will succeed +- If gdbstub isn't initialised then UART2 won't work, though initialisation will succeed - Cause: By design, uart callbacks can be registered for UART2 at any time, before or after initialisation - Solution: Not really an issue, just something to be aware of -- Error reported, “packet reply is too long” +- Error reported, "packet reply is too long" - Cause: Mismatch between GDB version and stub code - - Solution: Set :c:macro:`GDBSTUB_GDB_PATCHED` =1 or use an + - Solution: Set :c:macro:`GDBSTUB_GDB_PATCHED=1 ` or use an unpatched version of GDB - Whilst GDB is attached, input cannot be passed to application - Cause: GDB buffers keystrokes and replays them only when the - target is interrupted (e.g. via ctrl+C), rather than passing them + target is interrupted (e.g. via ctrl+C), rather than passing them via serial connection. - Solution: Application may use gdb_syscall interface to communicate with debugger. See ``$(SMING_HOME)/system/gdb_syscall.h``, and :sample:`LiveDebug` sample. -- No apparent way to have second ‘console’ (windows terminology) separate from GDB interface +- No apparent way to have second 'console' (windows terminology) separate from GDB interface - Cause: Unknown - Solution: Is this possible with remote targets? -- GDB (in Windows) doesn’t respond at all to Ctrl+C +- GDB (in Windows) doesn't respond at all to Ctrl+C - Cause: Unknown - - Solution: Press Ctrl+Break to ‘hard kill’ GDB. You'll probably + - Solution: Press Ctrl+Break to 'hard kill' GDB. You'll probably need to do the next step as well to get it back - When GDB is running under windows, appears to hang when target reset or restarted @@ -244,7 +227,7 @@ Known Issues and Limitations - quit terminal - run GDB again ``make gdb`` -- Debug messages don’t appear in Eclipse +- Debug messages don't appear in Eclipse - Cause: Unknown - Solution: Use command-line GDB, or a better visual debugger diff --git a/Sming/Arch/Esp8266/Components/gdbstub/appcode/gdb_hooks.cpp b/Sming/Arch/Esp8266/Components/gdbstub/appcode/gdb_hooks.cpp index 8301718ba1..8b1784d9df 100644 --- a/Sming/Arch/Esp8266/Components/gdbstub/appcode/gdb_hooks.cpp +++ b/Sming/Arch/Esp8266/Components/gdbstub/appcode/gdb_hooks.cpp @@ -63,7 +63,8 @@ void debug_print_stack(uint32_t start, uint32_t end) m_puts(instructions); } -void debug_crash_callback(const rst_info* rst_info, uint32_t stack, uint32_t stack_end) +void debug_crash_callback([[maybe_unused]] const rst_info* rst_info, [[maybe_unused]] uint32_t stack, + [[maybe_unused]] uint32_t stack_end) { #ifdef ENABLE_GDB gdbFlushUserData(); @@ -226,7 +227,7 @@ void ATTR_GDBINIT gdb_init(void) #endif } -void WEAK_ATTR gdb_enable(bool state) +void WEAK_ATTR gdb_enable(bool) { } @@ -235,7 +236,7 @@ GdbState WEAK_ATTR gdb_present(void) return eGDB_NotPresent; } -void WEAK_ATTR gdb_on_attach(bool attached) +void WEAK_ATTR gdb_on_attach(bool) { } @@ -245,7 +246,7 @@ void WEAK_ATTR gdb_detach(void) } // extern "C" -int WEAK_ATTR gdb_syscall(const GdbSyscallInfo& info) +int WEAK_ATTR gdb_syscall(const GdbSyscallInfo&) { return -1; } diff --git a/Sming/Arch/Esp8266/Components/gdbstub/component.mk b/Sming/Arch/Esp8266/Components/gdbstub/component.mk index 814d8d1bd7..6265aaa305 100644 --- a/Sming/Arch/Esp8266/Components/gdbstub/component.mk +++ b/Sming/Arch/Esp8266/Components/gdbstub/component.mk @@ -41,7 +41,5 @@ ifeq ($(GDB_UART_SWAP),1) APP_CFLAGS += -DGDB_UART_SWAP=1 endif -# -ifeq ($(USE_NEWLIB),1) +# All supported compiler versions now use unpatched GDB APP_CFLAGS += -DGDBSTUB_GDB_PATCHED=0 -endif diff --git a/Sming/Arch/Esp8266/Components/gdbstub/gdbstub.cpp b/Sming/Arch/Esp8266/Components/gdbstub/gdbstub.cpp index b563af1e06..79cb67eb89 100644 --- a/Sming/Arch/Esp8266/Components/gdbstub/gdbstub.cpp +++ b/Sming/Arch/Esp8266/Components/gdbstub/gdbstub.cpp @@ -17,10 +17,10 @@ * * Note from GDB manual: * - * At a minimum, a stub is required to support the ‘g’ and ‘G’ commands for register access, - * and the ‘m’ and ‘M’ commands for memory access. Stubs that only control single-threaded - * targets can implement run control with the ‘c’ (continue), and ‘s’ (step) commands. Stubs - * that support multi-threading targets should support the ‘vCont’ command. All other commands + * At a minimum, a stub is required to support the 'g' and 'G' commands for register access, + * and the 'm' and 'M' commands for memory access. Stubs that only control single-threaded + * targets can implement run control with the 'c' (continue), and 's' (step) commands. Stubs + * that support multi-threading targets should support the 'vCont' command. All other commands * are optional. * *********************************************************************************/ diff --git a/Sming/Arch/Esp8266/Components/gdbstub/gdbuart.cpp b/Sming/Arch/Esp8266/Components/gdbstub/gdbuart.cpp index e54fce80f3..e0ad9f5c6e 100644 --- a/Sming/Arch/Esp8266/Components/gdbstub/gdbuart.cpp +++ b/Sming/Arch/Esp8266/Components/gdbstub/gdbuart.cpp @@ -271,7 +271,7 @@ static void IRAM_ATTR doCtrlBreak() } } -static void IRAM_ATTR gdb_uart_callback(smg_uart_t* uart, uint32_t status) +static void IRAM_ATTR gdb_uart_callback(smg_uart_t*, uint32_t status) { #if GDBSTUB_ENABLE_UART2 user_uart_status = status; diff --git a/Sming/Arch/Esp8266/Components/heap/alloc.cpp b/Sming/Arch/Esp8266/Components/heap/alloc.cpp index f54b7a7ceb..67e5b1ccbd 100644 --- a/Sming/Arch/Esp8266/Components/heap/alloc.cpp +++ b/Sming/Arch/Esp8266/Components/heap/alloc.cpp @@ -41,12 +41,12 @@ void operator delete[](void* ptr) free(ptr); } -void operator delete(void* ptr, size_t sz) +void operator delete(void* ptr, size_t) { free(ptr); } -void operator delete[](void* ptr, size_t sz) +void operator delete[](void* ptr, size_t) { free(ptr); } diff --git a/Sming/Arch/Esp8266/Components/heap/custom_heap.c b/Sming/Arch/Esp8266/Components/heap/custom_heap.c index ba4f020b2b..362d5c2760 100644 --- a/Sming/Arch/Esp8266/Components/heap/custom_heap.c +++ b/Sming/Arch/Esp8266/Components/heap/custom_heap.c @@ -20,11 +20,15 @@ void* IRAM_ATTR pvPortMalloc(size_t size, const char* file, int line) { + (void)file; + (void)line; return UMM_FUNC(malloc)(size); } void IRAM_ATTR vPortFree(void *ptr, const char* file, int line) { + (void)file; + (void)line; UMM_FUNC(free)(ptr); } @@ -50,16 +54,22 @@ void IRAM_ATTR free(void *ptr) void* IRAM_ATTR pvPortCalloc(size_t count, size_t size, const char* file, int line) { + (void)file; + (void)line; return UMM_FUNC(calloc)(count, size); } void* IRAM_ATTR pvPortRealloc(void *ptr, size_t size, const char* file, int line) { + (void)file; + (void)line; return UMM_FUNC(realloc)(ptr, size); } void* IRAM_ATTR pvPortZalloc(size_t size, const char* file, int line) { + (void)file; + (void)line; return UMM_FUNC(calloc)(1, size); } diff --git a/Sming/Arch/Esp8266/Components/libc/README.rst b/Sming/Arch/Esp8266/Components/libc/README.rst index 9c35198999..da7461217b 100644 --- a/Sming/Arch/Esp8266/Components/libc/README.rst +++ b/Sming/Arch/Esp8266/Components/libc/README.rst @@ -3,6 +3,5 @@ Esp8266 LIBC Component .. highlight:: bash -This Component accommodates the differences in runtime libraries for the various supported toolchains. - -See also :doc:`/arch/esp8266/getting-started/eqt`. +This Component supports integration of the standard C library provided by the compiler toolchain. +See also :ref:`esp_quick_toolchain`. diff --git a/Sming/Arch/Esp8266/Components/libc/component.mk b/Sming/Arch/Esp8266/Components/libc/component.mk index 8e5247d0f3..8f98addef3 100644 --- a/Sming/Arch/Esp8266/Components/libc/component.mk +++ b/Sming/Arch/Esp8266/Components/libc/component.mk @@ -1,17 +1,9 @@ -COMPONENT_SRCDIRS := COMPONENT_INCDIRS := include COMPONENT_SRCDIRS := src COMPONENT_DOXYGEN_INPUT := include/sys -ifeq ($(USE_NEWLIB),1) -COMPONENT_SRCDIRS += src/newlib EXTRA_LIBS += m c gcc -else -COMPONENT_SRCDIRS += src/oldlib -LIBDIRS += $(COMPONENT_PATH)/lib -EXTRA_LIBS += microc microgcc setjmp -endif ifndef MAKE_CLEAN diff --git a/Sming/Arch/Esp8266/Components/libc/include/sys/pgmspace.h b/Sming/Arch/Esp8266/Components/libc/include/sys/pgmspace.h index 42a23c0b1b..0d348681b5 100644 --- a/Sming/Arch/Esp8266/Components/libc/include/sys/pgmspace.h +++ b/Sming/Arch/Esp8266/Components/libc/include/sys/pgmspace.h @@ -153,16 +153,16 @@ static inline uint16_t pgm_read_word_inlined(const void* addr) * @{ */ -void* memcpy_P(void* dest, const void* src_P, size_t length); -int memcmp_P(const void* a1, const void* b1, size_t len); -size_t strlen_P(const char* src_P); -char* strcpy_P(char* dest, const char* src_P); -char* strncpy_P(char* dest, const char* src_P, size_t size); -int strcmp_P(const char* str1, const char* str2_P); -int strncmp_P(const char* str1, const char* str2_P, const size_t size); -int strcasecmp_P(const char* str1, const char* str2_P); -char* strcat_P(char* dest, const char* src_P); -char* strstr_P(char* haystack, const char* needle_P); +void* memcpy_P(void* dest, PGM_VOID_P src_P, size_t length); +int memcmp_P(const void* buf1, PGM_VOID_P buf2_P, size_t len); +size_t strlen_P(PGM_VOID_P src_P); +char* strcpy_P(char* dest, PGM_P src_P); +char* strncpy_P(char* dest, PGM_P src_P, size_t size); +int strcmp_P(const char* str1, PGM_P str2_P); +int strncmp_P(const char* str1, PGM_P str2_P, const size_t size); +int strcasecmp_P(const char* str1, PGM_P str2_P); +char* strcat_P(char* dest, PGM_P src_P); +char* strstr_P(char* haystack, PGM_P needle_P); #define sprintf_P(s, f_P, ...) \ (__extension__({ \ diff --git a/Sming/Arch/Esp8266/Components/libc/lib/libmicroc.a b/Sming/Arch/Esp8266/Components/libc/lib/libmicroc.a deleted file mode 100644 index f130480852..0000000000 Binary files a/Sming/Arch/Esp8266/Components/libc/lib/libmicroc.a and /dev/null differ diff --git a/Sming/Arch/Esp8266/Components/libc/lib/libmicrogcc.a b/Sming/Arch/Esp8266/Components/libc/lib/libmicrogcc.a deleted file mode 100644 index baaedb473b..0000000000 Binary files a/Sming/Arch/Esp8266/Components/libc/lib/libmicrogcc.a and /dev/null differ diff --git a/Sming/Arch/Esp8266/Components/libc/lib/libsetjmp.a b/Sming/Arch/Esp8266/Components/libc/lib/libsetjmp.a deleted file mode 100644 index 1bf5b61882..0000000000 Binary files a/Sming/Arch/Esp8266/Components/libc/lib/libsetjmp.a and /dev/null differ diff --git a/Sming/Arch/Esp8266/Components/libc/src/libc.c b/Sming/Arch/Esp8266/Components/libc/src/libc.c index c0c8447a6b..d2b351e985 100644 --- a/Sming/Arch/Esp8266/Components/libc/src/libc.c +++ b/Sming/Arch/Esp8266/Components/libc/src/libc.c @@ -23,6 +23,8 @@ int* __errno(void) void __assert_func(const char* file, int line, const char* func, const char* what) { + (void)file; + (void)what; SYSTEM_ERROR("ASSERT: %s %d", func, line); gdb_do_break(); while(1) { diff --git a/Sming/Arch/Esp8266/Components/libc/src/newlib/libc_replacements.c b/Sming/Arch/Esp8266/Components/libc/src/libc_replacements.c similarity index 100% rename from Sming/Arch/Esp8266/Components/libc/src/newlib/libc_replacements.c rename to Sming/Arch/Esp8266/Components/libc/src/libc_replacements.c diff --git a/Sming/Arch/Esp8266/Components/libc/src/oldlib/README.rst b/Sming/Arch/Esp8266/Components/libc/src/oldlib/README.rst deleted file mode 100644 index ee596e987e..0000000000 --- a/Sming/Arch/Esp8266/Components/libc/src/oldlib/README.rst +++ /dev/null @@ -1,7 +0,0 @@ -This directory contains the following source code from sourceware's newlib -at https://sourceware.org/git/?p=newlib-cygwin.git;a=tree;f=newlib/libc/string - -strcspn.c -strspn.c - -License LGPL3 applies. diff --git a/Sming/Arch/Esp8266/Components/libc/src/oldlib/pgmspace.c b/Sming/Arch/Esp8266/Components/libc/src/oldlib/pgmspace.c deleted file mode 100644 index 741a4cce4f..0000000000 --- a/Sming/Arch/Esp8266/Components/libc/src/oldlib/pgmspace.c +++ /dev/null @@ -1,139 +0,0 @@ -/**** - * Sming Framework Project - Open Source framework for high efficiency native ESP8266 development. - * Created 2015 by Skurydin Alexey - * http://github.com/SmingHub/Sming - * All files of the Sming Core are provided under the LGPL v3 license. - * - * pgmspace.c - for use with newlib < 2.2 - * - ****/ - -#include -#include - -void* memcpy_P(void* dest, const void* src_P, size_t length) -{ - // Yes, it seems dest must also be aligned - if(IS_ALIGNED(dest) && IS_ALIGNED(src_P) && IS_ALIGNED(length)) { - return memcpy(dest, src_P, length); - } - - char* dest0 = (char*)dest; - const char* src0 = (const char*)src_P; - while(length-- != 0) { - *dest0++ = pgm_read_byte(src0++); - } - - return dest; -} - -int memcmp_P(const void* a1, const void* b1, size_t len) -{ - const uint8_t* a = (const uint8_t*)a1; - const uint8_t* b = (const uint8_t*)b1; - for(size_t i = 0; i < len; i++, ++a, ++b) { - uint8_t d = pgm_read_byte(a) - pgm_read_byte(b); - if(d != 0) { - return d; - } - } - return 0; -} - -size_t strlen_P(const char* src_P) -{ - char val; - size_t len = 0; - while((val = pgm_read_byte(src_P)) != 0) { - ++len; - ++src_P; - } - - return len; -} - -char* strcpy_P(char* dest, const char* src_P) -{ - for(char* p = dest; (*p = pgm_read_byte(src_P++)); p++) - ; - return dest; -} - -char* strncpy_P(char* dest, const char* src_P, size_t max_len) -{ - size_t len = strlen_P(src_P); - if(len > max_len) { - len = max_len; - } else if(len < max_len) { - dest[len] = '\0'; - } - memcpy_P(dest, src_P, len); - return dest; -} - -int strcmp_P(const char* str1, const char* str2_P) -{ - for(; *str1 == pgm_read_byte(str2_P); str1++, str2_P++) { - if(*str1 == '\0') - return 0; - } - return *(unsigned char*)str1 < (unsigned char)pgm_read_byte(str2_P) ? -1 : 1; -} - -int strncmp_P(const char* str1, const char* str2_P, const size_t size) -{ - for(unsigned i = 0; *str1 == pgm_read_byte(str2_P); str1++, str2_P++, i++) { - if(i == size) { - return 0; - } - } - return *(unsigned char*)str1 < (unsigned char)pgm_read_byte(str2_P) ? -1 : 1; -} - -char* strstr_P(char* haystack, const char* needle_P) -{ - const char* b = needle_P; - if(pgm_read_byte(b) == 0) { - return haystack; - } - - for(; *haystack != 0; haystack++) { - if(*haystack != pgm_read_byte(b)) - continue; - - char* a = haystack; - while(1) { - char c = pgm_read_byte(b); - if(c == 0) { - return haystack; - } - - if(*a != c) { - break; - } - - a++; - b++; - } - - b = needle_P; - } - - return 0; -} - -int strcasecmp_P(const char* str1, const char* str2_P) -{ - for(; tolower((unsigned char)*str1) == tolower(pgm_read_byte(str2_P)); str1++, str2_P++) { - if(*str1 == '\0') - return 0; - } - return tolower(*(unsigned char*)str1) < tolower(pgm_read_byte(str2_P)) ? -1 : 1; -} - -char* strcat_P(char* dest, const char* src_P) -{ - dest += strlen(dest); - strcpy_P(dest, src_P); - return dest; -} diff --git a/Sming/Arch/Esp8266/Components/libc/src/oldlib/strcspn.c b/Sming/Arch/Esp8266/Components/libc/src/oldlib/strcspn.c deleted file mode 100644 index abaa93ad67..0000000000 --- a/Sming/Arch/Esp8266/Components/libc/src/oldlib/strcspn.c +++ /dev/null @@ -1,48 +0,0 @@ -/* -FUNCTION - <>---count characters not in string - -INDEX - strcspn - -SYNOPSIS - size_t strcspn(const char *<[s1]>, const char *<[s2]>); - -DESCRIPTION - This function computes the length of the initial part of - the string pointed to by <[s1]> which consists entirely of - characters <[NOT]> from the string pointed to by <[s2]> - (excluding the terminating null character). - -RETURNS - <> returns the length of the substring found. - -PORTABILITY -<> is ANSI C. - -<> requires no supporting OS subroutines. - */ - -#include - -size_t -strcspn (const char *s1, - const char *s2) -{ - const char *s = s1; - const char *c; - - while (*s1) - { - for (c = s2; *c; c++) - { - if (*s1 == *c) - break; - } - if (*c) - break; - s1++; - } - - return s1 - s; -} diff --git a/Sming/Arch/Esp8266/Components/libc/src/oldlib/strerror.c b/Sming/Arch/Esp8266/Components/libc/src/oldlib/strerror.c deleted file mode 100644 index 149954c15e..0000000000 --- a/Sming/Arch/Esp8266/Components/libc/src/oldlib/strerror.c +++ /dev/null @@ -1,22 +0,0 @@ -/**** - * Sming Framework Project - Open Source framework for high efficiency native ESP8266 development. - * Created 2015 by Skurydin Alexey - * http://github.com/SmingHub/Sming - * All files of the Sming Core are provided under the LGPL v3 license. - * - * strerror.c - microc library doesn't contain strerror_r - * - ****/ - -#include - -int __xpg_strerror_r(int err, char* buf, size_t bufSize) -{ - m_snprintf(buf, bufSize, "ERROR #%u", err); - if(buf != NULL && bufSize > 0) { - buf[bufSize - 1] = '\0'; - } - return 0; -} - -int strerror_r(int err, char* buf, size_t bufSize) __attribute__((weak, alias("__xpg_strerror_r"))); diff --git a/Sming/Arch/Esp8266/Components/libc/src/oldlib/strspn.c b/Sming/Arch/Esp8266/Components/libc/src/oldlib/strspn.c deleted file mode 100644 index baf2399478..0000000000 --- a/Sming/Arch/Esp8266/Components/libc/src/oldlib/strspn.c +++ /dev/null @@ -1,52 +0,0 @@ -/* -FUNCTION - <>---find initial match - -INDEX - strspn - -SYNOPSIS - #include - size_t strspn(const char *<[s1]>, const char *<[s2]>); - -DESCRIPTION - This function computes the length of the initial segment of - the string pointed to by <[s1]> which consists entirely of - characters from the string pointed to by <[s2]> (excluding the - terminating null character). - -RETURNS - <> returns the length of the segment found. - -PORTABILITY -<> is ANSI C. - -<> requires no supporting OS subroutines. - -QUICKREF - strspn ansi pure -*/ - -#include - -size_t -strspn (const char *s1, - const char *s2) -{ - const char *s = s1; - const char *c; - - while (*s1) - { - for (c = s2; *c; c++) - { - if (*s1 == *c) - break; - } - if (*c == '\0') - break; - s1++; - } - - return s1 - s; -} diff --git a/Sming/Arch/Esp8266/Components/lwip2/Makefile.sming b/Sming/Arch/Esp8266/Components/lwip2/Makefile.sming new file mode 100644 index 0000000000..75e0453f2f --- /dev/null +++ b/Sming/Arch/Esp8266/Components/lwip2/Makefile.sming @@ -0,0 +1,50 @@ +# Modified version of lwip2/makefiles/Makefile.build-lwip2 +# Make from ./lwip2 directory + +include makefiles/Makefile.defs + +export LWIP_ESP=glue-esp/lwip-1.4-arduino/include +export LWIP_LIB=$(BUILD)/liblwip2.a +export target=arduino +export BUILD +export TCP_MSS +export LWIP_FEATURES +export LWIP_IPV6 +export V +export DEFINE_TARGET=ARDUINO +export LWIP_INCLUDES_RELEASE=include + +AUTO := \ + glue-lwip/lwip-err-t.h \ + glue-lwip/lwip-git-hash.h + +all: patch $(LWIP_LIB_RELEASE) + +.PHONY: upstream +upstream: lwip2-src/README + +.PHONY: patch +patch: upstream $(AUTO) + $(Q) $(MAKE) --no-print-directory -C lwip2-src/src -f ../../makefiles/Makefile.patches + +lwip2-src/README: + $(Q) git clone --depth=1 -b $(UPSTREAM_VERSION) https://github.com/lwip-tcpip/lwip lwip2-src + +glue-lwip/lwip-err-t.h: $(LWIP_ESP)/arch/cc.h upstream + $(Q) ( \ + echo "// script-generated, extracted from espressif SDK's lwIP arch/cc.h"; \ + echo "#define LWIP_NO_STDINT_H 1"; \ + echo "typedef signed short sint16_t;"; \ + grep -e LWIP_ERR_T -e ^typedef $< \ + ) > $@ + +glue-lwip/lwip-git-hash.h: upstream + makefiles/make-lwip-hash + +$(LWIP_LIB_RELEASE): $(LWIP_LIB) + @cp $< $@ + +$(LWIP_LIB): + $(Q) $(MAKE) -f makefiles/Makefile.glue-esp + $(Q) $(MAKE) -f makefiles/Makefile.glue + $(Q) $(MAKE) -C lwip2-src/src -f ../../makefiles/Makefile.lwip2 diff --git a/Sming/Arch/Esp8266/Components/lwip2/README.rst b/Sming/Arch/Esp8266/Components/lwip2/README.rst index 9432be959c..046e80905f 100644 --- a/Sming/Arch/Esp8266/Components/lwip2/README.rst +++ b/Sming/Arch/Esp8266/Components/lwip2/README.rst @@ -1,4 +1,40 @@ Esp8266 LWIP Version 2 ====================== -This Component implements the current Version 2 LWIP stack. Note that at present espconn\_* functions are not supported. +This Component implements the current Version 2 LWIP stack. + +.. note:: + + Prior to :pull_request:`2793`, ``espconn_*`` functions were unsupported, but their current status is unclear. + Please `raise an issue `__ if you require these and encounter problems. + + +.. envvar:: TCP_MSS + + Maximum TCP segment size. Default 1460. + + +.. envvar:: LWIP_IPV6 + + default: 0 (disabled) + + Set to enable IPv6 support. + + +.. envvar:: LWIP_FEATURES + + If anyone knows of an actual reference for this setting, link here please! + + Looking at glue-lwip/arduino/lwipopts.h, setting :envvar:`LWIP_FEATURES=1 ` enables these LWIP flags: + + - IP_FORWARD + - IP_REASSEMBLY + - IP_FRAG + - IP_NAPT (IPV4 only) + - LWIP_AUTOIP + - LWIP_DHCP_AUTOIP_COOP + - LWIP_TCP_SACK_OUT + - TCP_LISTEN_BACKLOG + - SNTP_MAX_SERVERS = 3 + + Also DHCP discovery gets hooked. diff --git a/Sming/Arch/Esp8266/Components/lwip2/component.mk b/Sming/Arch/Esp8266/Components/lwip2/component.mk index 20fb20b408..301af99494 100644 --- a/Sming/Arch/Esp8266/Components/lwip2/component.mk +++ b/Sming/Arch/Esp8266/Components/lwip2/component.mk @@ -10,33 +10,69 @@ ifeq ($(SMING_RELEASE),1) endif COMPONENT_VARS := ENABLE_LWIPDEBUG ENABLE_ESPCONN -ENABLE_LWIPDEBUG ?= 0 +ifneq ($(ENABLE_LWIPDEBUG),1) +override ENABLE_LWIPDEBUG := 0 +endif ENABLE_ESPCONN ?= 0 EXTRA_CFLAGS_LWIP := \ -I$(SMING_HOME)/System/include \ -I$(ARCH_COMPONENTS)/esp8266/include \ - -I$(ARCH_COMPONENTS)/libc/include + -I$(ARCH_COMPONENTS)/libc/include \ + -DULWIPDEBUG=$(ENABLE_LWIPDEBUG) -ifeq ($(ENABLE_LWIPDEBUG), 1) - EXTRA_CFLAGS_LWIP += -DLWIP_DEBUG -endif -ifeq ($(ENABLE_ESPCONN), 1) -$(error LWIP2 does not support espconn_* functions. Make sure to set ENABLE_CUSTOM_LWIP to 0 or 1.) +COMPONENT_SUBMODULES := lwip2 +COMPONENT_INCDIRS := \ + lwip2/glue-lwip/arduino \ + lwip2/glue-lwip \ + lwip2/glue \ + lwip2/lwip2-src/src/include + +LWIP2_PATH := $(COMPONENT_PATH)/lwip2 +LWIP2_LIBPATH := $(COMPONENT_LIBDIR) + +# +COMPONENT_VARS += TCP_MSS LWIP_IPV6 LWIP_FEATURES +TCP_MSS ?= 1460 +ifneq ($(LWIP_IPV6),1) +override LWIP_IPV6 := 0 +endif +ifneq ($(LWIP_FEATURES),1) +LWIP_FEATURES := 0 endif -COMPONENT_SUBMODULES := lwip2 -COMPONENT_INCDIRS := lwip2/glue-esp/include-esp lwip2/include +LWIP2_HASHVAL := $(foreach v,$(COMPONENT_VARS),$v=$($v)) +LWIP2_LIBHASH := $(call CalculateVariantHash,LWIP2_HASHVAL) +LWIP2_BUILD_DIR := $(COMPONENT_BUILD_BASE)/$(LWIP2_LIBHASH) -LWIP2_PATH := $(COMPONENT_PATH)/lwip2 +GLOBAL_CFLAGS += \ + -DTCP_MSS=$(TCP_MSS) \ + -DLWIP_IPV6=$(LWIP_IPV6) \ + -DLWIP_FEATURES=$(LWIP_FEATURES) \ + -DULWIPDEBUG=$(ENABLE_LWIPDEBUG) # Make is pretty complex for LWIP2, and mucks about with output sections so build as a regular library LWIP2_LIB := $(COMPONENT_NAME) -LWIP2_TARGET := $(COMPONENT_LIBDIR)/lib$(LWIP2_LIB).a +LWIP2_TARGET := $(LWIP2_BUILD_DIR)/lib$(LWIP2_LIB).a COMPONENT_TARGETS := $(LWIP2_TARGET) EXTRA_LIBS := $(LWIP2_LIB) +LIBDIRS += $(LWIP2_BUILD_DIR) + +COMPONENT_PREREQUISITES := $(LWIP2_PATH)/glue-lwip/lwip-err-t.h + +$(LWIP2_PATH)/glue-lwip/lwip-err-t.h: + $(Q) $(MAKE) -C $(LWIP2_PATH) -f ../Makefile.sming patch + $(COMPONENT_RULE)$(LWIP2_TARGET): - $(Q) $(MAKE) -C $(LWIP2_PATH) -f Makefile.sming BUILD=$(COMPONENT_BUILD_DIR) \ - USER_LIBDIR=$(COMPONENT_LIBDIR)/ CFLAGS_EXTRA="$(EXTRA_CFLAGS_LWIP)" CC=$(CC) AR=$(AR) all + $(Q) $(MAKE) --no-print-directory -C $(LWIP2_PATH) -f ../Makefile.sming \ + all \ + CFLAGS_EXTRA="$(EXTRA_CFLAGS_LWIP)" \ + LWIP_LIB_RELEASE=$(LWIP2_TARGET) \ + TOOLS=$(TOOLSPEC) \ + TCP_MSS=$(TCP_MSS) \ + LWIP_FEATURES=$(LWIP_FEATURES) \ + LWIP_IPV6=$(LWIP_IPV6) \ + BUILD=$(LWIP2_BUILD_DIR)/build \ + Q=$(Q) V=$(if $V,1,0) diff --git a/Sming/Arch/Esp8266/Components/lwip2/lwip2 b/Sming/Arch/Esp8266/Components/lwip2/lwip2 index cfe476dfa2..4087efd9d2 160000 --- a/Sming/Arch/Esp8266/Components/lwip2/lwip2 +++ b/Sming/Arch/Esp8266/Components/lwip2/lwip2 @@ -1 +1 @@ -Subproject commit cfe476dfa2793025660b8698d993258f4a598f8d +Subproject commit 4087efd9d2a8e1cee9a159e0796d831dc1e0c497 diff --git a/Sming/Arch/Esp8266/Components/lwip2/lwip2.patch b/Sming/Arch/Esp8266/Components/lwip2/lwip2.patch new file mode 100644 index 0000000000..ba551c5af1 --- /dev/null +++ b/Sming/Arch/Esp8266/Components/lwip2/lwip2.patch @@ -0,0 +1,134 @@ +diff --git a/glue-lwip/arch/cc.h b/glue-lwip/arch/cc.h +index 0b73cba..fff12b0 100644 +--- a/glue-lwip/arch/cc.h ++++ b/glue-lwip/arch/cc.h +@@ -56,8 +56,6 @@ void sntp_set_system_time (uint32_t t); + #endif + #endif // defined(LWIP_BUILD) + +-#include "mem.h" // useful for os_malloc used in esp-arduino's mDNS +- + #include "glue.h" // include assembly locking macro used below + typedef uint32_t sys_prot_t; + #define SYS_ARCH_DECL_PROTECT(lev) sys_prot_t lev +diff --git a/glue-lwip/esp-dhcpserver.c b/glue-lwip/esp-dhcpserver.c +index 6ac8a41..cd1faf0 100644 +--- a/glue-lwip/esp-dhcpserver.c ++++ b/glue-lwip/esp-dhcpserver.c +@@ -12,7 +12,7 @@ + #include "lwip/apps-esp/dhcpserver.h" + + #include "user_interface.h" +-#include "mem.h" ++#include + + #include "glue.h" + #include "lwip-helper.h" +diff --git a/glue/esp-missing.h b/glue/esp-missing.h +index b9fea2a..63bbb45 100644 +--- a/glue/esp-missing.h ++++ b/glue/esp-missing.h +@@ -12,18 +12,15 @@ uint32_t r_rand (void); + + // TODO: Patch these in from SDK + +-#if ARDUINO +-void* pvPortZalloc (size_t, const char*, int); +-void* pvPortMalloc (size_t xWantedSize, const char* file, int line) __attribute__((malloc, alloc_size(1))); +-void vPortFree (void *ptr, const char* file, int line); +-#else +-void *pvPortZalloc (size_t sz, const char *, unsigned); +-void *pvPortMalloc (size_t sz, const char *, unsigned) __attribute__((malloc, alloc_size(1))); +-void vPortFree (void *p, const char *, unsigned); +-#endif ++#include ++ ++#define ets_post system_os_post ++#define ets_task system_os_task + + struct netif* eagle_lwip_getif (int netif_index); + ++#if 0 ++ + void ets_intr_lock (void); + void ets_intr_unlock (void); + +@@ -61,3 +58,5 @@ struct ip_info; + #define os_memcpy ets_memcpy + + #endif ++ ++#endif +diff --git a/glue/gluedebug.h b/glue/gluedebug.h +index 9358878..905e41e 100644 +--- a/glue/gluedebug.h ++++ b/glue/gluedebug.h +@@ -10,10 +10,10 @@ + // because it is shared by both sides of glue + + #define UNDEBUG 1 // 0 or 1 (1: uassert removed = saves flash) +-#define UDEBUG 0 // 0 or 1 (glue debug) ++#define UDEBUG ULWIPDEBUG // 0 or 1 (glue debug) + #define UDUMP 0 // 0 or 1 (glue: dump packet) + +-#define ULWIPDEBUG 0 // 0 or 1 (trigger lwip debug) ++// #define ULWIPDEBUG 0 // 0 or 1 (trigger lwip debug) + #define ULWIPASSERT 0 // 0 or 1 (trigger lwip self-check, 0 saves flash) + + #if ARDUINO +@@ -58,7 +58,7 @@ extern void (*phy_capture) (int netif_idx, const char* data, size_t len, int out + + #include // os_printf* definitions + ICACHE_RODATA_ATTR + +-#if defined(ARDUINO) ++#if 0 + // os_printf() does not understand ("%hhx",0x12345678) => "78") and prints 'h' instead + // now hacking/using ::printf() from updated and patched esp-quick-toolchain-by-Earle + #include +diff --git a/makefiles/Makefile.glue b/makefiles/Makefile.glue +index 366d849..3fe3a6c 100644 +--- a/makefiles/Makefile.glue ++++ b/makefiles/Makefile.glue +@@ -3,6 +3,7 @@ + + GLUE_LWIP = lwip-git.c + GLUE_LWIP += esp-ping.c ++GLUE_LWIP += esp-dhcpserver.c + ifneq ($(target),arduino) + GLUE_LWIP += esp-dhcpserver.c + GLUE_LWIP += esp-time.c +@@ -14,7 +15,7 @@ OBJ = \ + $(patsubst %.c,$(BUILD)/%.o,$(wildcard glue/*.c)) \ + $(patsubst %.c,$(BUILD)/glue-lwip/%.o,$(GLUE_LWIP)) \ + +-BUILD_INCLUDES = -I$(BUILD) -Iglue -Iglue-lwip -Iglue-lwip/$(target) -Ilwip2-src/src/include -I$(SDK)/include ++BUILD_INCLUDES = -I$(BUILD) -Iglue -Iglue-lwip -Iglue-lwip/$(target) -Ilwip2-src/src/include $(CFLAGS_EXTRA) + + include makefiles/Makefile.defs + include makefiles/Makefile.rules +diff --git a/makefiles/Makefile.glue-esp b/makefiles/Makefile.glue-esp +index 8b756ff..ea414b1 100644 +--- a/makefiles/Makefile.glue-esp ++++ b/makefiles/Makefile.glue-esp +@@ -6,7 +6,7 @@ ifeq ($(LWIP_ESP),) + $(error LWIP_ESP must point to espressif sdk lwip/include) + endif + +-BUILD_INCLUDES = -I$(BUILD) -I$(SDK)/include -I$(LWIP_ESP) -Iglue ++BUILD_INCLUDES = -I$(BUILD) $(CFLAGS_EXTRA) -I$(LWIP_ESP) -Iglue + BUILD_FLAGS += -DLWIP14GLUE + + include makefiles/Makefile.defs +diff --git a/makefiles/Makefile.lwip2 b/makefiles/Makefile.lwip2 +index 6a4ccbd..01133ec 100644 +--- a/makefiles/Makefile.lwip2 ++++ b/makefiles/Makefile.lwip2 +@@ -13,7 +13,7 @@ OBJ = \ + # $(subst ../../lwip2-contrib-src/,contrib/, \ + # $(patsubst %.c,$(BUILD)/%.o,$(wildcard ../../lwip2-contrib-src/apps/ping/*.c))) + +-BUILD_INCLUDES = -I$(BUILD) -I$(SDK)/include -Iinclude -I../../glue -I../../glue-lwip -I../../glue-lwip/$(target) ++BUILD_INCLUDES = -I$(BUILD) $(CFLAGS_EXTRA) -Iinclude -I../../glue -I../../glue-lwip -I../../glue-lwip/$(target) + #BUILD_INCLUDES += -I../../lwip2-contrib-src/apps/ping + + all: $(LWIP_LIB) diff --git a/Sming/Arch/Esp8266/Components/sming-arch/README.rst b/Sming/Arch/Esp8266/Components/sming-arch/README.rst index 7ca74663cb..91cf0d42d1 100644 --- a/Sming/Arch/Esp8266/Components/sming-arch/README.rst +++ b/Sming/Arch/Esp8266/Components/sming-arch/README.rst @@ -3,11 +3,6 @@ Sming (Esp8266) This Component builds a library containing architecture-specific code, and defines dependencies for Sming to build for the Esp8266. -SDK 3.0+ --------- - -Default: OFF. In order to use SDK 3.0.0 or newer please follow the instructions here :component-esp8266:`esp8266`. - No-WiFi build ------------- @@ -35,28 +30,13 @@ controlled by the :envvar:`ENABLE_CUSTOM_LWIP` setting. 1 (default) Use custom compiled :component-esp8266:`esp-open-lwip` stack. Compared with the Espressif stack, this uses less RAM but - consumes FLASH (program) memory. All espconn\_* functions are turned off by default, so if you require these add - the :envvar:`ENABLE_ESPCONN` =1 directive. The :sample:`Basic_SmartConfig` example sets this in its ``component.mk`` - file. + consumes FLASH (program) memory. All ``espconn_*`` functions are turned off by default, so if you require these add + the :envvar:`ENABLE_ESPCONN=1 ` directive. + The :sample:`Basic_SmartConfig` example sets this in its ``component.mk`` file. 2 - Use :component-esp8266:`lwip2` stack. This does not have support for espconn\_* functions. + Use :component-esp8266:`lwip2` stack. This does not have support for ``espconn_*`` functions. .. envvar:: ENABLE_LWIP_DEBUG By default, some debug information will be printed for critical errors and situations. Set this to 1 to enable printing of all debug information. - - -Interactive debugging on the device ------------------------------------ - -.. envvar:: ENABLE_GDB - - In order to be able to debug live directly on the ESP8266 microcontroller you - should re-compile your application with ``ENABLE_GDB=1`` directive. - - undefined (default) - Compile normally - 1 - Compile with debugging support provided by :component-esp8266:`gdbstub`. - See also the :sample:`LiveDebug` sample. diff --git a/Sming/Arch/Esp8266/Components/spi_flash/flashmem.c b/Sming/Arch/Esp8266/Components/spi_flash/flashmem.c index 75f33ec622..62f9eda42a 100644 --- a/Sming/Arch/Esp8266/Components/spi_flash/flashmem.c +++ b/Sming/Arch/Esp8266/Components/spi_flash/flashmem.c @@ -15,7 +15,7 @@ * ****/ -#include "include/esp_spi_flash.h" +#include #include extern char _flash_code_end[]; @@ -40,7 +40,7 @@ static inline uint32_t min(uint32_t a, uint32_t b) return (a < b) ? a : b; } -uint32_t flashmem_get_address(const void* memptr) +flash_addr_t flashmem_get_address(const void* memptr) { uint32_t addr = (uint32_t)memptr - INTERNAL_FLASH_START_ADDRESS; // Determine which 1MB memory bank is mapped @@ -54,7 +54,7 @@ uint32_t flashmem_get_address(const void* memptr) return addr; } -uint32_t flashmem_write(const void* from, uint32_t toaddr, uint32_t size) +uint32_t flashmem_write(const void* from, flash_addr_t toaddr, uint32_t size) { if(IS_ALIGNED(from) && IS_ALIGNED(toaddr) && IS_ALIGNED(size)) return flashmem_write_internal(from, toaddr, size); @@ -126,7 +126,7 @@ uint32_t flashmem_write(const void* from, uint32_t toaddr, uint32_t size) return size; } -uint32_t flashmem_read(void* to, uint32_t fromaddr, uint32_t size) +uint32_t flashmem_read(void* to, flash_addr_t fromaddr, uint32_t size) { if(IS_ALIGNED(to) && IS_ALIGNED(fromaddr) && IS_ALIGNED(size)) return flashmem_read_internal(to, fromaddr, size); @@ -186,7 +186,7 @@ uint32_t flashmem_read(void* to, uint32_t fromaddr, uint32_t size) return size; } -bool flashmem_erase_sector(uint32_t sector_id) +bool flashmem_erase_sector(flash_sector_t sector_id) { WDT_FEED(); return spi_flash_erase_sector(sector_id) == SPI_FLASH_RESULT_OK; @@ -194,19 +194,31 @@ bool flashmem_erase_sector(uint32_t sector_id) SPIFlashInfo flashmem_get_info() { - SPIFlashInfo spi_flash_info STORE_ATTR; - if(flashmem_read_internal(&spi_flash_info, 0x00000000, sizeof(spi_flash_info)) == 0) { - memset(&spi_flash_info, 0, sizeof(spi_flash_info)); - } - return spi_flash_info; + struct { + uint8_t unknown0; + uint8_t unknown1; + uint8_t mode : 8; ///< SPIFlashMode + uint8_t speed : 4; ///< SPIFlashSpeed + uint8_t size : 4; ///< SPIFlashSize + } raw_info; + if(flashmem_read_internal(&raw_info, 0x00000000, sizeof(raw_info)) == 0) { + SPIFlashInfo nil = {}; + return nil; + } + SPIFlashInfo info = { + .mode = raw_info.mode, + .speed = raw_info.speed, + .size = raw_info.size, + }; + return info; } -uint8_t flashmem_get_size_type() +SPIFlashSize flashmem_get_size_type() { return flashmem_get_info().size; } -uint32_t flashmem_get_size_bytes() +flash_addr_t flashmem_get_size_bytes() { uint32_t flash_size = 0; switch (flashmem_get_info().size) @@ -239,35 +251,11 @@ uint32_t flashmem_get_size_bytes() return flash_size; } -uint16_t flashmem_get_size_sectors() -{ - return flashmem_get_size_bytes() / SPI_FLASH_SEC_SIZE; -} - -uint32_t flashmem_find_sector(uint32_t address, uint32_t *pstart, uint32_t *pend) -{ - // All the sectors in the flash have the same size, so just align the address - uint32_t sect_id = address / INTERNAL_FLASH_SECTOR_SIZE; - - if( pstart ) - *pstart = sect_id * INTERNAL_FLASH_SECTOR_SIZE; - if( pend ) - *pend = ( sect_id + 1 ) * INTERNAL_FLASH_SECTOR_SIZE - 1; - return sect_id; -} - -uint32_t flashmem_get_sector_of_address( uint32_t addr ) -{ - return flashmem_find_sector( addr, NULL, NULL ); -} - -///////////////////////////////////////////////////// - uint32_t flashmem_write_internal( const void *from, uint32_t toaddr, uint32_t size ) { assert(IS_ALIGNED(from) && IS_ALIGNED(toaddr) && IS_ALIGNED(size)); - SpiFlashOpResult r = spi_flash_write(toaddr, (uint32*)from, size); + SpiFlashOpResult r = spi_flash_write(toaddr, (uint32_t*)from, size); if(SPI_FLASH_RESULT_OK == r) return size; else{ @@ -280,7 +268,7 @@ uint32_t flashmem_read_internal( void *to, uint32_t fromaddr, uint32_t size ) { assert(IS_ALIGNED(to) && IS_ALIGNED(fromaddr) && IS_ALIGNED(size)); - SpiFlashOpResult r = spi_flash_read(fromaddr, (uint32*)to, size); + SpiFlashOpResult r = spi_flash_read(fromaddr, (uint32_t*)to, size); if(SPI_FLASH_RESULT_OK == r) return size; else{ @@ -288,11 +276,3 @@ uint32_t flashmem_read_internal( void *to, uint32_t fromaddr, uint32_t size ) return 0; } } - -uint32_t flashmem_get_first_free_block_address() -{ - // Round the total used flash size to the closest flash block address - uint32_t end; - flashmem_find_sector( ( uint32_t )_flash_code_end - INTERNAL_FLASH_START_ADDRESS - 1, NULL, &end); - return end + 1; -} diff --git a/Sming/Arch/Esp8266/Components/spi_flash/include/esp_spi_flash.h b/Sming/Arch/Esp8266/Components/spi_flash/include/esp_spi_flash.h index 51904f8a58..0893b15b30 100644 --- a/Sming/Arch/Esp8266/Components/spi_flash/include/esp_spi_flash.h +++ b/Sming/Arch/Esp8266/Components/spi_flash/include/esp_spi_flash.h @@ -25,18 +25,7 @@ extern "C" { * @{ */ -/// Flash memory access must be aligned and in multiples of 4-byte words -#define INTERNAL_FLASH_WRITE_UNIT_SIZE 4 -#define INTERNAL_FLASH_READ_UNIT_SIZE 4 - -#define FLASH_TOTAL_SEC_COUNT (flashmem_get_size_sectors()) - -/// Number of flash sectors reserved for system parameters at start -#define SYS_PARAM_SEC_COUNT 4 -#define FLASH_WORK_SEC_COUNT (FLASH_TOTAL_SEC_COUNT - SYS_PARAM_SEC_COUNT) - #define INTERNAL_FLASH_SECTOR_SIZE SPI_FLASH_SEC_SIZE -#define INTERNAL_FLASH_SIZE ((FLASH_WORK_SEC_COUNT)*INTERNAL_FLASH_SECTOR_SIZE) #define INTERNAL_FLASH_START_ADDRESS 0x40200000 typedef enum { @@ -64,85 +53,6 @@ typedef enum { SIZE_1MBIT = 0xFF, ///< Not supported } SPIFlashSize; -/** @brief SPI Flash memory information block. - * Stored at the beginning of flash memory. - */ -typedef struct { - uint8_t unknown0; - uint8_t unknown1; - uint8_t mode : 8; ///< SPIFlashMode - uint8_t speed : 4; ///< SPIFlashSpeed - uint8_t size : 4; ///< SPIFlashSize -} STORE_TYPEDEF_ATTR SPIFlashInfo; - -/** @brief Obtain the flash memory address for a memory pointer - * @param memptr - * @retval uint32_t Offset from start of flash memory - * @note If memptr is not in valid flash memory it will return an offset which exceeds - * the internal flash memory size. - * @note The flash location is dependent on where rBoot has mapped the firmware. - */ -uint32_t flashmem_get_address(const void* memptr); - -/** @brief Write a block of data to flash - * @param from Buffer to obtain data from - * @param toaddr Flash location to start writing - * @param size Number of bytes to write - * @retval uint32_t Number of bytes written - * @note None of the parameters need to be aligned - */ -uint32_t flashmem_write(const void* from, uint32_t toaddr, uint32_t size); - -/** @brief Read a block of data from flash - * @param to Buffer to store data - * @param fromaddr Flash location to start reading - * @param size Number of bytes to read - * @retval uint32_t Number of bytes written - * @note none of the parameters need to be aligned - */ -uint32_t flashmem_read(void* to, uint32_t fromaddr, uint32_t size); - -/** @brief Erase a single flash sector - * @param sector_id the sector to erase - * @retval true on success - */ -bool flashmem_erase_sector(uint32_t sector_id); - -/** @brief Get flash memory information block - * @retval SPIFlashInfo Information block - */ -SPIFlashInfo flashmem_get_info(); - -/** @brief Returns a number indicating the size of flash memory chip - * @retval uint8_t See SpiFlashInfo.size field for possible values - */ -uint8_t flashmem_get_size_type(); - -/** @brief get the total flash memory size - * @retval uint32_t Size in bytes - */ -uint32_t flashmem_get_size_bytes(); - -/** @brief Get the total number of flash sectors - * @retval uint16_t Sector count - */ -uint16_t flashmem_get_size_sectors(); - -/** @brief Helper function: find the flash sector in which an address resides - * @param address - * @param pstart OUT/OPTIONAL: Start of sector containing the given address - * @param pend OUT/OPTIONAL: Last address in sector - * @retval uint32_t Sector number for the given address - * @note Optional parameters may be null - */ -uint32_t flashmem_find_sector(uint32_t address, uint32_t* pstart, uint32_t* pend); - -/** @brief Get sector number containing the given address - * @param addr - * @retval uint32_t sector number - */ -uint32_t flashmem_get_sector_of_address(uint32_t addr); - /** @brief write to flash memory * @param from Buffer to read data from - MUST be word-aligned * @param toaddr Flash address (offset) to write to - MUST be word-aligned @@ -161,14 +71,8 @@ uint32_t flashmem_write_internal(const void* from, uint32_t toaddr, uint32_t siz */ uint32_t flashmem_read_internal(void* to, uint32_t fromaddr, uint32_t size); -/* - * @brief Returns the address of the first free block on flash - * @retval uint32_t The actual address on flash - */ -uint32_t flashmem_get_first_free_block_address(); - -/** @} */ - #ifdef __cplusplus } #endif + +#include diff --git a/Sming/Arch/Esp8266/Core/Digital.cpp b/Sming/Arch/Esp8266/Core/Digital.cpp index 434b69589f..7a7af26d1e 100644 --- a/Sming/Arch/Esp8266/Core/Digital.cpp +++ b/Sming/Arch/Esp8266/Core/Digital.cpp @@ -9,19 +9,42 @@ ****/ #include -#include "ESP8266EX.h" #include #include #include #include +#define TOTAL_PINS 16 + +#define PINMUX_OFFSET(addr) uint8_t((addr)-PERIPHS_IO_MUX) + +// Used for pullup/noPullup +extern const uint8_t esp8266_pinmuxOffset[] = { + PINMUX_OFFSET(PERIPHS_IO_MUX_GPIO0_U), // 0 FLASH + PINMUX_OFFSET(PERIPHS_IO_MUX_U0TXD_U), // 1 TXD0 + PINMUX_OFFSET(PERIPHS_IO_MUX_GPIO2_U), // 2 TXD1 + PINMUX_OFFSET(PERIPHS_IO_MUX_U0RXD_U), // 3 RXD0 + PINMUX_OFFSET(PERIPHS_IO_MUX_GPIO4_U), // 4 + PINMUX_OFFSET(PERIPHS_IO_MUX_GPIO5_U), // 5 + PINMUX_OFFSET(PERIPHS_IO_MUX_SD_CLK_U), // 6 SD_CLK_U + PINMUX_OFFSET(PERIPHS_IO_MUX_SD_DATA0_U), // 7 SD_DATA0_U + PINMUX_OFFSET(PERIPHS_IO_MUX_SD_DATA1_U), // 8 SD_DATA1_U + PINMUX_OFFSET(PERIPHS_IO_MUX_SD_DATA2_U), // 9 + PINMUX_OFFSET(PERIPHS_IO_MUX_SD_DATA3_U), // 10 + PINMUX_OFFSET(PERIPHS_IO_MUX_SD_CMD_U), // 11 SD_CMD_U + PINMUX_OFFSET(PERIPHS_IO_MUX_MTDI_U), // 12 HSPIQ + PINMUX_OFFSET(PERIPHS_IO_MUX_MTCK_U), // 13 HSPID + PINMUX_OFFSET(PERIPHS_IO_MUX_MTMS_U), // 14 HSPICLK + PINMUX_OFFSET(PERIPHS_IO_MUX_MTDO_U), // 15 HSPICS +}; + // Prototype declared in esp8266-peri.h -const uint8_t esp8266_gpioToFn[16] = {0x34, 0x18, 0x38, 0x14, 0x3C, 0x40, 0x1C, 0x20, - 0x24, 0x28, 0x2C, 0x30, 0x04, 0x08, 0x0C, 0x10}; +const uint8_t esp8266_gpioToFn[TOTAL_PINS] = {0x34, 0x18, 0x38, 0x14, 0x3C, 0x40, 0x1C, 0x20, + 0x24, 0x28, 0x2C, 0x30, 0x04, 0x08, 0x0C, 0x10}; void pinMode(uint16_t pin, uint8_t mode) { - if(pin < 16) { + if(pin < TOTAL_PINS) { if(mode == SPECIAL) { GPC(pin) = (GPC(pin) & (0xF << GPCI)); //SOURCE(GPIO) | DRIVER(NORMAL) | INT_TYPE(UNCHANGED) | WAKEUP_ENABLE(DISABLED) @@ -100,38 +123,32 @@ void digitalWrite(uint16_t pin, uint8_t val) pullup(pin); else noPullup(pin); - } else { - if(pin != 16) - GPIO_REG_WRITE((((val != LOW) ? GPIO_OUT_W1TS_ADDRESS : GPIO_OUT_W1TC_ADDRESS)), (1 << pin)); - else - WRITE_PERI_REG(RTC_GPIO_OUT, (READ_PERI_REG(RTC_GPIO_OUT) & (uint32)0xfffffffe) | (uint32)(val & 1)); - - //GPIO_OUTPUT_SET(pin, (val ? 0xFF : 00)); - } + } else if(pin != 16) + GPIO_REG_WRITE((((val != LOW) ? GPIO_OUT_W1TS_ADDRESS : GPIO_OUT_W1TC_ADDRESS)), (1 << pin)); + else + WRITE_PERI_REG(RTC_GPIO_OUT, (READ_PERI_REG(RTC_GPIO_OUT) & (uint32_t)0xfffffffe) | (uint32_t)(val & 1)); } uint8_t digitalRead(uint16_t pin) { - if(pin != 16) + if(pin != 16) { return ((GPIO_REG_READ(GPIO_IN_ADDRESS) >> pin) & 1); - else - return (uint8)(READ_PERI_REG(RTC_GPIO_IN_DATA) & 1); - - //return GPIO_INPUT_GET(pin); + } + return (uint8_t)(READ_PERI_REG(RTC_GPIO_IN_DATA) & 1); } void pullup(uint16_t pin) { - if(pin >= 16) - return; - PIN_PULLUP_EN((EspDigitalPins[pin].mux)); + if(pin < TOTAL_PINS) { + PIN_PULLUP_EN(PERIPHS_IO_MUX + esp8266_pinmuxOffset[pin]); + } } void noPullup(uint16_t pin) { - if(pin >= 16) - return; - PIN_PULLUP_DIS((EspDigitalPins[pin].mux)); + if(pin < TOTAL_PINS) { + PIN_PULLUP_DIS(PERIPHS_IO_MUX + esp8266_pinmuxOffset[pin]); + } } /* Measures the length (in microseconds) of a pulse on the pin; state is HIGH diff --git a/Sming/Arch/Esp8266/Core/ESP8266EX.cpp b/Sming/Arch/Esp8266/Core/ESP8266EX.cpp deleted file mode 100644 index 59e8bd4250..0000000000 --- a/Sming/Arch/Esp8266/Core/ESP8266EX.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/**** - * Sming Framework Project - Open Source framework for high efficiency native ESP8266 development. - * Created 2015 by Skurydin Alexey - * http://github.com/SmingHub/Sming - * All files of the Sming Core are provided under the LGPL v3 license. - * - * ESP8266EX.cpp - * - ****/ - -#include "Digital.h" -#include "ESP8266EX.h" -#include "Digital.h" -#include - -const EspDigitalPin EspDigitalPins[] = { - {0, PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0}, // FLASH - {1, PERIPHS_IO_MUX_U0TXD_U, FUNC_GPIO1}, // TXD0 - {2, PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2}, // TXD1 - {3, PERIPHS_IO_MUX_U0RXD_U, FUNC_GPIO3}, // RXD0 - {4, PERIPHS_IO_MUX_GPIO4_U, FUNC_GPIO4}, - {5, PERIPHS_IO_MUX_GPIO5_U, FUNC_GPIO5}, - {6, 0, 0}, // SD_CLK_U - {7, 0, 0}, // SD_DATA0_U - {8, 0, 0}, // SD_DATA1_U - {9, PERIPHS_IO_MUX_SD_DATA2_U, FUNC_GPIO9}, - {10, PERIPHS_IO_MUX_SD_DATA3_U, FUNC_GPIO10}, - {11, 0, 0}, // SD_CMD_U - {12, PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12}, // HSPIQ - {13, PERIPHS_IO_MUX_MTCK_U, FUNC_GPIO13}, // HSPID - {14, PERIPHS_IO_MUX_MTMS_U, FUNC_GPIO14}, // HSPICLK - {15, PERIPHS_IO_MUX_MTDO_U, FUNC_GPIO15}, // HSPICS -}; - -void EspDigitalPin::mode(uint8_t mode) const -{ - pinMode(id, mode); -} - -void EspDigitalPin::write(uint8_t val) const -{ - digitalWrite(id, val); -} - -uint8_t EspDigitalPin::read() const -{ - return digitalRead(id); -} diff --git a/Sming/Arch/Esp8266/Core/ESP8266EX.h b/Sming/Arch/Esp8266/Core/ESP8266EX.h deleted file mode 100644 index 6d83620d37..0000000000 --- a/Sming/Arch/Esp8266/Core/ESP8266EX.h +++ /dev/null @@ -1,38 +0,0 @@ -/**** - * Sming Framework Project - Open Source framework for high efficiency native ESP8266 development. - * Created 2015 by Skurydin Alexey - * http://github.com/SmingHub/Sming - * All files of the Sming Core are provided under the LGPL v3 license. - * - * ESP8266EX.h - * - ****/ - -#pragma once - -#include - -#define TOTAL_PINS 16 -#define NUM_DIGITAL_PINS TOTAL_PINS - -/** @brief ESP GPIO pin configuration - * @ingroup constants - */ -struct EspDigitalPin { - uint8_t id; - uint32_t mux; - uint8_t gpioFunc; - - operator const int() const - { - return id; - } - void mode(uint8_t mode) const; - void write(uint8_t val) const; - uint8_t read() const; -}; - -/** @brief ESP GPIO pin configuration - * @ingroup gpio - */ -extern const EspDigitalPin EspDigitalPins[]; diff --git a/Sming/Arch/Esp8266/Core/HardwarePWM.cpp b/Sming/Arch/Esp8266/Core/HardwarePWM.cpp index 585f5b813e..13aa43764a 100644 --- a/Sming/Arch/Esp8266/Core/HardwarePWM.cpp +++ b/Sming/Arch/Esp8266/Core/HardwarePWM.cpp @@ -25,11 +25,14 @@ #include #include -#include "ESP8266EX.h" #include +#include "pins_arduino.h" +#include #define PERIOD_TO_MAX_DUTY(x) (x * 25) +extern const uint8_t esp8266_pinmuxOffset[]; + HardwarePWM::HardwarePWM(uint8_t* pins, uint8_t noOfPins) : channel_count(noOfPins) { if(noOfPins == 0) { @@ -38,15 +41,22 @@ HardwarePWM::HardwarePWM(uint8_t* pins, uint8_t noOfPins) : channel_count(noOfPi uint32_t ioInfo[PWM_CHANNEL_NUM_MAX][3]; // pin information uint32_t pwmDutyInit[PWM_CHANNEL_NUM_MAX]; // pwm duty + unsigned pinCount = 0; for(uint8_t i = 0; i < noOfPins; i++) { - ioInfo[i][0] = EspDigitalPins[pins[i]].mux; - ioInfo[i][1] = EspDigitalPins[pins[i]].gpioFunc; - ioInfo[i][2] = EspDigitalPins[pins[i]].id; - pwmDutyInit[i] = 0; // Start with zero output - channels[i] = pins[i]; + auto pin = pins[i]; + assert(pin < 16); + if(pin >= 16) { + continue; + } + ioInfo[pinCount][0] = PERIPHS_IO_MUX + esp8266_pinmuxOffset[pin]; + ioInfo[pinCount][1] = esp8266_gpioToFn[pin]; + ioInfo[pinCount][2] = pin; + pwmDutyInit[pinCount] = 0; // Start with zero output + channels[pinCount] = pin; + ++pinCount; } const int initialPeriod = 1000; - pwm_init(initialPeriod, pwmDutyInit, noOfPins, ioInfo); + pwm_init(initialPeriod, pwmDutyInit, pinCount, ioInfo); update(); maxduty = PERIOD_TO_MAX_DUTY(initialPeriod); // for period of 1000 } diff --git a/Sming/Arch/Esp8266/Core/Interrupts.cpp b/Sming/Arch/Esp8266/Core/Interrupts.cpp index 7996b9e58f..fa8c10f385 100644 --- a/Sming/Arch/Esp8266/Core/Interrupts.cpp +++ b/Sming/Arch/Esp8266/Core/Interrupts.cpp @@ -31,14 +31,14 @@ static void interruptDelegateCallback(uint32_t interruptNumber) * @param intr_mask Interrupt mask * @param arg pointer to array of arguments */ -static void IRAM_ATTR interruptHandler(uint32 intr_mask, void* arg) +static void IRAM_ATTR interruptHandler([[maybe_unused]] uint32_t intr_mask, [[maybe_unused]] void* arg) { bool processed; do { - uint32 gpioStatus = GPIO_REG_READ(GPIO_STATUS_ADDRESS); + uint32_t gpioStatus = GPIO_REG_READ(GPIO_STATUS_ADDRESS); processed = false; - for(uint8 i = 0; i < MAX_INTERRUPTS; i++) { + for(uint8_t i = 0; i < MAX_INTERRUPTS; i++) { if(!bitRead(gpioStatus, i)) { continue; } @@ -73,7 +73,7 @@ void attachInterrupt(uint8_t pin, InterruptDelegate delegateFunction, GPIO_INT_T return; // WTF o_O } gpioInterruptsList[pin] = nullptr; - delegateFunctionList[pin] = delegateFunction; + delegateFunctionList[pin] = std::move(delegateFunction); attachInterruptHandler(pin, type); } diff --git a/Sming/Arch/Esp8266/Core/i2s.cpp b/Sming/Arch/Esp8266/Core/i2s.cpp index e9b9a1a467..68c1ad3d50 100644 --- a/Sming/Arch/Esp8266/Core/i2s.cpp +++ b/Sming/Arch/Esp8266/Core/i2s.cpp @@ -155,7 +155,7 @@ bool i2s_read_sample(int16_t* left, int16_t* right, bool blocking) return true; } -static void IRAM_ATTR i2s_callback(void* param, i2s_event_type_t event) +static void IRAM_ATTR i2s_callback([[maybe_unused]] void* param, i2s_event_type_t event) { switch(event) { case I2S_EVENT_TX_DONE: diff --git a/Sming/Arch/Esp8266/Platform/RTC.cpp b/Sming/Arch/Esp8266/Platform/RTC.cpp index b06db69d65..a42188e0f9 100644 --- a/Sming/Arch/Esp8266/Platform/RTC.cpp +++ b/Sming/Arch/Esp8266/Platform/RTC.cpp @@ -10,12 +10,14 @@ #include #include +#include +#include RtcClass RTC; #define RTC_MAGIC 0x55aaaa55 #define RTC_DES_ADDR 64 + 3 ///< rBoot may require 3 words at start -#define NS_PER_SECOND 1000000000 +#define NS_PER_SECOND 1'000'000'000 /** @brief Structure to hold RTC data * @addtogroup structures @@ -67,8 +69,8 @@ bool RtcClass::setRtcSeconds(uint32_t seconds) void updateTime(RtcData& data) { - uint32 rtc_cycles; - uint32 cal, cal1, cal2; + uint32_t rtc_cycles; + uint32_t cal, cal1, cal2; cal1 = system_rtc_clock_cali_proc(); __asm__ __volatile__("memw" : : : "memory"); // Just for fun cal2 = system_rtc_clock_cali_proc(); @@ -97,9 +99,52 @@ void loadTime(RtcData& data) // Initialise the time struct if(data.magic != RTC_MAGIC) { - debugf("rtc time init..."); + debug_d("rtc time init..."); data.magic = RTC_MAGIC; data.time = 0; data.cycles = 0; } } + +extern "C" int settimeofday(const struct timeval* tv, const struct timezone* tz) +{ + // os_printf_plus("** settimeofday(%p, %p), secs = %u\r\n", tv, tz, tv ? unsigned(tv->tv_sec) : 0); + + // Received from lwip2 SNTP + const uint32_t LWIP2_SNTP_MAGIC = 0xfeedC0de; + + if(reinterpret_cast(tz) == LWIP2_SNTP_MAGIC) { + tz = nullptr; + } + + if(tz || !tv) { + // tz is obsolete (cf. man settimeofday) + return EINVAL; + } + + // lwip2 calls this during static initialisation, before RTC is initialised, so ignore value 0 + if(tv->tv_sec) { + uint64_t ns = uint64_t(tv->tv_sec) * NS_PER_SECOND + tv->tv_usec * 1000; + RTC.setRtcNanoseconds(ns); + } + return 0; +} + +extern "C" int _gettimeofday_r(struct _reent*, struct timeval* tp, void*) +{ + if(tp) { + uint32_t micros = RTC.getRtcNanoseconds() / 1000LL; + tp->tv_sec = micros / 1000; + tp->tv_usec = micros % 1000; + } + return 0; +} + +extern "C" time_t time(time_t* t) +{ + time_t seconds = RTC.getRtcSeconds(); + if(t) { + *t = seconds; + } + return seconds; +} diff --git a/Sming/Arch/Esp8266/README.rst b/Sming/Arch/Esp8266/README.rst index a001a3c628..42b07b2425 100644 --- a/Sming/Arch/Esp8266/README.rst +++ b/Sming/Arch/Esp8266/README.rst @@ -3,14 +3,98 @@ Sming Esp8266 Architecture Support building Sming for the Esp8266 architecture. -See also :doc:`/arch/esp8266/getting-started/eqt`. +This is the SOC for which Sming was originally developed, +so many of the low-level API calls reflect those in the +:doc:`SDK `. +These include functions such as +:c:func:`system_get_free_heap_size`, +:c:func:`system_update_cpu_freq`, +:c:func:`system_get_cpu_freq`, +:c:func:`esp_get_ccount` +and others. -Build variables +The Esp8266 is the device which popularised 32-bit microcontrollers +with integrated WiFi capability, the so-called +`System on a chip `__ (SoC). + + +Features +-------- + +- Integrated boot loader :component:`rboot` with support for 1MB ROMs, OTA firmware updating and ROM switching. +- :doc:`Crash handlers ` for analyzing/handling system restarts due to fatal errors or WDT resets. +- :component-esp8266:`PWM support ` based on `Stefan Bruens PWM `__. +- Optional :component-esp8266:`custom heap allocation ` based on `Umm Malloc `__. +- Based on :component-esp8266:`Espressif NONOS SDK Version 3 `. + + +Characteristics --------------- +Compared with more recent offerings such as the +:doc:`ESP32 ` and +:doc:`RP2040 `, +it has characteristics which require special consideration: + +Limited RAM + Typically around 50 KiB of RAM is available for user applications, + compared with over 200 KiB for the Rp2040 and 300 KiB for the Esp32. + Although applications not requiring WiFi can recover another 30 KiB + via :component:`esp_no_wifi`, careful use of RAM is a primary consideration. + See :doc:`/information/memory`. +Word-aligned SPI flash accesses + Flash memory is relatively plentiful, provided via high-speed serial SPI. + Because it is not internal to the SoC, the Esp8266 (and others) have hardware which + supports mapping areas of external memory into the address space so that + code and data can be accessed using standard machine instructions. + The Esp8266 has a particular quirk in that all such accesses must be + properly aligned to 32-bit word boundaries; failure to do this crashes the + system. + Other microcontrollers have better caching which handles misaligned accesses + without issue. See :doc:`/information/flash'. +Weak hardware peripheral support + Even compared to older Atmel or Microchip 8-bit microcontrollers, + hardware support for interfaces such as I2C and PWM is lacking and these must + be implemented in software. + +.. _esp_quick_toolchain: + +ESP Quick Toolchain +------------------- + +In Sming 4.0.1 support was added for the `ESP Quick Toolchain `__. +This is the required toolchain for compiling Sming for the Esp8266. + +At time of writing the current release is +`3.0.0-newlib4.0.0-gnu20 `__ +for `GCC 10.2 `__. + +The toolchain is consistent across development platforms which also use the +standard C/C++ `NewLib `__ +runtime libraries. + + +Installation +------------ + +The easiest way to get started is with the Sming installer - see :doc:`/getting-started/index`. + +- Linux and MacOS: ``Tools/install.sh esp8266``. +- Windows: ``Tools\install esp8266``. + + +Configuration Variables +----------------------- + .. envvar:: ESP_HOME This contains the base directory for the toolchain used to build the framework. + See :ref:`esp_quick_toolchain`. + + The Sming installer extracts the toolchain to: + + - ``/opt/esp-quick-toolchain`` for linux and MadOS + - ``C:\tools\esp-quick-toolchain`` for Windows Components diff --git a/Sming/Arch/Esp8266/Services/Profiling/TaskStat.cpp b/Sming/Arch/Esp8266/Services/Profiling/TaskStat.cpp index dcedcfcec3..80280f3547 100644 --- a/Sming/Arch/Esp8266/Services/Profiling/TaskStat.cpp +++ b/Sming/Arch/Esp8266/Services/Profiling/TaskStat.cpp @@ -19,9 +19,7 @@ TaskStat::TaskStat(Print& out) : out(out) { } -TaskStat::~TaskStat() -{ -} +TaskStat::~TaskStat() = default; bool TaskStat::update() { diff --git a/Sming/Arch/Esp8266/Tools/ci/build.run.cmd b/Sming/Arch/Esp8266/Tools/ci/build.run.cmd index 4f73d92532..730e3db1a0 100644 --- a/Sming/Arch/Esp8266/Tools/ci/build.run.cmd +++ b/Sming/Arch/Esp8266/Tools/ci/build.run.cmd @@ -5,7 +5,7 @@ REM %MAKE_PARALLEL% samples || goto :error make clean samples-clean %MAKE_PARALLEL% Basic_Blink ENABLE_CUSTOM_HEAP=1 DEBUG_VERBOSE_LEVEL=3 || goto :error -%MAKE_PARALLEL% HttpServer_ConfigNetwork ENABLE_CUSTOM_LWIP=2 STRICT=1 || goto :error +make HttpServer_ConfigNetwork ENABLE_CUSTOM_LWIP=2 STRICT=1 || goto :error %MAKE_PARALLEL% Basic_Templates || goto :error goto :EOF diff --git a/Sming/Arch/Esp8266/Tools/install.cmd b/Sming/Arch/Esp8266/Tools/install.cmd index 33ec662a42..5b6e0b5971 100644 --- a/Sming/Arch/Esp8266/Tools/install.cmd +++ b/Sming/Arch/Esp8266/Tools/install.cmd @@ -1,9 +1,31 @@ REM Esp8266 install.cmd -call :install "%ESP_HOME%" x86_64-w64-mingw32.xtensa-lx106-elf-e6a192b.201211.zip +if "%ESP_HOME%" == "" goto :undefined +if exist "%ESP_HOME%" goto :installed + +echo. +echo ** Installing ESP8266 toolchain +echo. + +set EQT_REPO=https://github.com/earlephilhower/esp-quick-toolchain/releases/download/3.2.0-gcc10.3 +set EQT_TOOLCHAIN=x86_64-w64-mingw32.xtensa-lx106-elf-c791b74.230224.zip + +mkdir %ESP_HOME% +curl -Lo %DOWNLOADS%/%EQT_TOOLCHAIN% %EQT_REPO%/%EQT_TOOLCHAIN% || goto :EOF +7z -o%ESP_HOME% x %DOWNLOADS%/%EQT_TOOLCHAIN% || goto :EOF + goto :EOF -:install -mkdir %1 -curl -Lo %DOWNLOADS%/%2 %SMINGTOOLS%/%2 -7z -o%1 x %DOWNLOADS%/%2 + +:undefined +echo. +echo ** Cannot install Esp8266 tools: ESP_HOME not defined +echo. +goto :EOF + + +:installed +echo. +echo ** Skipping Esp8266 tools installation: '%ESP_HOME%' exists +echo. +goto :EOF diff --git a/Sming/Arch/Esp8266/Tools/install.sh b/Sming/Arch/Esp8266/Tools/install.sh index 29c1cb3fce..057e406816 100755 --- a/Sming/Arch/Esp8266/Tools/install.sh +++ b/Sming/Arch/Esp8266/Tools/install.sh @@ -2,13 +2,18 @@ # # Esp8266 install.sh -EQT_REPO=https://github.com/earlephilhower/esp-quick-toolchain/releases/download/3.0.0-newlib4.0.0-gnu20 +EQT_REPO="https://github.com/earlephilhower/esp-quick-toolchain/releases/download/3.2.0-gcc10.3" +if [ "$DIST" = "darwin" ]; then +EQT_PLATFORM="x86_64-apple-darwin14" +else +EQT_PLATFORM="$(uname -m)-linux-gnu" +fi +EQT_TOOLCHAIN="$EQT_PLATFORM.xtensa-lx106-elf-c791b74.230224.tar.gz" if [ -d "$ESP_HOME" ]; then - printf "\n\n** Skipping Esp8266 tools installation: '$ESP_HOME' exists\n\n" + printf "\n\n** Skipping Esp8266 tools installation: '%s' exists\n\n" "$ESP_HOME" else - TOOLCHAIN="$(uname -m)-linux-gnu.xtensa-lx106-elf-e6a192b.201211.tar.gz" - $WGET "$EQT_REPO/$TOOLCHAIN" -O "$DOWNLOADS/$TOOLCHAIN" + $WGET "$EQT_REPO/$EQT_TOOLCHAIN" -O "$DOWNLOADS/$EQT_TOOLCHAIN" mkdir -p "$ESP_HOME" - tar -zxf "$DOWNLOADS/$TOOLCHAIN" -C "$ESP_HOME" --totals + tar -zxf "$DOWNLOADS/$EQT_TOOLCHAIN" -C "$ESP_HOME" --totals fi diff --git a/Sming/Arch/Esp8266/Tools/travis/build.run.sh b/Sming/Arch/Esp8266/Tools/travis/build.run.sh deleted file mode 100755 index 7719f237b4..0000000000 --- a/Sming/Arch/Esp8266/Tools/travis/build.run.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -set -ex # exit with nonzero exit code if anything fails - -make -C "$SMING_PROJECTS_DIR/samples/HttpServer_FirmwareUpload" python-requirements -$MAKE_PARALLEL samples -make clean samples-clean -$MAKE_PARALLEL Basic_Blink ENABLE_CUSTOM_HEAP=1 DEBUG_VERBOSE_LEVEL=3 -$MAKE_PARALLEL HttpServer_ConfigNetwork ENABLE_CUSTOM_LWIP=2 STRICT=1 diff --git a/Sming/Arch/Esp8266/Tools/travis/build.setup.sh b/Sming/Arch/Esp8266/Tools/travis/build.setup.sh deleted file mode 100755 index 5234ca9f7a..0000000000 --- a/Sming/Arch/Esp8266/Tools/travis/build.setup.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -set -ex # exit with nonzero exit code if anything fails - -unset SPIFFY -unset ESPTOOL2 -unset SDK_BASE - -export PATH=$PATH:$ESP_HOME/xtensa-lx106-elf/bin:$ESP_HOME/utils/ diff --git a/Sming/Arch/Esp8266/Tools/travis/install.sh b/Sming/Arch/Esp8266/Tools/travis/install.sh deleted file mode 100644 index 9f0f866075..0000000000 --- a/Sming/Arch/Esp8266/Tools/travis/install.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -set -ex # exit with nonzero exit code if anything fails - -if [ "$TRAVIS_OS_NAME" == "linux" ]; then - # Old toolchain - TOOLCHAIN=esp-open-sdk-linux-x86_64.tar.gz - wget --no-verbose $SMINGTOOLS/$TOOLCHAIN - tar -zxf $TOOLCHAIN - mkdir -p $TRAVIS_BUILD_DIR/opt/esp-alt-sdk - ln -s $(pwd)/esp-open-sdk/xtensa-lx106-elf $TRAVIS_BUILD_DIR/opt/esp-alt-sdk/. - - # New toolchain - TOOLCHAIN=x86_64-linux-gnu.xtensa-lx106-elf-e6a192b.201211.tar.gz - wget --no-verbose $SMINGTOOLS/$TOOLCHAIN - mkdir -p opt/esp-quick-toolchain - tar -zxf $TOOLCHAIN -C opt/esp-quick-toolchain --totals -fi diff --git a/Sming/Arch/Esp8266/build.mk b/Sming/Arch/Esp8266/build.mk index a094406823..583dbf63cd 100644 --- a/Sming/Arch/Esp8266/build.mk +++ b/Sming/Arch/Esp8266/build.mk @@ -11,11 +11,9 @@ CXXFLAGS += -fno-threadsafe-statics DEBUG_VARS += ESP_HOME ifeq ($(UNAME),Windows) -ESP_HOME ?= c:/Espressif -else ifeq ($(UNAME),FreeBSD) -ESP_HOME ?= /usr/local/esp8266/esp-open-sdk +ESP_HOME ?= c:/tools/esp-quick-toolchain else -ESP_HOME ?= /opt/esp-open-sdk +ESP_HOME ?= /opt/esp-quick-toolchain endif export ESP_HOME := $(call FixPath,$(ESP_HOME)) @@ -35,8 +33,6 @@ OBJDUMP := $(TOOLSPEC)objdump NM := $(TOOLSPEC)nm GDB := $(TOOLSPEC)gdb -GCC_UPGRADE_URL := https://sming.readthedocs.io/en/latest/arch/esp8266/getting-started/eqt.html - CPPFLAGS += \ -nostdlib \ -mlongcalls \ @@ -53,8 +49,5 @@ ifeq (,$(wildcard $(XTENSA_TOOLS_ROOT))) $(error ESP_HOME not set correctly: "$(ESP_HOME)") endif -# Identifies which library we're building with -USE_NEWLIB = $(GCC_VERSION_COMPATIBLE) - # => Tools MEMANALYZER = $(PYTHON) $(ARCH_TOOLS)/memanalyzer.py $(OBJDUMP)$(TOOL_EXT) diff --git a/Sming/Arch/Host/Components/SerialLib/seriallib.patch b/Sming/Arch/Host/Components/SerialLib/seriallib.patch index 269d0a3cda..d304bd4983 100644 --- a/Sming/Arch/Host/Components/SerialLib/seriallib.patch +++ b/Sming/Arch/Host/Components/SerialLib/seriallib.patch @@ -1,5 +1,5 @@ diff --git a/lib/serialib.cpp b/lib/serialib.cpp -index 8dbe52f..dc25811 100644 +index 8dbe52f..e8a8eee 100644 --- a/lib/serialib.cpp +++ b/lib/serialib.cpp @@ -135,7 +135,7 @@ char serialib::openDevice(const char *Device,const unsigned int Bauds) @@ -11,6 +11,24 @@ index 8dbe52f..dc25811 100644 } // 8 bit data dcbSerialParams.ByteSize=8; +@@ -169,7 +169,7 @@ char serialib::openDevice(const char *Device,const unsigned int Bauds) + + + // Open device +- fd = open(Device, O_RDWR | O_NOCTTY | O_NDELAY); ++ fd = open(Device, O_RDWR | O_NOCTTY | O_NONBLOCK); + // If the device is not open, return -1 + if (fd == -1) return -2; + // Open the device in nonblocking mode +@@ -179,7 +179,7 @@ char serialib::openDevice(const char *Device,const unsigned int Bauds) + // Get the current options of the port + tcgetattr(fd, &options); + // Clear all the options +- bzero(&options, sizeof(options)); ++ memset(&options, 0, sizeof(options)); + + // Prepare speed (Bauds) + speed_t Speed; @@ -609,7 +609,7 @@ int serialib::available() // Device errors DWORD commErrors; diff --git a/Sming/Arch/Host/Components/driver/adc.cpp b/Sming/Arch/Host/Components/driver/adc.cpp index 09bddd3db4..2195d31bdf 100644 --- a/Sming/Arch/Host/Components/driver/adc.cpp +++ b/Sming/Arch/Host/Components/driver/adc.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include uint16_t system_adc_read(void) diff --git a/Sming/Arch/Host/Components/driver/hw_timer.cpp b/Sming/Arch/Host/Components/driver/hw_timer.cpp index e0d8f2c28c..ca61e486eb 100644 --- a/Sming/Arch/Host/Components/driver/hw_timer.cpp +++ b/Sming/Arch/Host/Components/driver/hw_timer.cpp @@ -56,7 +56,7 @@ class CTimerThread : public CThread callback.arg = nullptr; } - void enable(hw_timer_clkdiv_t div, hw_timer_intr_type_t intr_type, bool auto_load) + void enable(hw_timer_clkdiv_t div, hw_timer_intr_type_t, bool auto_load) { stop(); switch(div) { @@ -120,7 +120,6 @@ class CTimerThread : public CThread private: typedef std::ratio base_ticks_per_us; uint32_t divisor = 1; - uint32_t frequency = HW_TIMER_BASE_CLK; uint64_t start_time = 0; uint64_t interval = 0; // In microseconds CSemaphore sem; // Signals state change @@ -130,7 +129,6 @@ class CTimerThread : public CThread State state = stopped; hw_timer_source_type_t source_type = TIMER_FRC1_SOURCE; - unsigned irq_level = 1; struct { hw_timer_callback_t func = nullptr; void* arg = nullptr; @@ -205,7 +203,7 @@ static std::unique_ptr timer1; void hw_timer_init(void) { - timer1.reset(new CTimerThread("Timer1")); + timer1 = std::make_unique("Timer1"); } void hw_timer_cleanup() diff --git a/Sming/Arch/Host/Components/driver/include/driver/os_timer.h b/Sming/Arch/Host/Components/driver/include/driver/os_timer.h index 4502fc2e23..fc8ae7affc 100644 --- a/Sming/Arch/Host/Components/driver/include/driver/os_timer.h +++ b/Sming/Arch/Host/Components/driver/include/driver/os_timer.h @@ -52,7 +52,7 @@ void os_timer_setfn(os_timer_t* ptimer, os_timer_func_t* pfunction, void* parg); static inline uint64_t os_timer_expire(const os_timer_t* ptimer) { - if(ptimer == nullptr || int(ptimer->timer_next) == -1) { + if(ptimer == nullptr || intptr_t(ptimer->timer_next) == -1) { return 0; } return ptimer->timer_expire; diff --git a/Sming/Arch/Host/Components/driver/os_timer.cpp b/Sming/Arch/Host/Components/driver/os_timer.cpp index e546c35256..1d0f77f4dd 100644 --- a/Sming/Arch/Host/Components/driver/os_timer.cpp +++ b/Sming/Arch/Host/Components/driver/os_timer.cpp @@ -67,7 +67,7 @@ void os_timer_disarm(struct os_timer_t* ptimer) { assert(ptimer != nullptr); - if(int(ptimer->timer_next) == -1) { + if(intptr_t(ptimer->timer_next) == -1) { return; } diff --git a/Sming/Arch/Host/Components/driver/uart.cpp b/Sming/Arch/Host/Components/driver/uart.cpp index d67e386020..9294a03355 100644 --- a/Sming/Arch/Host/Components/driver/uart.cpp +++ b/Sming/Arch/Host/Components/driver/uart.cpp @@ -73,11 +73,6 @@ void notify(smg_uart_t* uart, smg_uart_notify_code_t code) } } -__forceinline bool smg_uart_isr_enabled(uint8_t nr) -{ - return bitRead(isrMask, nr); -} - } // namespace smg_uart_t* smg_uart_get_uart(uint8_t uart_nr) diff --git a/Sming/Arch/Host/Components/driver/uart.rst b/Sming/Arch/Host/Components/driver/uart.rst index ea635a9846..1c89671bcf 100644 --- a/Sming/Arch/Host/Components/driver/uart.rst +++ b/Sming/Arch/Host/Components/driver/uart.rst @@ -12,8 +12,8 @@ or directly to local host serial device (e.g. /dev/ttyUSB0, COM4, etc.) If not otherwise reassigned, UART0 output is sent to the console and keyboard input is written to the UART0 receive queue. -Build variables ---------------- +Configuration Variables +----------------------- .. envvar:: ENABLE_HOST_UARTID @@ -63,14 +63,14 @@ Now start a telnet session for each serial port, in separate command windows:: In the application window, press Enter. This behaviour is enabled by the ``pause`` option, which stops the emulator after initialisation so -telnet can connect to it. Without ``pause`` you’ll lose any serial +telnet can connect to it. Without ``pause`` you'll lose any serial output at startup.) .. note:: For Windows users, ``putty`` is a good alternative to telnet. It also has options for things like carriage-return/linefeed translation - (“\\n” -> “\\r\\n`”). Run using:: + ("\\n" -> "\\r\\n"). Run using:: putty telnet://localhost:10000 diff --git a/Sming/Arch/Host/Components/driver/uart_server.cpp b/Sming/Arch/Host/Components/driver/uart_server.cpp index aadc360bd1..bc99a6842f 100644 --- a/Sming/Arch/Host/Components/driver/uart_server.cpp +++ b/Sming/Arch/Host/Components/driver/uart_server.cpp @@ -18,7 +18,6 @@ ****/ #include "uart_server.h" -#include #include #include #include @@ -76,7 +75,7 @@ void* KeyboardThread::thread_routine() buf->writeChar(c); } while((c = getkey()) != KEY_NONE); - uart->status |= UART_RXFIFO_TOUT_INT_ST; + uart->status |= UART_STATUS_RXFIFO_TOUT; interrupt_begin(); @@ -170,9 +169,9 @@ void startup(const Config& config) auto& server = servers[i]; if(devname == nullptr) { - server.reset(new CUartPort(i)); + server = std::make_unique(i); } else { - server.reset(new CUartDevice(i, devname, config.baud[i])); + server = std::make_unique(i, devname, config.baud[i]); } server->execute(); } @@ -254,7 +253,7 @@ int CUart::serviceRead() int space = uart->rx_buffer->getFreeSpace(); if(space < avail) { - uart->status |= UART_RXFIFO_OVF_INT_ST; + uart->status |= UART_STATUS_RXFIFO_OVF; } int read = std::min(space, avail); if(read != 0) { @@ -266,9 +265,9 @@ int CUart::serviceRead() } space -= read; if(space == 0) { - uart->status |= UART_RXFIFO_FULL_INT_ST; + uart->status |= UART_STATUS_RXFIFO_FULL; } else { - uart->status |= UART_RXFIFO_TOUT_INT_ST; + uart->status |= UART_STATUS_RXFIFO_TOUT; } } } @@ -306,7 +305,7 @@ int CUart::serviceWrite() } while((avail = txbuf->getReadData(data)) != 0); if(txbuf->isEmpty()) { - uart->status |= UART_TXFIFO_EMPTY_INT_ST; + uart->status |= UART_STATUS_TXFIFO_EMPTY; } else { txsem.post(); } @@ -450,7 +449,7 @@ void* CUartDevice::thread_routine() while(!done) { if(txsem.timedwait(IDLE_SLEEP_MS * 1000)) { if(uart != nullptr && !device) { - device.reset(new SerialDevice); + device = std::make_unique(); char res = device->openDevice(deviceName, uart->baud_rate); if(res != 1) { host_debug_e("UART%u error %d opening serial device '%s'", uart_nr, res, deviceName); diff --git a/Sming/Arch/Host/Components/esp_hal/clk.c b/Sming/Arch/Host/Components/esp_hal/clk.c index 8eedfb078f..fa9231f623 100644 --- a/Sming/Arch/Host/Components/esp_hal/clk.c +++ b/Sming/Arch/Host/Components/esp_hal/clk.c @@ -11,19 +11,16 @@ static uint32_t base_ccount; */ static uint32_t get_ccount(uint64_t nanos) { - uint32_t ccount; if(base_nanos == 0) { base_nanos = nanos; base_ccount = nanos / cpu_frequency; - ccount = base_ccount; - } else { - ccount = base_ccount + cpu_frequency * ((nanos - base_nanos) / 1000); + return base_ccount; } - return ccount; + return base_ccount + cpu_frequency * ((nanos - base_nanos) / 1000); } -bool system_update_cpu_freq(uint8 freq) +bool system_update_cpu_freq(uint8_t freq) { if(freq == cpu_frequency) { return true; @@ -46,7 +43,7 @@ uint8_t ets_get_cpu_frequency(void) return cpu_frequency; } -uint8 system_get_cpu_freq(void) +uint8_t system_get_cpu_freq(void) { return ets_get_cpu_frequency(); } diff --git a/Sming/Arch/Host/Components/esp_hal/component.mk b/Sming/Arch/Host/Components/esp_hal/component.mk index 60b7a64153..0b32dac91c 100644 --- a/Sming/Arch/Host/Components/esp_hal/component.mk +++ b/Sming/Arch/Host/Components/esp_hal/component.mk @@ -1,3 +1 @@ -COMPONENT_INCDIRS := include $(ESP8266_COMPONENTS)/esp8266/include - COMPONENT_DEPENDS := hostlib diff --git a/Sming/Arch/Host/Components/esp_hal/include/esp_clk.h b/Sming/Arch/Host/Components/esp_hal/include/esp_clk.h index da77d2650a..eb510b1dce 100644 --- a/Sming/Arch/Host/Components/esp_hal/include/esp_clk.h +++ b/Sming/Arch/Host/Components/esp_hal/include/esp_clk.h @@ -11,7 +11,7 @@ extern "C" { #define SYS_CPU_80MHZ 80 #define SYS_CPU_160MHZ 160 -bool system_update_cpu_freq(uint8 freq); +bool system_update_cpu_freq(uint8_t freq); uint8_t ets_get_cpu_frequency(void); uint8_t system_get_cpu_freq(void); diff --git a/Sming/Arch/Host/Components/esp_hal/include/esp_sleep.h b/Sming/Arch/Host/Components/esp_hal/include/esp_sleep.h index 82b4dfc028..9a6525d167 100644 --- a/Sming/Arch/Host/Components/esp_hal/include/esp_sleep.h +++ b/Sming/Arch/Host/Components/esp_hal/include/esp_sleep.h @@ -31,7 +31,7 @@ void wifi_fpm_auto_sleep_set_in_null_mode(uint8_t req); /* GPIO */ -void wifi_enable_gpio_wakeup(uint32 i, GPIO_INT_TYPE intr_status); +void wifi_enable_gpio_wakeup(uint32_t i, GPIO_INT_TYPE intr_status); void wifi_disable_gpio_wakeup(void); /* These aren't defined in the RTOS SDK */ diff --git a/Sming/Arch/Host/Components/esp_hal/include/esp_system.h b/Sming/Arch/Host/Components/esp_hal/include/esp_system.h index a436fad478..a1d4e0a42e 100644 --- a/Sming/Arch/Host/Components/esp_hal/include/esp_system.h +++ b/Sming/Arch/Host/Components/esp_hal/include/esp_system.h @@ -57,7 +57,7 @@ void os_delay_us(uint32_t us); const char* system_get_sdk_version(void); -uint32 system_get_chip_id(void); +uint32_t system_get_chip_id(void); bool system_rtc_mem_read(uint8_t src_addr, void* des_addr, uint16_t load_size); bool system_rtc_mem_write(uint8_t des_addr, const void* src_addr, uint16_t save_size); diff --git a/Sming/Arch/Host/Components/esp_hal/include/esp_tasks.h b/Sming/Arch/Host/Components/esp_hal/include/esp_tasks.h index be1d289e63..48882c54da 100644 --- a/Sming/Arch/Host/Components/esp_hal/include/esp_tasks.h +++ b/Sming/Arch/Host/Components/esp_hal/include/esp_tasks.h @@ -6,8 +6,8 @@ extern "C" { #endif -typedef uint32_t os_signal_t; -typedef uint32_t os_param_t; +typedef uintptr_t os_signal_t; +typedef uintptr_t os_param_t; typedef struct { os_signal_t sig; @@ -32,9 +32,9 @@ void host_init_tasks(); // Hook function to process task queues void host_service_tasks(); -typedef void (*host_task_callback_t)(uint32_t param); +typedef void (*host_task_callback_t)(os_param_t param); -bool host_queue_callback(host_task_callback_t callback, uint32_t param); +bool host_queue_callback(host_task_callback_t callback, os_param_t param); #ifdef __cplusplus } diff --git a/Sming/Arch/Host/Components/esp_hal/sleep.c b/Sming/Arch/Host/Components/esp_hal/sleep.c index d3aacca753..c922ee21d1 100644 --- a/Sming/Arch/Host/Components/esp_hal/sleep.c +++ b/Sming/Arch/Host/Components/esp_hal/sleep.c @@ -2,11 +2,13 @@ bool system_deep_sleep(uint32_t time_in_us) { + (void)time_in_us; return false; } bool system_deep_sleep_set_option(uint8_t option) { + (void)option; return false; } @@ -24,15 +26,18 @@ void wifi_fpm_do_wakeup(void) void wifi_fpm_set_wakeup_cb(fpm_wakeup_cb cb) { + (void)cb; } sint8 wifi_fpm_do_sleep(uint32_t sleep_time_in_us) { + (void)sleep_time_in_us; return -2; // not enabled } void wifi_fpm_set_sleep_type(enum sleep_type type) { + (void)type; } enum sleep_type wifi_fpm_get_sleep_type(void) @@ -42,12 +47,15 @@ enum sleep_type wifi_fpm_get_sleep_type(void) void wifi_fpm_auto_sleep_set_in_null_mode(uint8_t req) { + (void)req; } /* GPIO */ -void wifi_enable_gpio_wakeup(uint32 i, GPIO_INT_TYPE intr_status) +void wifi_enable_gpio_wakeup(uint32_t i, GPIO_INT_TYPE intr_status) { + (void)i; + (void)intr_status; } void wifi_disable_gpio_wakeup(void) @@ -68,6 +76,7 @@ enum sleep_type wifi_get_sleep_type(void) bool wifi_set_sleep_level(enum sleep_level level) { + (void)level; return false; } @@ -78,6 +87,7 @@ enum sleep_level wifi_get_sleep_level(void) bool wifi_set_listen_interval(uint8_t interval) { + (void)interval; return false; } diff --git a/Sming/Arch/Host/Components/esp_hal/system.cpp b/Sming/Arch/Host/Components/esp_hal/system.cpp index 114cc751a0..ed4159fb10 100644 --- a/Sming/Arch/Host/Components/esp_hal/system.cpp +++ b/Sming/Arch/Host/Components/esp_hal/system.cpp @@ -27,7 +27,7 @@ static uint64_t initTime() timeref.startTicks = os_get_nanoseconds(); #endif - timeval tv; + timeval tv{}; gettimeofday(&tv, nullptr); return (1000000ULL * tv.tv_sec) + tv.tv_usec; } @@ -41,7 +41,7 @@ uint64_t os_get_nanoseconds() QueryPerformanceCounter(&count); return timeref.countsPerNanosecond * uint64_t(count.QuadPart - timeref.startCount.QuadPart); #else - timespec ts; + timespec ts{}; clock_gettime(CLOCK_MONOTONIC, &ts); return (1000000000ULL * ts.tv_sec) + ts.tv_nsec - timeref.startTicks; #endif @@ -96,7 +96,7 @@ const char* system_get_sdk_version(void) return version_string; } -uint32 system_get_chip_id(void) +uint32_t system_get_chip_id(void) { return 0xC001BEAF; } diff --git a/Sming/Arch/Host/Components/esp_hal/tasks.cpp b/Sming/Arch/Host/Components/esp_hal/tasks.cpp index 437d9a6b08..1c561564a0 100644 --- a/Sming/Arch/Host/Components/esp_hal/tasks.cpp +++ b/Sming/Arch/Host/Components/esp_hal/tasks.cpp @@ -9,11 +9,8 @@ class TaskQueue { public: TaskQueue(os_task_t callback, os_event_t* events, uint8_t length) + : callback(callback), events(events), length(length) { - this->callback = callback; - this->events = events; - this->length = length; - read = count = 0; } bool post(os_signal_t sig, os_param_t par) @@ -45,8 +42,8 @@ class TaskQueue static CMutex mutex; os_task_t callback; os_event_t* events; - uint8_t read; - uint8_t count; + uint8_t read{0}; + uint8_t count{0}; uint8_t length; }; @@ -117,7 +114,7 @@ void host_service_tasks() } } -bool host_queue_callback(host_task_callback_t callback, uint32_t param) +bool host_queue_callback(host_task_callback_t callback, os_param_t param) { return task_queues[HOST_TASK_PRIO]->post(os_signal_t(callback), param); } diff --git a/Sming/Arch/Host/Components/esp_wifi/README.rst b/Sming/Arch/Host/Components/esp_wifi/README.rst index 18270f816d..f13ef4ccde 100644 --- a/Sming/Arch/Host/Components/esp_wifi/README.rst +++ b/Sming/Arch/Host/Components/esp_wifi/README.rst @@ -1,4 +1,4 @@ Host WiFi ========= -Provides WiFi / network functions. The actual implementations are provided in :component-host:`lwip` +Provides WiFi / network functions. The actual implementations are provided in :component:`lwip` diff --git a/Sming/Arch/Host/Components/gdbstub/README.rst b/Sming/Arch/Host/Components/gdbstub/README.rst index e0414fc28c..ac2d01f424 100644 --- a/Sming/Arch/Host/Components/gdbstub/README.rst +++ b/Sming/Arch/Host/Components/gdbstub/README.rst @@ -1,10 +1,16 @@ GDB Stub for Host ================= -This defines the command line to use when ``make gdb`` is run. No additional code is required to debug for the Host. +This defines command lines to run Host debuggers, either the GNU debugger:: -If you want to debug your application while having a separate UART then make sure to send the following commands to your debugger:: + make gdb - handle SIGUSR1 nostop noprint +Or LLVM debugger:: -This component provides also ``gdbinit`` file containing the optimal settings needed for debugging. + make lldb + +Generally the GNU debugger is used but for MacOS lldb is the default. + +This Component also provides default settings for each in the ``gdbcmds`` and ``lldbcmds`` files. + +See :doc:`/debugging/host/index`. diff --git a/Sming/Arch/Host/Components/gdbstub/component.mk b/Sming/Arch/Host/Components/gdbstub/component.mk index 46fd3ee841..93950132ca 100644 --- a/Sming/Arch/Host/Components/gdbstub/component.mk +++ b/Sming/Arch/Host/Components/gdbstub/component.mk @@ -4,3 +4,13 @@ GDBSTUB_DIR := $(COMPONENT_PATH) CACHE_VARS += GDB_CMDLINE GDB_CMDLINE = trap '' INT; $(GDB) -x $(GDBSTUB_DIR)/gdbcmds --args $(TARGET_OUT_0) $(CLI_TARGET_OPTIONS) --pause -- $(HOST_PARAMETERS) + +# LLVM debugger +CACHE_VARS += LLDB_CMDLINE +LLDB_CMDLINE = lldb --source $(GDBSTUB_DIR)/lldbcmds $(TARGET_OUT_0) -- $(CLI_TARGET_OPTIONS) --pause $(HOST_PARAMETERS) + +##@Tools + +.PHONY: lldb +lldb: ##Run the LLVM debugger console + $(LLDB_CMDLINE) diff --git a/Sming/Arch/Host/Components/gdbstub/gdb_syscall.cpp b/Sming/Arch/Host/Components/gdbstub/gdb_syscall.cpp index 52c57f1c0d..9eee5702cb 100644 --- a/Sming/Arch/Host/Components/gdbstub/gdb_syscall.cpp +++ b/Sming/Arch/Host/Components/gdbstub/gdb_syscall.cpp @@ -1,7 +1,7 @@ #include -#include +#include -int gdb_syscall(const GdbSyscallInfo& info) +int gdb_syscall(const GdbSyscallInfo&) { errno = ENODEV; return -1; diff --git a/Sming/Arch/Host/Components/gdbstub/gdbstub.c b/Sming/Arch/Host/Components/gdbstub/gdbstub.c index 4b22298076..dd3acb2ea8 100644 --- a/Sming/Arch/Host/Components/gdbstub/gdbstub.c +++ b/Sming/Arch/Host/Components/gdbstub/gdbstub.c @@ -2,6 +2,7 @@ void gdb_enable(bool state) { + (void)state; } GdbState gdb_present(void) @@ -11,19 +12,14 @@ GdbState gdb_present(void) void __attribute__((weak)) gdb_on_attach(bool attached) { + (void)attached; } void gdb_detach(void) { } - - unsigned __gdb_no_op(void) { return 0; } - -//#define NOOP __attribute__((weak, alias("__gdb_no_op"))) -// -//void gdb_on_attach(bool attached) NOOP; diff --git a/Sming/Arch/Host/Components/gdbstub/lldbcmds b/Sming/Arch/Host/Components/gdbstub/lldbcmds new file mode 100644 index 0000000000..346ff806c2 --- /dev/null +++ b/Sming/Arch/Host/Components/gdbstub/lldbcmds @@ -0,0 +1,5 @@ +# Used for interrupt emulation +process handle -p true -s false -n false SIGUSR1 SIGUSR2 + +# Display a welcome prompt +script print("\nWelcome to SMING!\nType 'r' to run application\n\n") diff --git a/Sming/Arch/Host/Components/heap/README.rst b/Sming/Arch/Host/Components/heap/README.rst index a8ea0dac75..83a292391e 100644 --- a/Sming/Arch/Host/Components/heap/README.rst +++ b/Sming/Arch/Host/Components/heap/README.rst @@ -1,5 +1,5 @@ -Heap -==== +Host Heap support +================= This Component implements heap-related housekeeping functions. Heap usage is tracked using :component:`malloc_count`. This also provides some validation (using *sentinels* to detect if memory blocks are overwritten). diff --git a/Sming/Arch/Host/Components/hostlib/README.rst b/Sming/Arch/Host/Components/hostlib/README.rst index 55716d30db..3e6f37db68 100644 --- a/Sming/Arch/Host/Components/hostlib/README.rst +++ b/Sming/Arch/Host/Components/hostlib/README.rst @@ -17,7 +17,7 @@ the :cpp:class:`CommandLine`. Startup ------- -Initialises :component-host:`spi_flash`, Uart server (in :component-host:`driver`) and :component-host:`lwip` +Initialises :component-host:`spi_flash`, Uart server (in :component-host:`driver`) and :component:`lwip` networking, then enters the main task loop. This loop services LWIP plus the task and timer queues (implemented in :component-host:`esp_hal`). The ``Ctrl+C`` keypress is trapped to provide an orderly exit. If the system has become stuck in a loop or is otherwise diff --git a/Sming/Arch/Host/Components/hostlib/component.mk b/Sming/Arch/Host/Components/hostlib/component.mk index 4f6ce7af50..37afff2015 100644 --- a/Sming/Arch/Host/Components/hostlib/component.mk +++ b/Sming/Arch/Host/Components/hostlib/component.mk @@ -2,7 +2,7 @@ EXTRA_LIBS := pthread ifeq ($(UNAME),Windows) EXTRA_LIBS += wsock32 -else +else ifneq ($(UNAME),Darwin) EXTRA_LIBS += rt endif diff --git a/Sming/Arch/Host/Components/hostlib/hostlib.c b/Sming/Arch/Host/Components/hostlib/hostlib.c index 93d6d00941..5dca640e45 100644 --- a/Sming/Arch/Host/Components/hostlib/hostlib.c +++ b/Sming/Arch/Host/Components/hostlib/hostlib.c @@ -21,6 +21,10 @@ #include #include +#ifdef __APPLE__ +#include +#endif + int msleep(unsigned ms) { struct timespec req, rem; @@ -35,14 +39,16 @@ size_t getHostAppDir(char* path, size_t bufSize) return 0; } - size_t len; - char sep; #ifdef __WIN32 - len = GetModuleFileName(NULL, path, bufSize); - sep = '\\'; + size_t len = GetModuleFileName(NULL, path, bufSize); + char sep = '\\'; +#elif defined(__APPLE__) + uint32_t size = bufSize; + size_t len = _NSGetExecutablePath(path, &size) ? 0 : strlen(path); + char sep = '/'; #else - len = readlink("/proc/self/exe", path, bufSize - 1); - sep = '/'; + size_t len = readlink("/proc/self/exe", path, bufSize - 1); + char sep = '/'; #endif path[len] = '\0'; char* p = strrchr(path, sep); diff --git a/Sming/Arch/Host/Components/hostlib/hostmsg.c b/Sming/Arch/Host/Components/hostlib/hostmsg.c index 0c561b0fd4..14b8311cbc 100644 --- a/Sming/Arch/Host/Components/hostlib/hostmsg.c +++ b/Sming/Arch/Host/Components/hostlib/hostmsg.c @@ -56,7 +56,7 @@ void host_printf(const char* fmt, ...) void host_printfp(const char* fmt, const char* pretty_function, ...) { - size_t len; + size_t len = 0; const char* name = get_method_name(pretty_function, &len); va_list args; diff --git a/Sming/Arch/Host/Components/hostlib/include/hostlib/init.h b/Sming/Arch/Host/Components/hostlib/include/hostlib/Streams.h similarity index 55% rename from Sming/Arch/Host/Components/hostlib/include/hostlib/init.h rename to Sming/Arch/Host/Components/hostlib/include/hostlib/Streams.h index 6b73b8afbc..698fb25f05 100644 --- a/Sming/Arch/Host/Components/hostlib/include/hostlib/init.h +++ b/Sming/Arch/Host/Components/hostlib/include/hostlib/Streams.h @@ -1,7 +1,7 @@ -/**** - * hostlib.h +/** + * Streams.h - Print support for host output * - * Copyright 2019 mikee47 + * Copyright 2024 mikee47 * * This file is part of the Sming Framework Project * @@ -19,12 +19,32 @@ #pragma once -#ifdef __cplusplus -extern "C" { -#endif +#include -void host_init(); +namespace Host +{ +class OutputStream : public Print +{ +public: + OutputStream(int fileno) : fileno(fileno) + { + } -#ifdef __cplusplus -} -#endif + virtual size_t write(uint8_t c) override + { + return write(&c, 1); + } + + size_t write(const uint8_t* buffer, size_t size) override + { + return ::write(fileno, buffer, size); + } + +private: + int fileno; +}; + +OutputStream standardOutput(STDOUT_FILENO); +OutputStream standardError(STDERR_FILENO); + +}; // namespace Host diff --git a/Sming/Arch/Host/Components/hostlib/include/hostlib/hostlib.h b/Sming/Arch/Host/Components/hostlib/include/hostlib/hostlib.h index 8dc8f9d2b3..139e8a661f 100644 --- a/Sming/Arch/Host/Components/hostlib/include/hostlib/hostlib.h +++ b/Sming/Arch/Host/Components/hostlib/include/hostlib/hostlib.h @@ -19,10 +19,6 @@ #pragma once -// Required for sleep(), probably others -#undef _POSIX_C_SOURCE -#define _POSIX_C_SOURCE 200112L - #ifdef __WIN32 // Prevent early inclusion of winsock.h #include diff --git a/Sming/Arch/Host/Components/hostlib/init.cpp b/Sming/Arch/Host/Components/hostlib/init.cpp deleted file mode 100644 index 4246269810..0000000000 --- a/Sming/Arch/Host/Components/hostlib/init.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/** - * init.cpp - Sming Host Emulator startup code - * - * Copyright 2019 mikee47 - * - * This file is part of the Sming Framework Project - * - * This library is free software: you can redistribute it and/or modify it under the terms of the - * GNU General Public License as published by the Free Software Foundation, version 3 or later. - * - * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with SHEM. - * If not, see . - * - ****/ - -#include "include/hostlib/init.h" - -extern void init(); - -void host_init() -{ - init(); -} diff --git a/Sming/Arch/Host/Components/hostlib/keyb.cpp b/Sming/Arch/Host/Components/hostlib/keyb.cpp index ed1b418072..1ccb296cde 100644 --- a/Sming/Arch/Host/Components/hostlib/keyb.cpp +++ b/Sming/Arch/Host/Components/hostlib/keyb.cpp @@ -19,9 +19,9 @@ #include "keyb.h" -#include -#include -#include +#include +#include +#include #ifdef __WIN32 @@ -34,9 +34,14 @@ #include #include -static bool g_orig_values_saved, g_values_changed; -static struct termios g_orig_attr; -static int g_orig_flags; +namespace +{ +bool g_orig_values_saved; +bool g_values_changed; +struct termios g_orig_attr; +int g_orig_flags; + +} // namespace #endif @@ -62,9 +67,9 @@ class CKeycode int add(int c); private: - char m_esc; - char m_buffer[32]; - unsigned m_count; + char m_esc{}; + char m_buffer[32]{}; + unsigned m_count{}; void push(char c) { @@ -199,8 +204,9 @@ int CKeycode::add(int c) ret = 0x0300 | m_buffer[0]; else if(m_count == 2) ret = ((m_buffer[0] & 0x0f) << 8) | m_buffer[1]; - else - ; //!! Unexpected + else { + //!! Unexpected + } reset(); break; @@ -228,14 +234,16 @@ int CKeycode::add(int c) void keyb_restore() { #ifndef __WIN32 - if(g_values_changed) { - static struct termios attr = g_orig_attr; - attr.c_lflag |= ICANON | ECHO; - tcsetattr(STDIN_FILENO, TCSANOW, &attr); - - (void)fcntl(0, F_SETFL, g_orig_flags); - g_values_changed = false; + if(!g_values_changed) { + return; } + + static struct termios attr = g_orig_attr; + attr.c_lflag |= ICANON | ECHO; + tcsetattr(STDIN_FILENO, TCSANOW, &attr); + + (void)fcntl(0, F_SETFL, g_orig_flags); + g_values_changed = false; #endif } @@ -271,14 +279,16 @@ int getch() int getkey() { static CKeycode kc; - int c; + int c = 0; for(;;) { c = getch(); - if(c == KEY_NONE) + if(c == KEY_NONE) { break; + } c = kc.add(c); - if(c != KEY_NONE) + if(c != KEY_NONE) { break; + } } return c; } diff --git a/Sming/Arch/Host/Components/hostlib/options.cpp b/Sming/Arch/Host/Components/hostlib/options.cpp index 91beab8a9e..f71c1c7f29 100644 --- a/Sming/Arch/Host/Components/hostlib/options.cpp +++ b/Sming/Arch/Host/Components/hostlib/options.cpp @@ -20,8 +20,8 @@ #include "options.h" #include "include/hostlib/hostmsg.h" #include -#include -#include +#include +#include struct option_help_t { const char* brief; diff --git a/Sming/Arch/Host/Components/hostlib/sockets.cpp b/Sming/Arch/Host/Components/hostlib/sockets.cpp index 4dcc740289..9dfef8e84a 100644 --- a/Sming/Arch/Host/Components/hostlib/sockets.cpp +++ b/Sming/Arch/Host/Components/hostlib/sockets.cpp @@ -19,7 +19,7 @@ #include "sockets.h" #include "include/hostlib/hostmsg.h" -#include +#include #ifndef __WIN32 // For FIONREAD @@ -27,6 +27,24 @@ #include #endif +namespace +{ +/* + * There's no guarantee which version of strerror_r got linked, + * so use overloaded helper function to get correct result. + */ +[[maybe_unused]] const char* get_error_string(char* retval, char*) +{ + return retval; +} + +[[maybe_unused]] const char* get_error_string(int, char* buffer) +{ + return buffer; +} + +} // namespace + void sockets_initialise() { #ifdef __WIN32 @@ -123,19 +141,16 @@ std::string socket_strerror() { char buf[256]; buf[0] = '\0'; - int ErrorCode; #ifdef __WIN32 - ErrorCode = WSAGetLastError(); + int ErrorCode = WSAGetLastError(); FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ARGUMENT_ARRAY, nullptr, ErrorCode, 0, buf, sizeof(buf), nullptr); + return buf[0] ? buf : std::string("Error #" + std::to_string(ErrorCode)); #else - ErrorCode = errno; - char* res = strerror_r(ErrorCode, buf, sizeof(buf)); - if(res == nullptr) { - strcpy(buf, "Unknown"); - } + int ErrorCode = errno; + auto r = strerror_r(ErrorCode, buf, sizeof(buf)); + return get_error_string(r, buf); #endif - return buf[0] ? buf : std::string("Error #" + std::to_string(ErrorCode)); } bool CSocket::create() @@ -438,7 +453,8 @@ CSocket* CServerSocket::try_connect() return nullptr; } - struct sockaddr sa; + struct sockaddr sa { + }; host_socklen_t len = sizeof(sa); int fd = ::accept(m_fd, &sa, &len); if(fd < 0) { diff --git a/Sming/Arch/Host/Components/hostlib/sockets.h b/Sming/Arch/Host/Components/hostlib/sockets.h index 83570d30ab..ffc3437a09 100644 --- a/Sming/Arch/Host/Components/hostlib/sockets.h +++ b/Sming/Arch/Host/Components/hostlib/sockets.h @@ -58,7 +58,7 @@ class CSockAddr struct sockaddr sa; struct sockaddr_in in4; // AF_INET struct sockaddr_in6 in6; // AF_INET6 - } m_addr; + } m_addr{}; public: CSockAddr() @@ -113,12 +113,12 @@ class CSocket assign(fd, addr); } - virtual ~CSocket() + ~CSocket() { close(); } - virtual void close(); + void close(); bool setblocking(bool block); bool bind(const CSockAddr& sa); @@ -213,11 +213,16 @@ class CSocketList : public std::vector class CServerSocket : public CSocket { public: - CServerSocket(int type = SOCK_STREAM) : CSocket(type), m_max_connections(1) + CServerSocket(int type = SOCK_STREAM) : CSocket(type) { } - void close() override + virtual ~CServerSocket() + { + close(); + } + + void close() { m_clients.closeall(); CSocket::close(); @@ -235,6 +240,6 @@ class CServerSocket : public CSocket } private: - unsigned m_max_connections; + unsigned m_max_connections{1}; CSocketList m_clients; }; diff --git a/Sming/Arch/Host/Components/hostlib/startup.cpp b/Sming/Arch/Host/Components/hostlib/startup.cpp index 8bb37fe968..ff13bcd506 100644 --- a/Sming/Arch/Host/Components/hostlib/startup.cpp +++ b/Sming/Arch/Host/Components/hostlib/startup.cpp @@ -31,8 +31,7 @@ #include #include #include -#include -#include "include/hostlib/init.h" +#include #include "include/hostlib/emu.h" #include "include/hostlib/hostlib.h" #include "include/hostlib/CommandLine.h" @@ -43,6 +42,8 @@ #include #endif +extern void init(); + namespace { static int exitCode; @@ -85,7 +86,7 @@ static size_t parse_flash_size(const char* str) if(str == nullptr) { return 0; } - char* tail; + char* tail = nullptr; long res = strtol(str, &tail, 0); if(res < 0) { return 0; @@ -132,21 +133,22 @@ int main(int argc, char* argv[]) struct Config { int pause{-1}; int exitpause{-1}; - int loopcount; - uint8_t cpulimit; - bool initonly; + int loopcount{}; + uint8_t cpulimit{}; + bool initonly{}; bool enable_network{true}; - UartServer::Config uart; - FlashmemConfig flash; + UartServer::Config uart{}; + FlashmemConfig flash{}; #ifndef DISABLE_NETWORK - struct lwip_param lwip; + struct lwip_param lwip { + }; #endif }; static Config config{}; int uart_num{-1}; option_tag_t opt; - const char* arg; + const char* arg = nullptr; while((opt = get_option(argc, argv, arg)) != opt_none) { switch(opt) { case opt_help: @@ -244,12 +246,15 @@ int main(int argc, char* argv[]) } } + m_setPuts(&host_nputs); + host_debug_i("\nWelcome to the Sming Host emulator\n\n"); auto i = get_first_non_option(); commandLine.parse(argc - i, &argv[i]); if(!host_flashmem_init(config.flash)) { + host_debug_e("Flash init failed\n"); return 1; } @@ -286,7 +291,7 @@ int main(int argc, char* argv[]) System.initialize(); - host_init(); + init(); while(!done) { int due = host_main_loop(); @@ -307,7 +312,7 @@ int main(int argc, char* argv[]) pause(config.exitpause); // Avoid issues with debug statements whilst running exit handlers - m_setPuts(nullptr); + m_setPuts(&host_nputs); return exitCode; } diff --git a/Sming/Arch/Host/Components/hostlib/threads.cpp b/Sming/Arch/Host/Components/hostlib/threads.cpp index 83aa68ca08..ba8e8b1d81 100644 --- a/Sming/Arch/Host/Components/hostlib/threads.cpp +++ b/Sming/Arch/Host/Components/hostlib/threads.cpp @@ -20,8 +20,9 @@ #include "threads.h" #include #include -#include +#include #include +#include unsigned CThread::interrupt_mask; @@ -44,10 +45,13 @@ HANDLE host_thread_semaphore; CSemaphore host_thread_semaphore; volatile bool mainThreadSignalled; -timer_t signalTimer; int pauseSignal; int resumeSignal; +#ifndef __APPLE__ +timer_t signalTimer; +#endif + void signal_handler(int sig) { if(sig == pauseSignal) { @@ -61,6 +65,11 @@ void signal_handler(int sig) * - timer_settime() as for alarm() but with smaller interval * */ +#ifdef __APPLE__ + while(mainThreadSignalled) { + sched_yield(); + } +#else struct timespec ts = {0, long(0.1e9)}; struct itimerspec its = {ts, ts}; timer_settime(signalTimer, 0, &its, nullptr); @@ -69,6 +78,7 @@ void signal_handler(int sig) } its = {}; timer_settime(signalTimer, 0, &its, nullptr); +#endif } else if(sig == resumeSignal) { mainThreadSignalled = false; } else if(sig == SIGALRM) { @@ -79,8 +89,7 @@ void signal_handler(int sig) #endif -bool isMainThread() __attribute__((unused)); -bool isMainThread() +[[maybe_unused]] bool isMainThread() { return pthread_equal(pthread_self(), mainThread); } @@ -136,16 +145,27 @@ void CMutex::unlock() bool CSemaphore::timedwait(unsigned us) { - struct timespec ts; +#ifdef __APPLE__ + dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, us * 1000); + if(dispatch_semaphore_wait(m_sem, time) == 0) { + return true; + } + errno = ETIMEDOUT; + return false; +#else + struct timespec ts { + }; clock_gettime(CLOCK_REALTIME, &ts); uint64_t ns = ts.tv_nsec + uint64_t(us) * 1000; ts.tv_sec += ns / 1000000000; ts.tv_nsec = ns % 1000000000; - return timedwait(&ts); + return sem_timedwait(&m_sem, &ts) == 0; +#endif } -void CThread::startup(unsigned cpulimit) +void CThread::startup([[maybe_unused]] unsigned cpulimit) { +#ifndef __APPLE__ if(cpulimit != 0) { cpu_set_t set; CPU_ZERO(&set); @@ -158,12 +178,19 @@ void CThread::startup(unsigned cpulimit) host_debug_e("ERROR! Failed to set CPU affinity"); } } +#endif mainThread = pthread_self(); interrupt = new CBasicMutex; #ifdef __WIN32 host_thread_semaphore = CreateSemaphore(nullptr, 0, 1024, nullptr); +#elif defined(__APPLE__) + pauseSignal = SIGUSR1; + resumeSignal = SIGUSR2; + signal(pauseSignal, signal_handler); + signal(resumeSignal, signal_handler); + signal(SIGALRM, signal_handler); #else pauseSignal = SIGRTMIN + 0; resumeSignal = SIGRTMIN + 1; diff --git a/Sming/Arch/Host/Components/hostlib/threads.h b/Sming/Arch/Host/Components/hostlib/threads.h index b97e708f65..82a651568c 100644 --- a/Sming/Arch/Host/Components/hostlib/threads.h +++ b/Sming/Arch/Host/Components/hostlib/threads.h @@ -22,7 +22,11 @@ #include "include/hostlib/hostlib.h" #include #include +#ifdef __APPLE__ +#include +#else #include +#endif #include #if defined(DEBUG_VERBOSE_LEVEL) && (DEBUG_VERBOSE_LEVEL == 3) @@ -39,6 +43,14 @@ class CBasicMutex { public: + CBasicMutex() + { + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&m_priv, &attr); + } + ~CBasicMutex() { pthread_mutex_destroy(&m_priv); @@ -69,7 +81,7 @@ class CBasicMutex * This behaviour allows threads to lock the mutex multiple times whilst * blocking other threads. Avoids risk of deadlocks and simplifies code. */ - pthread_mutex_t m_priv = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; + pthread_mutex_t m_priv; }; /** @@ -95,45 +107,55 @@ class CSemaphore public: CSemaphore() { +#ifdef __APPLE__ + m_sem = dispatch_semaphore_create(0); +#else sem_init(&m_sem, 0, 0); +#endif } ~CSemaphore() { +#ifndef __APPLE__ sem_destroy(&m_sem); +#endif } bool post() { +#ifdef __APPLE__ + return dispatch_semaphore_signal(m_sem) == 0; +#else return sem_post(&m_sem) == 0; +#endif } bool wait() { +#ifdef __APPLE__ + return dispatch_semaphore_wait(m_sem, DISPATCH_TIME_FOREVER) == 0; +#else return sem_wait(&m_sem) == 0; +#endif } bool trywait() { +#ifdef __APPLE__ + return dispatch_semaphore_wait(m_sem, DISPATCH_TIME_NOW) == 0; +#else return sem_trywait(&m_sem) == 0; - } - - bool timedwait(const struct timespec* abs_timeout) - { - return sem_timedwait(&m_sem, abs_timeout) == 0; +#endif } bool timedwait(unsigned us); - int value() const - { - int n{0}; - sem_getvalue(const_cast(&m_sem), &n); - return n; - } - private: - sem_t m_sem; +#ifdef __APPLE__ + dispatch_semaphore_t m_sem; +#else + sem_t m_sem{}; +#endif }; /** diff --git a/Sming/Arch/Host/Components/libc/README.rst b/Sming/Arch/Host/Components/libc/README.rst index 57bd3a21eb..7d28c40fb7 100644 --- a/Sming/Arch/Host/Components/libc/README.rst +++ b/Sming/Arch/Host/Components/libc/README.rst @@ -1,4 +1,4 @@ -libc -==== +Host libc +========= Contains implementations of any non-standard C library functions. diff --git a/Sming/Arch/Host/Components/libc/gmtime_r.c b/Sming/Arch/Host/Components/libc/gmtime_r.c new file mode 100644 index 0000000000..b9af8fc798 --- /dev/null +++ b/Sming/Arch/Host/Components/libc/gmtime_r.c @@ -0,0 +1,122 @@ +/* + * gmtime_r.c + * Original Author: Adapted from tzcode maintained by Arthur David Olson. + * Modifications: + * - Changed to mktm_r and added __tzcalc_limits - 04/10/02, Jeff Johnston + * - Fixed bug in mday computations - 08/12/04, Alex Mogilnikov + * - Fixed bug in __tzcalc_limits - 08/12/04, Alex Mogilnikov + * - Move code from _mktm_r() to gmtime_r() - 05/09/14, Freddie Chopin + * - Fixed bug in calculations for dates after year 2069 or before year 1901. Ideas for + * solution taken from musl's __secs_to_tm() - 07/12/2014, Freddie Chopin + * + * - Use faster algorithm from civil_from_days() by Howard Hinnant - 12/06/2014, + * Freddie Chopin + * + * Converts the calendar time pointed to by tim_p into a broken-down time + * expressed as local time. Returns a pointer to a structure containing the + * broken-down time. + */ + +#ifdef __WIN32 + +#include + +#define SECSPERMIN 60L +#define MINSPERHOUR 60L +#define HOURSPERDAY 24L +#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) +#define SECSPERDAY (SECSPERHOUR * HOURSPERDAY) +#define DAYSPERWEEK 7 +#define MONSPERYEAR 12 + +#define YEAR_BASE 1900 +#define EPOCH_YEAR 1970 +#define EPOCH_WDAY 4 +#define EPOCH_YEARS_SINCE_LEAP 2 +#define EPOCH_YEARS_SINCE_CENTURY 70 +#define EPOCH_YEARS_SINCE_LEAP_CENTURY 370 + +#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0) + +/* Move epoch from 01.01.1970 to 01.03.0000 (yes, Year 0) - this is the first + * day of a 400-year long "era", right after additional day of leap year. + * This adjustment is required only for date calculation, so instead of + * modifying time_t value (which would require 64-bit operations to work + * correctly) it's enough to adjust the calculated number of days since epoch. + */ +#define EPOCH_ADJUSTMENT_DAYS 719468L +/* year to which the adjustment was made */ +#define ADJUSTED_EPOCH_YEAR 0 +/* 1st March of year 0 is Wednesday */ +#define ADJUSTED_EPOCH_WDAY 3 +/* there are 97 leap years in 400-year periods. ((400 - 97) * 365 + 97 * 366) */ +#define DAYS_PER_ERA 146097L +/* there are 24 leap years in 100-year periods. ((100 - 24) * 365 + 24 * 366) */ +#define DAYS_PER_CENTURY 36524L +/* there is one leap year every 4 years */ +#define DAYS_PER_4_YEARS (3 * 365 + 366) +/* number of days in a non-leap year */ +#define DAYS_PER_YEAR 365 +/* number of days in January */ +#define DAYS_IN_JANUARY 31 +/* number of days in non-leap February */ +#define DAYS_IN_FEBRUARY 28 +/* number of years per era */ +#define YEARS_PER_ERA 400 + +struct tm * +gmtime_r (const time_t *__restrict tim_p, + struct tm *__restrict res) +{ + long days, rem; + const time_t lcltime = *tim_p; + int era, weekday, year; + unsigned erayear, yearday, month, day; + unsigned long eraday; + + days = lcltime / SECSPERDAY + EPOCH_ADJUSTMENT_DAYS; + rem = lcltime % SECSPERDAY; + if (rem < 0) + { + rem += SECSPERDAY; + --days; + } + + /* compute hour, min, and sec */ + res->tm_hour = (int) (rem / SECSPERHOUR); + rem %= SECSPERHOUR; + res->tm_min = (int) (rem / SECSPERMIN); + res->tm_sec = (int) (rem % SECSPERMIN); + + /* compute day of week */ + if ((weekday = ((ADJUSTED_EPOCH_WDAY + days) % DAYSPERWEEK)) < 0) + weekday += DAYSPERWEEK; + res->tm_wday = weekday; + + /* compute year, month, day & day of year */ + /* for description of this algorithm see + * http://howardhinnant.github.io/date_algorithms.html#civil_from_days */ + era = (days >= 0 ? days : days - (DAYS_PER_ERA - 1)) / DAYS_PER_ERA; + eraday = days - era * DAYS_PER_ERA; /* [0, 146096] */ + erayear = (eraday - eraday / (DAYS_PER_4_YEARS - 1) + eraday / DAYS_PER_CENTURY - + eraday / (DAYS_PER_ERA - 1)) / 365; /* [0, 399] */ + yearday = eraday - (DAYS_PER_YEAR * erayear + erayear / 4 - erayear / 100); /* [0, 365] */ + month = (5 * yearday + 2) / 153; /* [0, 11] */ + day = yearday - (153 * month + 2) / 5 + 1; /* [1, 31] */ + month += month < 10 ? 2 : -10; + year = ADJUSTED_EPOCH_YEAR + erayear + era * YEARS_PER_ERA + (month <= 1); + + res->tm_yday = yearday >= DAYS_PER_YEAR - DAYS_IN_JANUARY - DAYS_IN_FEBRUARY ? + yearday - (DAYS_PER_YEAR - DAYS_IN_JANUARY - DAYS_IN_FEBRUARY) : + yearday + DAYS_IN_JANUARY + DAYS_IN_FEBRUARY + isleap(erayear); + res->tm_year = year - YEAR_BASE; + res->tm_mon = month; + res->tm_mday = day; + + res->tm_isdst = 0; + + return (res); +} + +#endif // __WIN32 + diff --git a/Sming/Arch/Host/Components/libc/include/sys/pgmspace.h b/Sming/Arch/Host/Components/libc/include/sys/pgmspace.h index e97595d139..8c88c63ca9 100644 --- a/Sming/Arch/Host/Components/libc/include/sys/pgmspace.h +++ b/Sming/Arch/Host/Components/libc/include/sys/pgmspace.h @@ -25,9 +25,9 @@ bool isFlashPtr(const void* ptr); #define PGM_P const char* #define PGM_VOID_P const void* -#define pgm_read_byte(addr) (*(const unsigned char*)(addr)) -#define pgm_read_word(addr) (*(const unsigned short*)(addr)) -#define pgm_read_dword(addr) (*(const unsigned long*)(addr)) +#define pgm_read_byte(addr) (*(const uint8_t*)(addr)) +#define pgm_read_word(addr) (*(const uint16_t*)(addr)) +#define pgm_read_dword(addr) (*(const uint32_t*)(addr)) #define pgm_read_float(addr) (*(const float*)(addr)) #define pgm_read_byte_near(addr) pgm_read_byte(addr) @@ -39,17 +39,17 @@ bool isFlashPtr(const void* ptr); #define pgm_read_dword_far(addr) pgm_read_dword(addr) #define pgm_read_float_far(addr) pgm_read_float(addr) -#define memcpy_P(dest, src, num) memcpy(dest, src, num) -#define memcmp_P(a1, b1, len) memcmp(a1, b1, len) -#define strlen_P(a) strlen(a) -#define strcpy_P(dest, src) strcpy(dest, src) -#define strncpy_P(dest, src, size) strncpy(dest, src, size) -#define strcmp_P(a, b) strcmp(a, b) +#define memcpy_P(dest, src_P, num) memcpy(dest, src_P, num) +#define memcmp_P(buf1, buf2_P, len) memcmp(buf1, buf2_P, len) +#define strlen_P(str_P) strlen(str_P) +#define strcpy_P(dest, src_P) strcpy(dest, src_P) +#define strncpy_P(dest, src_P, size) strncpy(dest, src_P, size) +#define strcmp_P(str1, str2_P) strcmp(str1, str2_P) #define strncmp_P(str1, str2_P, size) strncmp(str1, str2_P, size) -#define strcasecmp_P(a, b) strcasecmp(a, b) -#define strcat_P(dest, src) strcat(dest, src) -#define strstr_P(a, b) strstr(a, b) -#define sprintf_P(s, f, ...) m_snprintf(s, 1024, f, ##__VA_ARGS__) +#define strcasecmp_P(str1, str2_P) strcasecmp(str1, str2_P) +#define strcat_P(dest, src_P) strcat(dest, src_P) +#define strstr_P(haystack, needle_P) strstr(haystack, needle_P) +#define sprintf_P(str, format_P, ...) m_snprintf(str, 1024, format_P, ##__VA_ARGS__) #ifdef __cplusplus } diff --git a/Sming/Arch/Host/Components/libc/include/time.h b/Sming/Arch/Host/Components/libc/include/time.h new file mode 100644 index 0000000000..4b54658620 --- /dev/null +++ b/Sming/Arch/Host/Components/libc/include/time.h @@ -0,0 +1,17 @@ +#pragma once + +#include_next + +#ifdef __WIN32 + +#ifdef __cplusplus +extern "C" { +#endif + +struct tm* gmtime_r(const time_t*, struct tm*); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Sming/Arch/Host/Components/sming-arch/component.mk b/Sming/Arch/Host/Components/sming-arch/component.mk index af6aa02b8a..cb3e2503d3 100644 --- a/Sming/Arch/Host/Components/sming-arch/component.mk +++ b/Sming/Arch/Host/Components/sming-arch/component.mk @@ -10,10 +10,6 @@ # EXCLUDE_LIBRARIES := Adafruit_ILI9341 Adafruit_NeoPixel Adafruit_PCD8544 Adafruit_SSD1306 \ # ArduCAM CapacitiveSensor IR MCP23S17 RF24 SDCard TFT_ILI9163C WS2812 -# Eventually this will go, but for now we use some Esp8266 code -ESP8266_COMPONENTS := $(SMING_HOME)/Arch/Esp8266/Components -export ESP8266_COMPONENTS - COMPONENT_SRCDIRS := \ $(ARCH_CORE) $(call ListAllSubDirs,$(ARCH_CORE)) \ $(ARCH_BASE)/Platform \ diff --git a/Sming/Arch/Host/Components/spi_flash/README.rst b/Sming/Arch/Host/Components/spi_flash/README.rst index 4a427923ed..83047814a1 100644 --- a/Sming/Arch/Host/Components/spi_flash/README.rst +++ b/Sming/Arch/Host/Components/spi_flash/README.rst @@ -1,5 +1,5 @@ -SPI Flash -========= +SPI Flash Emulation +=================== This Component emulates an embedded flash memory device using a backing file. It includes additional checks on addresses, sizes and alignments to detect common issues which can be more difficult to find diff --git a/Sming/Arch/Host/Components/spi_flash/component.mk b/Sming/Arch/Host/Components/spi_flash/component.mk index 0aa8fcafcc..8d5b1ee2f6 100644 --- a/Sming/Arch/Host/Components/spi_flash/component.mk +++ b/Sming/Arch/Host/Components/spi_flash/component.mk @@ -1,3 +1 @@ -COMPONENT_INCDIRS += $(ESP8266_COMPONENTS)/spi_flash/include - COMPONENT_DEPENDS := IFS diff --git a/Sming/Arch/Host/Components/spi_flash/flashmem.cpp b/Sming/Arch/Host/Components/spi_flash/flashmem.cpp index 18a01c2b6e..123b77b979 100644 --- a/Sming/Arch/Host/Components/spi_flash/flashmem.cpp +++ b/Sming/Arch/Host/Components/spi_flash/flashmem.cpp @@ -19,7 +19,7 @@ #include #include "flashmem.h" -#include +#include #include #include #include @@ -32,16 +32,17 @@ char flashFileName[256]; const char defaultFlashFileName[]{"flash.bin"}; // Top bit of flash address is set to indicate it's actually program memory -constexpr uint32_t FLASHMEM_REAL_BIT{0x80000000U}; -constexpr uint32_t FLASHMEM_REAL_MASK{~FLASHMEM_REAL_BIT}; +constexpr flash_addr_t FLASHMEM_REAL_BIT{1UL << (sizeof(flash_addr_t) * 8 - 1)}; +constexpr flash_addr_t FLASHMEM_REAL_MASK{~FLASHMEM_REAL_BIT}; } // namespace -#define CHECK_ALIGNMENT(_x) assert(((uint32_t)(_x)&0x00000003) == 0) +#define CHECK_ALIGNMENT(_x) assert((uintptr_t(_x) & 0x00000003) == 0) #define CHECK_RANGE(_addr, _size) \ if((_addr) + (_size) > flashFileSize) { \ host_debug_e("addr = 0x%08x, size = 0x%08x", _addr, _size); \ + assert(false); \ return false; \ } @@ -136,27 +137,22 @@ SPIFlashInfo flashmem_get_info() return info; } -uint8_t flashmem_get_size_type() +SPIFlashSize flashmem_get_size_type() { return flashmem_get_info().size; } -uint32 spi_flash_get_id(void) +uint32_t spi_flash_get_id(void) { return 0xFA1E0008; } -uint32_t flashmem_get_size_bytes() +flash_addr_t flashmem_get_size_bytes() { return flashFileSize; } -uint16_t flashmem_get_size_sectors() -{ - return flashFileSize / SPI_FLASH_SEC_SIZE; -} - -uint32_t flashmem_write_internal(const void* from, uint32_t toaddr, uint32_t size) +uint32_t flashmem_write_internal(const void* from, uintptr_t toaddr, uint32_t size) { CHECK_ALIGNMENT(from); CHECK_ALIGNMENT(toaddr); @@ -165,7 +161,7 @@ uint32_t flashmem_write_internal(const void* from, uint32_t toaddr, uint32_t siz return flashmem_write(from, toaddr, size); } -static bool readRealMem(void* buffer, uint32_t addr, uint32_t count) +static bool readRealMem(void* buffer, flash_addr_t addr, uint32_t count) { if((addr & FLASHMEM_REAL_BIT) == 0) { return false; @@ -176,7 +172,7 @@ static bool readRealMem(void* buffer, uint32_t addr, uint32_t count) return true; } -uint32_t flashmem_read_internal(void* to, uint32_t fromaddr, uint32_t size) +uint32_t flashmem_read_internal(void* to, uintptr_t fromaddr, uint32_t size) { if(readRealMem(to, fromaddr, size)) { return size; @@ -190,14 +186,14 @@ uint32_t flashmem_read_internal(void* to, uint32_t fromaddr, uint32_t size) return (res < 0) ? 0 : res; } -uint32_t flashmem_write(const void* from, uint32_t toaddr, uint32_t size) +uint32_t flashmem_write(const void* from, flash_addr_t toaddr, uint32_t size) { CHECK_RANGE(toaddr, size); int res = writeFlashFile(toaddr, from, size); return (res < 0) ? 0 : res; } -uint32_t flashmem_read(void* to, uint32_t fromaddr, uint32_t size) +uint32_t flashmem_read(void* to, flash_addr_t fromaddr, uint32_t size) { if(readRealMem(to, fromaddr, size)) { return size; @@ -208,11 +204,6 @@ uint32_t flashmem_read(void* to, uint32_t fromaddr, uint32_t size) return (res < 0) ? 0 : res; } -uint32_t flashmem_get_sector_of_address(uint32_t addr) -{ - return addr / INTERNAL_FLASH_SECTOR_SIZE; -} - bool flashmem_erase_sector(uint32_t sector_id) { uint32_t addr = sector_id * INTERNAL_FLASH_SECTOR_SIZE; @@ -222,7 +213,8 @@ bool flashmem_erase_sector(uint32_t sector_id) return writeFlashFile(addr, tmp, sizeof(tmp)) == sizeof(tmp); } -uint32_t flashmem_get_address(const void* memptr) +flash_addr_t flashmem_get_address(const void* memptr) { - return reinterpret_cast(memptr) | FLASHMEM_REAL_BIT; + assert(uintptr_t(memptr) <= FLASHMEM_REAL_MASK); + return reinterpret_cast(memptr) | FLASHMEM_REAL_BIT; } diff --git a/Sming/Arch/Host/Components/spi_flash/include/esp_spi_flash.h b/Sming/Arch/Host/Components/spi_flash/include/esp_spi_flash.h index 61a55af1b9..004630efa9 100644 --- a/Sming/Arch/Host/Components/spi_flash/include/esp_spi_flash.h +++ b/Sming/Arch/Host/Components/spi_flash/include/esp_spi_flash.h @@ -1,15 +1,67 @@ -#define SPI_FLASH_SEC_SIZE 4096 +/**** + * Sming Framework Project - Open Source framework for high efficiency native ESP8266 development. + * Created 2015 by Skurydin Alexey + * http://github.com/SmingHub/Sming + * All files of the Sming Core are provided under the LGPL v3 license. + * + ****/ + +#pragma once + +#include #ifdef __cplusplus extern "C" { #endif -#include +#define INTERNAL_FLASH_SECTOR_SIZE 4096 +#define INTERNAL_FLASH_START_ADDRESS 0x40200000 + +typedef enum { + MODE_QIO = 0, + MODE_QOUT = 1, + MODE_DIO = 2, + MODE_DOUT = 15, + MODE_SLOW_READ = 0xFE, ///< Not supported + MODE_FAST_READ = 0xFF, ///< Not supported +} SPIFlashMode; + +typedef enum { + SPEED_40MHZ = 0, + SPEED_26MHZ = 1, + SPEED_20MHZ = 2, + SPEED_80MHZ = 15, +} SPIFlashSpeed; + +typedef enum { + SIZE_4MBIT = 0, + SIZE_2MBIT = 1, + SIZE_8MBIT = 2, + SIZE_16MBIT = 3, + SIZE_32MBIT = 4, + SIZE_1MBIT = 0xFF, ///< Not supported +} SPIFlashSize; + +/** @brief write to flash memory + * @param from Buffer to read data from - MUST be word-aligned + * @param toaddr Flash address (offset) to write to - MUST be word-aligned + * @param size Number of bytes to write - MUST be word-aligned + * @retval uint32_t Number of bytes actually written + * @note All parameters MUST be aligned to 4-byte word boundaries, **including** the RAM pointer + */ +uint32_t flashmem_write_internal(const void* from, uintptr_t toaddr, uint32_t size); -uint32_t spi_flash_get_id(void); +/** @brief Read from flash memory + * @param to Buffer to store data - MUST be word-aligned + * @param fromaddr Flash address (offset) to read from - MUST be word-aligned + * @param size Number of bytes to read - MUST be word-aligned + * @retval uint32_t Number of bytes actually read + * @note All parameters MUST be aligned to 4-byte word boundaries, **including** the RAM pointer + */ +uint32_t flashmem_read_internal(void* to, uintptr_t fromaddr, uint32_t size); #ifdef __cplusplus } #endif -#include_next +#include diff --git a/Sming/Arch/Host/Components/spi_flash/include/iram_precache.h b/Sming/Arch/Host/Components/spi_flash/include/iram_precache.h index a0dd9e4d15..01d6eaaeb7 100644 --- a/Sming/Arch/Host/Components/spi_flash/include/iram_precache.h +++ b/Sming/Arch/Host/Components/spi_flash/include/iram_precache.h @@ -10,6 +10,8 @@ extern "C" { static inline void iram_precache(void* addr, uint32_t bytes) { + (void)addr; + (void)bytes; } #ifdef __cplusplus diff --git a/Sming/Arch/Host/Components/vflash/README.rst b/Sming/Arch/Host/Components/vflash/README.rst index 5fa2f06fa0..4dcdd4a8ae 100644 --- a/Sming/Arch/Host/Components/vflash/README.rst +++ b/Sming/Arch/Host/Components/vflash/README.rst @@ -6,8 +6,8 @@ Flash memory access is emulated using :component-host:`spi_flash`. This Component implements make targets to operate on the flash backing file in a similar way to flashing a real device. -Build Variables ---------------- +Configuration Variables +----------------------- The following options are interpreted and used to provide command-line parameters to the emulator executable: diff --git a/Sming/Arch/Host/Core/Digital.cpp b/Sming/Arch/Host/Core/Digital.cpp index cb1f221e16..c266677a70 100644 --- a/Sming/Arch/Host/Core/Digital.cpp +++ b/Sming/Arch/Host/Core/Digital.cpp @@ -13,7 +13,7 @@ // Wemos D1 mini has pin 16 #define PIN_MAX 16 -static uint8 pinModes[PIN_MAX + 1]; +static uint8_t pinModes[PIN_MAX + 1]; DigitalHooks defaultHooks; static DigitalHooks* activeHooks = &defaultHooks; diff --git a/Sming/Arch/Host/Core/HardwarePWM.cpp b/Sming/Arch/Host/Core/HardwarePWM.cpp index d2eaf908f7..cf5d2de430 100644 --- a/Sming/Arch/Host/Core/HardwarePWM.cpp +++ b/Sming/Arch/Host/Core/HardwarePWM.cpp @@ -25,13 +25,11 @@ #include -HardwarePWM::HardwarePWM(uint8_t* pins, uint8_t no_of_pins) : channel_count(no_of_pins), maxduty(0) +HardwarePWM::HardwarePWM(uint8_t* pins, uint8_t no_of_pins) : channel_count(no_of_pins) { } -HardwarePWM::~HardwarePWM() -{ -} +HardwarePWM::~HardwarePWM() = default; uint8_t HardwarePWM::getChannel(uint8_t pin) { diff --git a/Sming/Arch/Host/Platform/RTC.cpp b/Sming/Arch/Host/Platform/RTC.cpp index 6d93b702be..a871b44bf3 100644 --- a/Sming/Arch/Host/Platform/RTC.cpp +++ b/Sming/Arch/Host/Platform/RTC.cpp @@ -19,13 +19,12 @@ namespace int timeDiff; // Difference between set time and system time } -RtcClass::RtcClass() -{ -} +RtcClass::RtcClass() = default; uint64_t RtcClass::getRtcNanoseconds() { - struct timeval tv; + struct timeval tv { + }; gettimeofday(&tv, nullptr); uint64_t usecs = (tv.tv_sec * 1000000ULL) + (uint32_t)tv.tv_usec; return usecs * 1000; @@ -33,14 +32,15 @@ uint64_t RtcClass::getRtcNanoseconds() uint32_t RtcClass::getRtcSeconds() { - struct timeval tv; + struct timeval tv { + }; gettimeofday(&tv, nullptr); return tv.tv_sec + timeDiff; } bool RtcClass::setRtcNanoseconds(uint64_t nanoseconds) { - return false; + return setRtcSeconds(nanoseconds / 1'000'000'000ULL); } bool RtcClass::setRtcSeconds(uint32_t seconds) diff --git a/Sming/Arch/Host/README.rst b/Sming/Arch/Host/README.rst index d4fc206122..dd47bcb677 100644 --- a/Sming/Arch/Host/README.rst +++ b/Sming/Arch/Host/README.rst @@ -3,48 +3,210 @@ Sming Host Emulator .. highlight:: bash +Sming allows most libraries and sample applications to be compiled on a Linux/MacOs/Windows +development system and be tested before uploading them to the microcontroller. + +If you want to try it we have an +`interactive tutorial `__ +that can be run directly from your browser. + +For installation details see :doc:`/getting-started/index`. + Summary ------- -Allows Sming applications to be built as an executable to run on the -development host (Windows or Linux). - This is a source-level emulator for developing and testing new framework code prior to flashing a real device. This is not a machine emulator; if you need something operating at a lower level take a look at `QEMU `__. +The design goals for Host builds are: + +- Simplify development of complex applications +- Enable use of advanced testing and code quality tools (valgrind, code sanitizers) +- Support CI testing by actually executing code, not just building it + + Requirements ------------ -``CMake`` is required to build LWIP +``CMake`` and ``Ninja`` are required to build some libraries (e.g. lwip). + +Tested compilers: + +- GCC version 8 or later +- Clang version 15 or later +- Apple-clang version 14 or later -Ensure you are using relatively recent compilers, with 32-bit libraries available. +.. _linux_requirements: -For Linux, you may require the ``gcc-multilib`` and ``g++-multilib`` -packages to build 32-bit executables on a 64-bit OS. +Linux +~~~~~ + +Host executables can be built in 32-bit emulation mode, which is the default for Linux. +This requires installation of 32-bit runtime libraries. +For debian/ubuntu:: + + sudo apt install g++-multilib + +For Fedora:: + + sudo dnf install glibc-devel.i686 libstdc++.i686 + +Alternatively set :envvar:`BUILD64` to 1 to build in native 64-bit mode. + +MacOS +~~~~~ + +MacOS comes pre-installed with ``Apple Clang`` as the standard toolchain. +This should be sufficient to build Sming in Host mode. +Note that MacOS does not support 32-bit applications so the emulator will build in 64-bit mode. + +Windows +~~~~~~~ For Windows, make sure your ``MinGW`` distro is up to date. See :doc:`/getting-started/windows/index` for further details. + Building -------- -Build the framework and application as usual, specifying :envvar:`SMING_ARCH` =Host. For example:: +Environment variables +~~~~~~~~~~~~~~~~~~~~~ - cd $SMING_HOME/../samples/Basic_Serial - make SMING_ARCH=Host +:envvar:`SMING_ARCH` must be set to use ``Host`` as the desired architecture:: -This builds the application as an executable in, for example, -``out/Host/firmware/app.exe``. Various command-line options are -supported, use ``--help`` for details. + export SMING_ARCH=Host + +Debug Build +~~~~~~~~~~~ + +If you plan to use a debugger make sure to set :envvar:`ENABLE_GDB` and (optionally) +:envvar:`ENABLE_LWIPDEBUG` before compiling the code:: + + export ENABLE_GDB=1 + export ENABLE_LWIPDEBUG=1 # set prompt string - EOL -> set end of line character - welcome -message -> set the welcome message - -System Commands -=============== - -The base ``CommandHandler`` has the following sysytem commands -implemented: - ``help``, Displays all available commands - ``status``, -Displays System Information - ``echo``, Displays command entered - -``debugon``, Set Serial debug on - ``debugoff``, Set Serial debug off - -``command``, Usage verbose/silent/prompt for command options - -Application options -=================== - -Applications (and Sming Core functionality) can add commands to the -``CommandProcesor`` using a construct like - -.. code-block:: c++ - - registerCommand(CommandDelegate( - "status", - "Displays System Information", - "system", - commandFunctionDelegate(&CommandHandler::procesStatusCommand, this) - )); - -The added command will then be available over every opened command -channel. - -Example usage -============= - -The capabilities of ``CommandHandler`` are shown in the example -``CommandProcessing_Debug``. - -The example will create an application which shows ``CommandProcessing`` -for Telnet, Websocket and Serial. - -- to test Telnet, open telnet client and connect on port 23 to the ESP - ip -- to test the Websocket, open a web browser with the ESP -- to test Serial use your “Serial program” and make sure “local echo” - is activated - -For all implementations type “help” to show the available Commands - -The possibilities of extending commands with the application are shown -in: - the class ``ExampleCommand`` - the functions -``startExampleApplicationCommand()`` and -``processApplicationCommands()`` diff --git a/docs/source/information/debugging.rst b/docs/source/information/debugging.rst deleted file mode 100644 index aa1b8ffdda..0000000000 --- a/docs/source/information/debugging.rst +++ /dev/null @@ -1,21 +0,0 @@ -Debugging -========= - -Debugging is a powerful technique allowing you to interactively run your -code and be able to see much more information about the things that went -wrong. - -Architectures -~~~~~~~~~~~~~ - -Debugging on the supported architectures requires the installation and initial setup of different debugging tools. -The links below will give you more information and step-by-step instructions. - -.. toctree:: - :titlesonly: - :maxdepth: 1 - - /arch/host/debugging/index - /arch/esp8266/debugging/index - /arch/esp32/debugging/index - /arch/rp2040/debugging/index diff --git a/docs/source/information/develop/ci.rst b/docs/source/information/develop/ci.rst index 74581accd6..1a0b1350f6 100644 --- a/docs/source/information/develop/ci.rst +++ b/docs/source/information/develop/ci.rst @@ -10,7 +10,8 @@ framework with all samples (both in the framework any any associated libraries). This is done using the integration testing framework using linux and Windows build environments. In addition, a number of integration tests are run using Host builds which verify the logic of a large -proportion of the code. +proportion of the code. This includes the main ``HostTests`` application plus all ``test`` applications +in every Component/library. Testing low-level operation requires real hardware and this must be done manually, but in general libraries and samples can be largely tested using Host builds and carefully constructed tests. @@ -25,271 +26,224 @@ Github Actions We use Github Actions to manage all test builds. This service is free of charge for open-source projects. -.. note:: - - Appveyor has been removed in favour of GitHub Actions. - - We used to use `Travis `__ but this is no longer free of charge. - Sming performs the build and test logic is handled using scripts, which are intended to be easily portable to other CI services if necessary. Mostly batch scripts (.cmd) are used for Windows, and bash scripts (.sh) for GNU/Linux but where practical powershell core is used as this runs on either. -.. note:: +These are the main Sming workflows in ``.github/workflows``: - Sming doesn't perform CI builds for MacOS. +Cache clean + Dispatch workflow as convenient way to clean action cache. Cleaning levels are: + - pull-requests + Any items created by pull requests, excludes anything in develop branch. + Normally pull requests will make use of caches present in the develop branch, but if there isn't one it will create its own. This becomes redundant when merged to develop. -Library CI support ------------------- + Such caches should be expired automatically, but this option can be used to remove them. -Sming libraries may be separately built and tested whether or not they are included as part of -the Sming repository (or a fork). + - ccache + All ccache items. Use if pull requests are taking too long to build. -There are two mechanisms available. - -GitHub Actions -~~~~~~~~~~~~~~ - -The ``library.yml`` re-useable workflow is provided, which takes care of these tasks: - -- Checking in the library to test -- Checking in the Sming framework -- Installing build tools -- Builds all applications within the library's ``samples`` directory, for all supported architectures -- If a test application is provided then that should be located in a ``test`` directory. - This is built for all architectures, and also executed for Host. + - idf-tools + All IDF tool. Use before merging to develop if IDF toolchains have been updated. -Builds are handled using :source:`Tools/ci/library/Makefile`. + - ccache+idf + All ccache and IDF tool caches. -See also https://docs.github.com/en/actions/using-workflows/reusing-workflows. + Note that cleaning can always be done locally using ``gh``:: -To use this in a project, add a suitable workflow to the ``.github/workflows`` directory. -Templates are provided in the ``.github/workflows/library`` directory. + gh cache list # For fork + gh cache list -R SmingHub/Sming + gh cache delete --all -R SmingHub/Sming -Here is the basic ``push`` scenario: + etc. -.. code-block:: yaml - name: CI Push - on: [push] - jobs: - build: - uses: SmingHub/Sming/.github/workflows/library.yml@develop - # Inputs are all optional, defaults are shown - with: - # Repository to fetch Sming from - sming_repo: 'https://github.com/SmingHub/Sming' - # Sming branch to run against - sming_branch: 'develop' - # Library alias - alias: '' - -The ``sming_repo`` and ``sming_branch`` inputs are provided if your library requires modifications -to Sming which are not (yet) in the main repository. - -The ``alias`` input is required where the library repository name does not correspond with -the working title. -For example, the ``jerryscript`` library is in a repository called ``Sming-jerryscript``, -so must be checked out using a different name. -If Sming contains a library (or Component) with the same name then it will be overridden, -with a warning ``Multiple matches found for Component 'jerryscript'`` in the build log. - -The ``ci-dispatch.yml`` example demonstrates manual triggering, which allows these inputs to be easily changed. -See https://docs.github.com/en/actions/managing-workflow-runs/manually-running-a-workflow. - -Note that the workflow must be available in the library's default branch, or it will -not appear in the github web page. +CodeQL + Performs code quality analysis when develop branch is updated. +Continuous Integration (CI) + Tests for all architectures except esp32. Run for every pull request and merge to develop. -Appveyor -~~~~~~~~ +Continuous Integration (CI) for Esp32 + Tests for esp32 architecture. Requires a separate workflow as matrix becomes too complex otherwise. -Appveyor may be configured to test a Sming library separately. Steps to enable: +Continuous Integration (CI) for Library + Used indirectly by library workflows for testing. See workflows/library. -Add project to appveyor account - ``Projects`` -> ``New Project`` and select from list +Coverity Scan + Code quality analyser. Does instrumented build then uploads database to coverity servers for analysis. -Set ``Custom Configuration`` - to https://raw.githubusercontent.com/SmingHub/Sming/develop/Tools/ci/library/appveyor.txt. +Release + Run manually during release phase only. -Set ``Project URL slug`` - If the library under test already exists in the Sming framework then the test directory - MUST have the same name to ensure it gets picked up. +Spelling Check + Run for all pull requests and merge to develop. - For example, testing the ``Sming-jerryscript`` library requires this value to be set to ``jerryscript`` - to match the Sming library name. - Build logs should then report a warning ``Multiple matches found for Component 'jerryscript'. -Set sming fork/branch - By default builds use the main Sming ``develop`` branch. - If testing a library which requires changes to the framework, you'll need to use a fork - and add ``SMING_REPO`` and ``SMING_BRANCH`` environment variables to the project settings. +Esp32 IDF and tools cleaning +---------------------------- - Note that environment variables set here will override any values set in appveyor.txt. +Because the IDF and associated tools are large and relatively time-consuming to install, these are cached. +There's so much bloat that it doesn't take much to fill the 10GB github cache allocation. -The provided default :source:`makefile ` -builds all applications within the library's ``samples`` directory. -If a test application is provided then that should be located in a ``test`` directory. -This is built for all architectures, and also executed for Host. +So after installing the tools - before it gets cached - the ``clean-tools.py`` script gets run. +This tool contains a list of filters (regular expressions) which match various paths. +Candidates for removal were identified by inspection using the Gnome disk usage analyzer. +Some other stuff (like test code and examples) are fairly safe candidates to remove as well. +To evaluate how much would be removed run this command (it's safe):: -Build on your own 'cloud' -------------------------- + python clean-tools.py scan -Resources are limited to one concurrent build job per appveyor account. -Each build gets two virtual CPUs but they're not particular fast. -Network connectivity is, on the other hand, excellent! +To perform 'dry-run' of a clean operation, without actually deleteing anything:: -One very useful feature that appveyor provides is `Bring Your Own Cloud or Computer `__. -This allows the actual builds to be run on other hardware. + python clean-tools.py clean -Builds can have up to 5 concurrent jobs and as many CPUs as are available. -In addition, build images can be pre-installed with toolchains. -This can reduce total run times from 5+ hours to around 30 minutes. +To actually delete stuff requires a confirmation flag:: + python clean-tools.py clean --delete -Configuration -~~~~~~~~~~~~~ +Note that some unused submodules are cleaned, but by default the IDF pulls them back in again! +To prevent this behaviour, set `IDF_SKIP_CHECK_SUBMODULES=1`. -Full support requires a Windows server with Hyper-V, WSL2 and `Docker `__ installed. -Hyper-V is built into Windows 10/11 professional edition. -WSL2 should be available on all Windows versions. -Linux/MacOS are supported but only for GNU/Linux images. +CI logs +------- -Note that whilst Docker supports both Windows and Linux images, both cannot be used at the same time: -it is necessary to manually switch between Linux/Windows containers. -However, testing shows much better performance using Hyper-V for Windows builds. +Analysing CI logs is important for several reasons: -1. Add Docker build cloud for Linux builds: +Identifying sudden jumps in memory usage between builds + This can indicate a potential problem with SDK updates or the build system - - Appveyor -> BYOC -> Add Cloud +Checking warnings + - Compiler warnings are a very important indicator of potential problems in code. + - CI runs are built in STRICT mode so despite best efforts there can be many remaining messages. + - The same warning in a particular source file can occur multiple times in a run and across + multiple runs - - Cloud Provider: Docker +Logs can be downloaded via the web browser in 'raw' format, but getting these takes manual +effort and has to be repeated for each build: currently there are 42 builds across two runs. - - Operating system: Windows +Fortunately, github actions provides a CLI application to do this. +The log files related to a run and therefore only two are required (the main build, and esp32). - - Base Image: ``Ubuntu 20.04 Minimal`` - - Shell commands:: +Setup +~~~~~ - git clone https://github.com/SmingHub/Sming --branch develop --depth 1 /tmp/sming - pwsh /tmp/sming/Tools/Docker/appveyor/setup.ps1 +The github CLI client must be installed and authenticated with the Sming repo (or fork). - - Image name: ``linux`` +See https://docs.github.com/en/github-cli/github-cli/quickstart. - Execute commands as indicated in the resulting screen. - Wait for the image to be built. +Usage +~~~~~ - The final stage updates the cloud information in your appveyor account. - Customise as follows: +Fetch and scan the most recent build:: - - Name - Change this so it contains only letters, numbers and dash (-). - Default names contain a space, e.g. ``COMPUTER Docker`` so change to ``COMPUTER-Docker`` + python scanlog.py last-build.txt --fetch - - Custom Docker command arguments - Customise CPU resources, RAM usage, etc. For example:: +This will download all CI runs from the most recent workflow into ``last-build.txt``, then parse it. +If the file already exists, downloading will be skipped. +Output is to console and can be redirected to a file if required. - --cpus=8 +To compare with another previously fetched set of logs:: - See https://docs.docker.com/engine/reference/commandline/run/. + python scanlog.py last-build.txt -c previous-build.txt - - Failover strategy - Default values will fail a job if no worker is available to service it. - The following settings are suggested:: +To fetch a specific build:: - Job start timeout: 60 - Provisioning attempts: 100 + python scanlog.py custom-fixes.txt --fetch --branch feature/custom-fixes +To explicitly specify the repository to fetch from:: -2. Add Hyper-V build cloud for Windows builds: + python scanlog.py custom-fixes.txt --fetch --branch feature/custom-fixes --repo SmingHub/Sming -Same as (1) above except: +To list all source locations with warnings:: -- Cloud Provider: Hyper-V -- Base Image: ``Windows Server Core 2019 Minimal`` -- Image name: ``windows`` + python scanlog.py last-build.txt -w -m -When complete, fix the build cloud name as previously, e.g. ``COMPUTER-HyperV``. -Also check CPU cores, RAM allocation, failover strategy. +Note: The 'm' flag merges warnings from all jobs. Omitting this shows warnings for each job separately. +To filter out warnings:: -3. Fix authorization token + python scanlog.py last-build.txt -w -m --exclude warn-exclude.lst -The above steps will also install the Appveyor Host Agent software on your computer. -This is the software which communicates with the Appveyor server and directs the build jobs. +The named exclusion file contains a list of regular expressions to match against. -The authorization token used by the agent can be found in the registry: -.. code-block:: text +vscode +~~~~~~ - Computer\HKEY_LOCAL_MACHINE\SOFTWARE\AppVeyor\HostAgent +The warnings output using the scanlog tool can be used as hyperlinks in vscode: -Make sure that both clouds have the same token. +- Select a project, e.g. ``tests/HostTests`` and run ``make ide-vscode`` +- Open the resulting workspace in vscode +- Add the ``sming`` folder to the project +- Open an integrated terminal and dump the warnings as shown above. + Or, redirect them into a file and ``cat`` it. +The file locations act as links to the source. +Note that this isn't perfect. For example, esp-idf paths are not resolved to the specific version in use. +Listing warnings for each job can be helpful as it shows which IDF version was used. -4. Configure BYOC images - Select ``BYOC`` -> ``Images`` and amend mappings as follows: - - (1) - - - Image Name: ``Ubuntu2004`` - - OS Type: ``Linux`` - - Build cloud: "COMPUTER-Docker" (as configured above) - - (2) - - - Image Name: ``Visual Studio 2019`` - - OS Type: ``Windows`` - - Build cloud: "COMPUTER-HyperV" (as configured above) - - Now, when a build is started it should use your own server. - To revert back to normal operation change the ``Image Name`` fields in the entries. - It's not necessary to delete them: just add, say, "X" to the name so they're not recognised. - - - .. note:: - - Clouds may also be configured on a per-project basis by setting the ``APPVEYOR_BUILD_WORKER_CLOUD`` - environment variable to the appropriate cloud name. - - To get both Linux and Windows builds working concurrently using this approach would require a single - cloud to support dual images. +Library CI support +------------------ +Sming libraries may be separately built and tested whether or not they are included as part of +the Sming repository (or a fork). -Rebuilding docker images -~~~~~~~~~~~~~~~~~~~~~~~~ +There is currently only one supported mechanism available: GitHub Actions. -Appveyor images are customised by pre-installing Sming build tools. -When these are updated images must be re-built. +The ``library.yml`` reusable workflow is provided, which takes care of these tasks: -The easiest way to do this is using the provided dockerfiles:: +- Checking in the library to test +- Checking in the Sming framework +- Installing build tools +- Builds all applications within the library's ``samples`` directory, for all supported architectures +- If a test application is provided then that should be located in a ``test`` directory. + This is built for all architectures, and also executed for Host. - cd $SMING_HOME/../Tools/Docker/appveyor - docker build --no-cache -t linux -f Dockerfile-Linux . - docker build --no-cache -t windows -f Dockerfile-Windows . +Builds are handled using :source:`Tools/ci/library/Makefile`. +See also https://docs.github.com/en/actions/using-workflows/reusing-workflows. -Custom images -------------- +To use this in a project, add a suitable workflow to the ``.github/workflows`` directory. +Templates are provided in the ``.github/workflows/library`` directory. -To use a Sming fork for building the image simply replace the repo URL and branch in the ``Shell Commands`` given above. +Here is the basic ``push`` scenario: -These may also be passed to docker build as follows:: +.. code-block:: yaml - docker build -t linux-test -f Dockerfile-Linux --build-arg SMING_REPO=https://github.com/myrepo/Sming --build-arg SMING_BRANCH=feature/appveyor-revisions . + name: CI Push + on: [push] + jobs: + build: + uses: SmingHub/Sming/.github/workflows/library.yml@develop + # Inputs are all optional, defaults are shown + with: + # Repository to fetch Sming from + sming_repo: 'https://github.com/SmingHub/Sming' + # Sming branch to run against + sming_branch: 'develop' + # Library alias + alias: '' +The ``sming_repo`` and ``sming_branch`` inputs are provided if your library requires modifications +to Sming which are not (yet) in the main repository. -Issues ------- +The ``alias`` input is required where the library repository name does not correspond with +the working title. +For example, the ``jerryscript`` library is in a repository called ``Sming-jerryscript``, +so must be checked out using a different name. +If Sming contains a library (or Component) with the same name then it will be overridden, +with a warning ``Multiple matches found for Component 'jerryscript'`` in the build log. -If you get error ``image not supported by cloud`` this probably means an image has been mapped to the wrong clould. -Goto Appveyor -> BYOC -> Images and update/delete the offending entries. +The ``ci-dispatch.yml`` example demonstrates manual triggering, which allows these inputs to be easily changed. +See https://docs.github.com/en/actions/managing-workflow-runs/manually-running-a-workflow. -If either cloud is shown as ``offline`` then check the authorization token (step 4 above). -It may be necessary to restart the ``Appveyor Host Agent`` service (via Windows service manager). +Note that the workflow must be available in the library's default branch, or it will +not appear in the github web page. diff --git a/docs/source/information/develop/clang-tools.rst b/docs/source/information/develop/clang-tools.rst index aba5e45913..683a89bfc5 100644 --- a/docs/source/information/develop/clang-tools.rst +++ b/docs/source/information/develop/clang-tools.rst @@ -5,10 +5,10 @@ Clang Tools is a tool that implements automatic source code formatting. It can be used to automatically enforce the layout rules for Sming. -`clang-tidy `__ -is a C++ “linter” tool to assist with diagnosing and fixing typical programming errors -such as style violations, interface misuse, or bugs that can be deduced via static analysis. -It is provided as part of +`clang-tidy `__ +is a C++ "linter" tool to assist with diagnosing and fixing typical programming errors +including portability/readability issues, bug-prone code constructs, +interface misuse, or bugs that can be deduced via static analysis. You can find details for the current release at https://releases.llvm.org/download.html. Note that *clang-format* is part of the main **Clang** project, whilst *clang-tidy* can be @@ -31,15 +31,15 @@ systems. Different versions of clang-format can produce different results, despite using the same configuration file. - We are using version 8.0.1 of clang-format and clang-tidy on our + We are using version 8.0.1 of clang-format on our Continuous Integration (CI) System. - + You should install the same version on your development computer. -Configuration -------------- +clang-format +------------ Rules ~~~~~ @@ -57,21 +57,15 @@ IDE integration There are multiple existing integrations for IDEs. You can find details in the `ClangFormat documentation `__. -Eclipse IDE -^^^^^^^^^^^ - -For our Eclipse IDE, which is our preferred IDE, we recommend installing +For the Eclipse IDE we recommend installing the `CppStyle plugin `__. You can -configure your IDE to auto-format the code on “Save” using the +configure your IDE to auto-format the code on "Save" using the recommended coding style and/or format according to our coding style rules using Ctrl-Shift-F (for formatting of whole file or selection of lines). Read `Configure CppStyle `__ for details. -Usage ------ - Command Line ~~~~~~~~~~~~ @@ -79,10 +73,10 @@ Single File If you want to directly apply the coding standards from the command line you can run the following command:: - + cd $SMING_HOME clang-format -style=file -i Core/ - + Where ``Core/`` should be replaced with the path to the file that you have modified. @@ -91,10 +85,10 @@ All files The following command will run again the coding standards formatter over all C, C++ and header files inside the ``Sming/Core``, ``samples`` and other key directories:: - + cd $SMING_HOME make cs - + The command needs time to finish. So be patient. It will go over all files and will try to fix any coding style issues. @@ -105,7 +99,7 @@ All files make cs from your project directory. - + Eclipse ~~~~~~~ @@ -116,3 +110,60 @@ Alternatively, you can manually apply the coding style rules by selecting the so C, C++ or header file or a selection in it and run the ``Format`` command (usually Ctrl-Shift-F). + +clang-tidy +---------- + +Configuration +~~~~~~~~~~~~~ + +No specific version is required but generally you should aim to use the most recent version +available in your distribution. Version 17.0.6 was used at time of writing these notes. + +The default tool configuration is defined in the +`.clang-tidy `__ +file, located in the root directory of the framework. + +.. note:: + + Unlike clang-format, clang-tidy has to be able to compile the target code in order to perform static analysis. + Code must build without errors for **Host** architecture. + This means it cannot check code modules for embedded devices, that is, anything in ``Arch/`` which isn't ``Host/``. + It is therefore good practice to keep the device-specific modules to a minimum. + + No object code is generated by clang-tidy. + +Usage +~~~~~ + +Only source files which haven't been built are inspected. +So, to restrict which code gets processed built the entire application normally, +then 'clean' the relevant modules before proceeding with clang-tidy. + +For example:: + + cd $SMING_HOME/../samples/Basic_Servo + make -j SMING_SOC=host + make clean Servo-clean + make CLANG_TIDY=clang-tidy + +If you want to fix a particular type of problem, it's usually best to be explicit:: + + make CLANG_TIDY="clang-tidy --checks='-*,modernize-use-equals-default' --fix" + +Remember to run ``make cs`` and check the output before committing! + +If you want to provide a custom configuration file:: + + make CLANG_TIDY="clang-tidy --config-file=myTidyConfig" + + +.. note:: + + clang-tidy can take a long time to do its work, so it's tempting to use the `-j` option + to speed things up. + You may see some corrupted output though as the output from multiple clang-tidy + instances aren't serialised correctly. + It's usually fine to get a rough 'first-pass' indication of any problems though. + + However, if attempting to apply fixes **DO NOT** use the -j option as this will result in corrupted output. diff --git a/docs/source/information/develop/coding-style.rst b/docs/source/information/develop/coding-style.rst index a9bfa632b1..7e03c3b392 100644 --- a/docs/source/information/develop/coding-style.rst +++ b/docs/source/information/develop/coding-style.rst @@ -91,7 +91,7 @@ Variables Variable names should be short yet meaningful. The choice of a variable name should be mnemonic — that is, designed to indicate to the casual observer the intent of its use. One-character variable names should be avoided except for - temporary “throwaway” variables. Common names for temporary variables are i, j, k, m, and n for integers; c, d, and e for characters. + temporary "throwaway" variables. Common names for temporary variables are i, j, k, m, and n for integers; c, d, and e for characters. Examples:: @@ -180,7 +180,7 @@ For the moment we recommend the use of C++11. The corresponding settings in clan Starting and ending spaces -------------------------- -We don’t recommend the use of a starting or ending space in angles, +We don't recommend the use of a starting or ending space in angles, container literals, c-style cast parentheses, parentheses and square brackets. Our settings are:: @@ -243,7 +243,7 @@ Always on the left:: Includes -------- -We don’t re-sort includes although it is highly recommended to order the +We don't re-sort includes although it is highly recommended to order the headers alphabetically whenever possible:: SortIncludes: false @@ -290,7 +290,7 @@ contributions. These should be marked with a new @author tag. Deprecating code ---------------- -Where a change in the Sming API may break existing users’ code, then the +Where a change in the Sming API may break existing users' code, then the existing type/method/function/variable must be maintained for a time to allow time for migration to the new technique. Such changes should only be made if there is a good reason, for example improved reliability, @@ -320,7 +320,7 @@ Sming makes extensive use of virtual classes. If you are modifying or adding virtual methods then please follow these guidelines: **Rule**: The base class must have a virtual destructor, even if it -doesn’t do anything. Example:: +doesn't do anything. Example:: virtual ~Stream() {} @@ -331,7 +331,7 @@ doesn’t do anything. Example:: ~IDataSourceStream(); Rationale: virtual destructors do not behave like regular virtual -methods - they are ‘chained’ rather than overridden - therefore +methods - they are 'chained' rather than overridden - therefore ``override`` is not appropriate and ``virtual`` is both un-necessary and unhelpful @@ -345,17 +345,19 @@ inherit from and generate a warning if one is not found, or if parameters do not correspond. -**Rule**: Don’t use empty destructors in inherited virtual classes +**Rule**: Don't use empty destructors in inherited virtual classes -Rationale: They’re not necessary +Rationale: They're not necessary Common issues ------------- -Some notes on commonly occurring issues:: +Some notes on commonly occurring issues. +Note that in practice `std::unique_ptr` would be appropriate. +:: /** * @brief Basic example class diff --git a/docs/source/information/develop/components.rst b/docs/source/information/develop/components.rst index 8f9d0c0e20..8682c096ec 100644 --- a/docs/source/information/develop/components.rst +++ b/docs/source/information/develop/components.rst @@ -84,7 +84,7 @@ Supported architectures Unless there are specific reasons not to do so, Components should work on all supported architectures. In particular, it should build and run under the -:doc:`Host Emulator `. +:doc:`Host Emulator `. In order to do this, you should remove any low-level code from the library by: diff --git a/docs/source/information/develop/documentation.rst b/docs/source/information/develop/documentation.rst index c2164682fe..b89724f5b0 100644 --- a/docs/source/information/develop/documentation.rst +++ b/docs/source/information/develop/documentation.rst @@ -171,7 +171,7 @@ perhaps using a group:: Or individual classes. Some experimentation may be necessary but there are plenty of examples within the main documentation to guide you. -You can use the following build variables within your Component's +You can use the following configuration variables within your Component's component.mk file to direct doxygen parsing: diff --git a/docs/source/information/develop/documenting-the-api.rst b/docs/source/information/develop/documenting-the-api.rst index 7d41dad644..4785e8a555 100644 --- a/docs/source/information/develop/documenting-the-api.rst +++ b/docs/source/information/develop/documenting-the-api.rst @@ -7,7 +7,7 @@ developers of the framework, not users of the framework. Sming API documentation is created using javadoc style comments within the source code. Comments are added to header files and doxygen is used to create HTML documentation. API documentation is organised as a set of -*modules*, each of which represents a logical topic, e.g. Date and Time. +*modules*, each of which represents a logical topic, e.g. Date and Time. The API documentation covers the core Sming framework and relevant parts of the ESP SDK (where this is required to use the framework). The API diff --git a/docs/source/information/develop/external-sources.rst b/docs/source/information/develop/external-sources.rst index 065e52b1a2..b2b9c146f7 100644 --- a/docs/source/information/develop/external-sources.rst +++ b/docs/source/information/develop/external-sources.rst @@ -32,12 +32,10 @@ or contained within a Component (e.g. :component:`rboot`). The location must be chosen carefully: Code required within the core Sming framework - If the Component supports multiple architectures, place it in ``Sming/Components``. Otherwise, use the appropriate ``Sming/Arch/*/Components`` directory. Code for general use - Create a new Library in ``Sming/Libraries`` Please consult :doc:`/_inc/Sming/building` for further details about how Components are constructed. @@ -69,24 +67,24 @@ As an example, this is how the `new PWM` submodule was added to the :component-e https://github.com/StefanBruens/ESP8266_new_pwm.git \ Arch/Esp8266/Components/driver/new-pwm -This adds an entry to the end of the ``.gitmodules`` file:: + This adds an entry to the end of the ``.gitmodules`` file:: - [submodule "ESP8266.new-pwm"] - path = Sming/Arch/Esp8266/Components/driver/new-pwm - url = https://github.com/StefanBruens/ESP8266_new_pwm.git + [submodule "ESP8266.new-pwm"] + path = Sming/Arch/Esp8266/Components/driver/new-pwm + url = https://github.com/StefanBruens/ESP8266_new_pwm.git -For naming submodules, please follow the convention used for the other entries in -``.gitmodules``, which is determined by the local path:: + For naming submodules, please follow the convention used for the other entries in + ``.gitmodules``, which is determined by the local path:: -- ``Sming/Components``: just use the name of the submodule -- ``Sming/Arch/ARCH/Components``: Use ``ARCH.name`` -- ``Sming/Libraries``: Use ``Libraries.name`` + - ``Sming/Components``: just use the name of the submodule + - ``Sming/Arch/ARCH/Components``: Use ``ARCH.name`` + - ``Sming/Libraries``: Use ``Libraries.name`` 2. Open ``.gitmodules`` in a text editor and: -a. Move the entry to a more suitable location in the file, i.e. at the end of the - section listing all the ESP8266-specific submodules -b. Add the line ``ignore = dirty`` + a. Move the entry to a more suitable location in the file, i.e. at the end of the + section listing all the ESP8266-specific submodules + b. Add the line ``ignore = dirty`` Applying Patches diff --git a/docs/source/information/events.rst b/docs/source/information/events.rst index 962508fa4d..572c06cc66 100644 --- a/docs/source/information/events.rst +++ b/docs/source/information/events.rst @@ -65,7 +65,7 @@ Both techniques have advantages and disadvantages, and interrupts are certainly Bear in mind that every time an interrupt occurs the CPU has to stop executing your regular program, save any critical registers then jump to the interrupt service routine to run your code. All this takes time, so if the input changes very fast and very frequently then it can consume -a lot of CPU and make the system very sluggish (or even crash it). +a lot of CPU and make the system very sluggish (or even crash it). See :doc:`information/interrupts`. Callbacks --------- @@ -91,3 +91,7 @@ This flexibility comes at a cost, however: These are the main reasons why you should not use Delegates in an interrupt context. See :pull-request:`1734` for some further details about the relative speeds. + + +.. doxygenclass:: Delegate + :members: diff --git a/docs/source/information/flash.rst b/docs/source/information/flash.rst index 884da9ccc4..e835bc0282 100644 --- a/docs/source/information/flash.rst +++ b/docs/source/information/flash.rst @@ -8,29 +8,30 @@ Introduction ESP8266 flash memory sizes vary from 512Kbytes on the ESP-01 up to 4Mbytes on the ESP12F. Up to 16MBytes are supported for custom designs. +Rp2040 has similar support, and the Esp32 has enhanced VMM (Virtual Memory Management) hardware. Sming version 4.3 introduced partition tables to support multiple architectures, different hardware variants and custom flash layouts without restriction. +It is binary compatible with the Esp32 IDF partition tables but with a consistent API across all architectures. See :ref:`hardware_config` for details. -A typical layout for a 4MByte device might look like this: +A typical layout for a 4MByte Esp8266 device might look like this: ======= =============== ==== ========================= =================================================== Address Config variable Size Source filename Description (hex) (if any) (KB) (if applicable) ======= =============== ==== ========================= =================================================== 000000 1 rboot.bin Boot loader - 001000 4 rBoot configuration - 002000 4 Partition table - 003000 4 esp_init_data_default.bin PHY configuration data - 004000 12 blank.bin System parameter area - 006000 4 blank.bin RF Calibration data (Initialised to FFh) - 006000 4 Reserved - 008000 ROM_0_ADDR rom0.bin First ROM image - 100000 RBOOT_SPIFFS_0 - 208000 ROM_1_ADDR rom1.bin Second ROM image + 001000 4 rBoot configuration + 002000 ROM_0_ADDR rom0.bin First ROM image + 102000 ROM_1_ADDR rom1.bin Second ROM image + 200000 RBOOT_SPIFFS_0 300000 RBOOT_SPIFFS_1 + 3FA000 4 Partition table + 3FB000 4 blank.bin RF Calibration data (Initialised to FFh) + 3FC000 4 esp_init_data_default.bin PHY configuration data + 3FD000 12 blank.bin System parameter area ======= =============== ==== ========================= =================================================== @@ -52,13 +53,14 @@ A typical layout for a 4MByte device might look like this: 3FC000 4 esp_init_data_default.bin PHY configuration data 3FD000 12 blank.bin System parameter area ======= =============== ==== ========================= =================================================== - + +The actual layout in use can be seen by running ``make map``. Speed and caching ----------------- -Flash memory on the ESP8266 is accessed via an external SPI bus, so reading it takes about 12x +Flash memory is accessed via an external SPI bus, so reading it takes about 12x longer than reading from internal RAM. To mitigate this, some of the internal RAM is used to cache data. Part of this is managed in hardware, which means if the data required is already in the cache then there is no difference in speed. In general, then, frequently accessed data is read diff --git a/docs/source/information/index.rst b/docs/source/information/index.rst index 0b360e0604..b75aedb06e 100644 --- a/docs/source/information/index.rst +++ b/docs/source/information/index.rst @@ -13,7 +13,5 @@ Information strings interrupts tasks - debugging rboot-ota - command-handler tips-n-tricks diff --git a/docs/source/information/memory.rst b/docs/source/information/memory.rst index 675881c379..4b6d5d151c 100644 --- a/docs/source/information/memory.rst +++ b/docs/source/information/memory.rst @@ -1,6 +1,8 @@ Memory ====== +This section refers to the ESP8266 but is applicable to all device architectures. + Map --- @@ -10,7 +12,7 @@ You can find a map for the ESP8266 memory layout in the `Wiki `. This changes all sizes and offsets to 64-bit. If manipulating files greater than about 2GB (signed 32-bit value) then the :cpp:envvar:`ENABLE_FILE_SIZE64` setting should also be enabled. diff --git a/docs/source/information/tasks.png b/docs/source/information/tasks.png new file mode 100644 index 0000000000..86baa87419 Binary files /dev/null and b/docs/source/information/tasks.png differ diff --git a/docs/source/information/tasks.rst b/docs/source/information/tasks.rst index 339406cd69..42aaf6679c 100644 --- a/docs/source/information/tasks.rst +++ b/docs/source/information/tasks.rst @@ -17,31 +17,7 @@ The BasicTask class This class uses the task queue plus a timer to provide an easy way to write a background task. All you need to is define a *loop()* function which does the work. The task has three states: -.. seqdiag:: - :caption: Task states - :align: center - - seqdiag task-states { - activation = none; - node_width = 80; - node_height = 60; - edge_length = 160; - span_height = 5; - default_shape = roundedbox; - default_fontsize = 12; - - SUSPENDED [label = "suspended"]; - RUNNING [label = "running"]; - SLEEPING [label = "sleeping"]; - - SUSPENDED -> RUNNING [label = "resume()"]; - SUSPENDED -> SLEEPING [label = "sleep()"]; - RUNNING -> SLEEPING [label = "sleep()"]; - RUNNING -> SUSPENDED [label = "suspend()"]; - SLEEPING -> RUNNING [label = "resume()"]; - SLEEPING -> RUNNING [label = "timer expired"]; - SLEEPING -> SUSPENDED [label = "suspend()"]; - } +.. image:: tasks.png To see this in operation, have a look at the :sample:`Basic_Tasks` sample. diff --git a/docs/source/information/tips-n-tricks.rst b/docs/source/information/tips-n-tricks.rst index a987befe1d..04000d3d75 100644 --- a/docs/source/information/tips-n-tricks.rst +++ b/docs/source/information/tips-n-tricks.rst @@ -90,10 +90,10 @@ But the files are big and this is a problem not just because it is slow. The watchdog does not like things to take a long time, and you will almost certainly end up with a timeout. -When a browser asks for a file it doesn’t mind receiving a compressed -version using gzip. (Note that you need to add “Content-Encoding/gzip” +When a browser asks for a file it doesn't mind receiving a compressed +version using gzip. (Note that you need to add "Content-Encoding/gzip" to the header in the response from the server). Using gzip vastly -reduces the sizes of files and it’s well worth doing. +reduces the sizes of files and it's well worth doing. Another size optimisation for CSS files is to remove unused CSS (UNCSS) - I recommend against this as it was too aggressive at removing stuff I diff --git a/docs/source/link-roles.py b/docs/source/link-roles.py index bbf7152f0c..284cd58ff1 100644 --- a/docs/source/link-roles.py +++ b/docs/source/link-roles.py @@ -33,7 +33,7 @@ def get_github_rev(): def setup(app): app.add_role('source', SourceRole()) - app.add_role('issue', autolink('Issue #{0} <' + github_url + '/issue/{0}>')) + app.add_role('issue', autolink('Issue #{0} <' + github_url + '/issues/{0}>')) app.add_role('pull-request', autolink('Pull Request #{0} <' + github_url + '/pull/{0}>')) app.add_role('sample', SampleRole) diff --git a/docs/source/tools/clion.rst b/docs/source/tools/clion.rst index e95f5a2818..d86ecd4236 100644 --- a/docs/source/tools/clion.rst +++ b/docs/source/tools/clion.rst @@ -22,7 +22,7 @@ Developing with the Sming framework can also be done in CLion. 2. Create ``app`` folder and add ``application.cpp`` there 3. Edit ``CMakeLists.txt`` -## Edit CMakeLists.txt +## Edit CMakeLists.txt :: diff --git a/docs/source/tools/eclipse.rst b/docs/source/tools/eclipse.rst index 4bbeb3201b..57a4228b68 100644 --- a/docs/source/tools/eclipse.rst +++ b/docs/source/tools/eclipse.rst @@ -10,15 +10,10 @@ For easier integration make sure you have both :envvar:`ESP_HOME` and :envvar:`SMING_HOME` exported in your working environment. -Software involved ------------------ - -- `Eclipse CDT `__ - Installation ------------ -- Install Eclipse CDT using your operating system packaging tools. +- Install `Eclipse CDT `__ using your operating system packaging tools. Configuration ------------- @@ -52,3 +47,4 @@ you can create such files by going to the root folder of your application and th make ide-eclipse +See also :doc:`/debugging/eclipse/index`. diff --git a/docs/source/tools/vscode.rst b/docs/source/tools/vscode.rst index bf5d254aa7..ffce93cf15 100644 --- a/docs/source/tools/vscode.rst +++ b/docs/source/tools/vscode.rst @@ -13,6 +13,17 @@ Software involved - `Visual Studio Code `__ - `C/C++ extension `__ +.. note:: + + Linux users may prefer `VSCodium `__ which does not contain telemetry or tracking. + + Standard C/C++ language support is available via the `cpptools `__ + extension which is not available in the vscodium repositories. + + Visit https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools and go to ``Version History`` + to download the .vsix file. Open the ``Extensions`` pane in vscodium and drag the file there to install, + or run ``codium --install-extension NAME-OF-FILE.vsix``. + Installation ------------ @@ -70,6 +81,22 @@ To debug your application, follow these steps: VS Code debug selection +Editor window titles +-------------------- + +As Sming is a multi-architecture framework there are lots of files with the same name. +By default editor window titles contain only the filename, but in vscode this can be changed +to something more useful, like including the parent directory name. + +Open user settings JSON (via F1 hotkey) and add this to the config: + +.. code-block:: json + + "workbench.editor.customLabels.patterns": { + "**/*.*": "${dirname}/${filename}.${extname}" + } + + Manual configuration changes ---------------------------- @@ -98,7 +125,7 @@ Known issues / features ----------------------- - The vscode configuration files are only updated when you manually run ``make ide-vscode``. - If you update change critical build variables or add/remove Components to your project, + If you change critical configuration variables or add/remove Components to your project, you may need to run it again to update them. - When running ``make ide-vscode``, comments in the configuration files will be discarded. - ``make ide-vscode`` may overwrite parts of your configuration: be warned! diff --git a/docs/source/troubleshooting/random-restart.rst b/docs/source/troubleshooting/random-restart.rst index 749b29bcab..67069a99de 100644 --- a/docs/source/troubleshooting/random-restart.rst +++ b/docs/source/troubleshooting/random-restart.rst @@ -1,15 +1,17 @@ Random Restarts =============== -First try setting the baud rate to ``74880``. Example for Linux:: +Esp8266 +------- - python -m serial.tools.miniterm /dev/ttyUSB0 74880 +First try setting the baud rate to ``74880``:: + + make terminal COM_SPEED=74880 The random symbols should become readable messages. If you see repeating messages containing ``rf_cal[0] !=0x05`` then most -probably you should ``initialize`` the flash memory on your ESP8266 -device. +probably you should ``initialize`` the flash memory on your ESP8266 device. To achieve this do the following: @@ -34,3 +36,18 @@ To achieve this do the following: 4) Verify flash data has been written successfully make verifyflash + + +Esp32 +----- + +Bootloader messages should be visible and may give some indication as to the problem. + +If :envvar:`SDK_CUSTOM_CONFIG` has been set in your project, or the SDK configuration has otherwise +been changed from defaults, try reverting it back to defaults:: + + make sdk-config-clean + make SDK_CUSTOM_CONFIG= + +The ESP IDF framework runs on FreeRTOS and there is a known deadlock problem related to flash memory access if FreeRTOS is initialised and running on both cores. +For this reason, the setting ``CONFIG_FREERTOS_UNICODE=y`` must be set. See :issue:`2653`. diff --git a/docs/source/troubleshooting/sample-compilation.rst b/docs/source/troubleshooting/sample-compilation.rst index 0098d6a331..6cb2cd62df 100644 --- a/docs/source/troubleshooting/sample-compilation.rst +++ b/docs/source/troubleshooting/sample-compilation.rst @@ -4,19 +4,21 @@ Sample Compilation .. highlight:: bash +.. note:: + + The commands given here are for linux/MacOS with bash shell. + If using another OS or shell they may require adjusting. + The first thing that you need to do is to make sure that you have a clean source code. And second if the sample is still not compiling you have to provide us with more information. -Let’s start with the first part: “Clean Source Code State”. If you are +Let's start with the first part: "Clean Source Code State". If you are familiar with ``git`` you can run ``git status`` to get more -information. Sometimes this won’t be enough therefore we recommend you -the following steps ( They are working on Linux with bash shell. If you -have another OS and shell you should adjust them accordingly). +information. Sometimes this won't be enough therefore we recommend you +the following steps:: -:: - - cd /tmp + cd /tmp git clone https://github.com/SmingHub/Sming.git SmingForTest cd /tmp/SmingForTest/Sming export SMING_HOME=/tmp/SmingForTest/Sming @@ -26,12 +28,9 @@ should be completely different than the Sming directory that you are using on a daily basis. Also it points the SMING_HOME variable to the new temporary directory with the clean source code. -Now let’s go to the second step: “Compile a sample and report issues, if -any”. We will use the Basic_Ssl sample. Before we compile a sample we -need to compile the Sming library. This can be done calling the -following commands: - -:: +Now let's go to the second step: "Compile a sample and report issues, if +any". We will use the Basic_Ssl sample. Before we compile a sample we +need to compile the Sming library:: cd /tmp/SmingForTest/Sming export SMING_HOME=/tmp/SmingForTest/Sming @@ -41,32 +40,25 @@ The last makes sure to clean any intermediate files or directories. If we run now ``make``. It will fetch the needed submodules, compile the code and build a library out of it. In our case we need to compile Sming with an optional SSL support. In order to compile Sming with SSL we need -to add the :envvar:`ENABLE_SSL` =1 directive. The command that we need to run now -will look like this: +to add the :envvar:`ENABLE_SSL=1 `__ before posting a github issues. Maybe someone else had a similar issue! If nothing found, please make sure to provide all required information -when posting issues. Here’s the minimum that you will need to get: +when posting issues. Here's the minimum that you will need to get: Start ``cmd.exe`` and provide output of the following commands: :: @@ -29,6 +29,6 @@ Common issues & solutions path separator, and NO backslash ``\`` at the end. - MinGW paths should be at the start of PATH environment variable (before other items). -- If you update your sming-core source don’t forget to do +- If you update your sming-core source don't forget to do ``cd c:\tools\sming\Sming && make clean && make`` diff --git a/docs/source/upgrading/3.8-4.0.rst b/docs/source/upgrading/3.8-4.0.rst index 47b7369a0e..10ca2ef110 100644 --- a/docs/source/upgrading/3.8-4.0.rst +++ b/docs/source/upgrading/3.8-4.0.rst @@ -24,7 +24,7 @@ architectures, such as the Host Emulator, and in the future the ESP32. The ``Sming/Arch`` directory should never be accessed directly: it contains specific files for the target architecture, and may provide different header file versions to the main ones. Instead, consider these -directories to be your ‘root’ include directories: +directories to be your 'root' include directories: :: @@ -64,7 +64,7 @@ user_include.h -------------- This file is generally #included ahead of everything else so that common -architecture-specific definitions are available. Unless you’ve made +architecture-specific definitions are available. Unless you've made changes to the file, it is not required and you should delete it: Sming provides a default which will be used. diff --git a/docs/source/upgrading/4.2-4.3.rst b/docs/source/upgrading/4.2-4.3.rst index 01e24235c8..7f57a2b7c7 100644 --- a/docs/source/upgrading/4.2-4.3.rst +++ b/docs/source/upgrading/4.2-4.3.rst @@ -114,17 +114,17 @@ Functions are now mainly just wrappers around filing system calls. A single global IFileSystem instance is used. SPIFFS - All access is now managed via the ``IFS::SPIFFS::FileSystem`` implementation. + All access is now managed via the :cpp:class:`IFS::SPIFFS::FileSystem` implementation. Applications should not use SPIFFS functions directly. .. important:: - SPIFFS is now built with ``SPIFFS_OBJ_META_LEN=16`` to store extended attribute information. + SPIFFS is now built with :envvar:`SPIFFS_OBJ_META_LEN=16 ` to store extended attribute information. Existing volumes built with other values will not be directly compatible; the file listing may be correct but file contents will not. - To accommodate use of existing pre-built SPIFFS images, :envvar:`SPIFFS_OBJ_META_LEN` has been added:: + To retain compatibility with existing pre-built SPIFFS images, you can override as follows:: make SPIFFS_OBJ_META_LEN=0 @@ -132,4 +132,4 @@ SPIFFS File open flags e.g. eFO_ReadOnly. These will still work but are now deprecated and should be replaced with their - C++ equivalent such as ``File::ReadOnly``. + C++ equivalent such as :cpp:member:`File::ReadOnly`. diff --git a/docs/source/upgrading/4.4-4.5.rst b/docs/source/upgrading/4.4-4.5.rst index 800cb30d2a..8e18033a3b 100644 --- a/docs/source/upgrading/4.4-4.5.rst +++ b/docs/source/upgrading/4.4-4.5.rst @@ -27,7 +27,7 @@ For more information read the updated :doc:`/tools/eclipse`. Esp8266 toolchain ----------------- -Sming now requires the :doc:`/arch/esp8266/getting-started/eqt` for building. +Sming now requires the :ref:`esp_quick_toolchain` for building. Support for the old legacy toolchains (ESP open SDK, UDK) have been dropped. They may still work but are no longer tested. diff --git a/docs/source/upgrading/4.7-5.1.rst b/docs/source/upgrading/4.7-5.1.rst index a1c8aa0c87..57bfb12ca5 100644 --- a/docs/source/upgrading/4.7-5.1.rst +++ b/docs/source/upgrading/4.7-5.1.rst @@ -20,7 +20,7 @@ This has to be replaced with the directive ``COMPONENT_DEPENDS += CommandProcess Including Header Files ~~~~~~~~~~~~~~~~~~~~~~~ -To include the command processing headers in your C/C++ application we used to do the following +To include the command processing headers in your C++ application we used to do the following For example:: diff --git a/docs/source/upgrading/5.1-5.2.rst b/docs/source/upgrading/5.1-5.2.rst new file mode 100644 index 0000000000..55cbc7a831 --- /dev/null +++ b/docs/source/upgrading/5.1-5.2.rst @@ -0,0 +1,143 @@ +From v5.1 to v5.2 +================= + +.. highlight:: c++ + +**Deprecated: ESP32 IDF version 4.3, 4.4 and 5.0** + +The older 4.3, 4.4 and 5.0 versions of the ESP32 IDF are deprecated and support for them will be removed in the future. +The installation scripts now install IDF version 5.2 by default. See :ref:`idf_versions` for further details. + +**Windows installer** + +The Windows installer makes use of custom chocolatey packages, which are out of date. +These packages are separate from the main Sming repository which makes maintenance problematic. + +The procedure has therefore been revised to use installation scripts instead of these chocolatey packages. This brings the installation procedure closer to that for Linux/MacOS. + +The initial installation step to bootstrap the installation remains unchanged: The ``choco-install.cmd`` script is fetched from the Sming ``develop`` branch and executed. +The custom choco scripts have been replaced with scripted logic. + +Installation of toolchains is done as a separate step as it does not require administrative priviledges. + +The documentation at https://sming.readthedocs.io/en/latest/getting-started/windows/index.html has been updated to reflect these changes. + + +**PartitionStream: Breaking change** + +The :cpp:class:`Storage::PartitionStream` constructors with ``blockErase`` parameter have been deprecated. +The intended default behaviour is read-only, however previously this also allowed writing without block erase. +This can result in corrupted flash contents where the flash has not been explicitly erased beforehand. + +The new constructors instead use a :cpp:enum:`Storage::Mode` so behaviour is more explicit. +The default is read-only and writes will now be failed. For example:: + + Storage::PartitionStream stream(myPartition, Storage::Mode::BlockErase); + + +**64-bit time_t** + +There is some variability in whether `time_t` is 32 or 64 bits. See :issue:`2758`. + +This is dependent on the toolchain and accompanying C library. + +32-bits: + +- Esp32 IDF 4.x +- Windows Host (using mingw) +- Linux host builds prior to Sming v5.2 + +Building for these will generate a warning ``**Y2038** time_t is only 32-bits in this build configuration``. +If you cannot upgrade then build with :envvar:`STRICT` set to 1. + +Range of time_t: + +=========== =================== +value Timestamp +=========== =================== +-0x80000000 1901-12-13 20:45:52 +0x00000000 1970-01-01 00:00:00 +0x7fffffff 2038-01-19 03:14:07 +=========== =================== + +All others use 64-bit values. + +For reference, C library source code can be found here https://sourceware.org/git/?p=newlib-cygwin.git;a=blob;f=newlib/libc/ + +Rp2040 builds with standard ARM toolkit so probably accommodated by the standard repo. + +Espressif toolchains use forks: + +- esp8266: https://github.com/earlephilhower/newlib-xtensa/blob/xtensa-4_0_0-lock-arduino/newlib/libc/ +- esp32: https://github.com/espressif/newlib-esp32/blob/esp-4.3.0/newlib/libc/ + + +**Toolchain versions updated** + +Esp8266 + The installer has been updated to use the latest toolchain (Feb 23), gcc 10.3. + +Esp32 IDF + The installation scripts now install IDF version 5.2 by default. + See :ref:`idf_versions` for further details. + +RP2040 + The installer has been updated to use the latest toolchain (Oct 23), gcc 13.2. + + +**Bearssl client certificate validation** + +Using ENABLE_SSL=Bearssl in a client application, no verification on the server certificate is performed. +This is a potential security issue. + +Attempting the same thing with Axtls results in an ``X509_VFY_ERROR_NO_TRUSTED_CERT`` error. +Applications must explicitly call :cpp:func:`HttpRequest::onSslInit` and set the ``verifyLater`` flag. +This extra step ensures that security checks are not unintentionally bypassed. + +The same behaviour is now presented when using Bearssl, and will now fail with ``X509_NOT_TRUSTED``. + + +**FlashString copy support removed** + +The :library:`FlashString` previously supported copies (references) like this:: + + FlashString emptyString; + FlashString stringCopy(FS("Inline string")); + + DEFINE_FSTR_DATA_LOCAL(flashHelloData, "Hello"); + auto myCopy = flashHelloData; + +These will now fail to compile. +Copy construction and assignment has been explicitly deleted so avoid unintentional side-effects. + +Objects should always be passed by reference. + + +**spi_flash functions** + +Several definitions have been deprecated/removed as they serve no purpose since partitions introduced. + +``flashmem_get_first_free_block_address()`` + +``flashmem_get_info()`` returns a common ``SPIFlashInfo`` structure for all architectures. +Esp8266 previously had a structure definition with two ``unknown`` fields as this directly represented +the contents of the first 16 bytes of flash. These have been removed and the structure unpacked. + +The following macro definitions have been removed for esp8266: + +- ``SYS_PARAM_SEC_COUNT`` +- ``FLASH_WORK_SEC_COUNT`` +- ``INTERNAL_FLASH_SIZE`` + +These are related to the fixed system parameter block at the end of flash memory. +With partitions this is relocatable so any code which depends on these will be wrong. + + +**CsvReader library** + +The :cpp:type:`CsvReader` class has been moved out of ``Core/Data`` and into :library:`CsvReader` +which has additional capabilities. Changes to existing code: + +- Add ``CsvReader`` to your project's :cpp:envvar:`COMPONENT_DEPENDS` +- Change ``#include `` to ``#include `` +- Change ``CsvReader`` class to :cpp:class:`CSV::Reader` diff --git a/docs/source/upgrading/index.rst b/docs/source/upgrading/index.rst index 9677ddf287..a0e3ace2a7 100644 --- a/docs/source/upgrading/index.rst +++ b/docs/source/upgrading/index.rst @@ -7,6 +7,7 @@ For newer versions we have dedicated pages. .. toctree:: :maxdepth: 1 + 5.1-5.2 4.7-5.1 4.6-4.7 4.5-4.6 diff --git a/samples/Accel_Gyro_MPU6050/README.rst b/samples/Accel_Gyro_MPU6050/README.rst index d43abbcfff..a4c6596240 100644 --- a/samples/Accel_Gyro_MPU6050/README.rst +++ b/samples/Accel_Gyro_MPU6050/README.rst @@ -1,5 +1,5 @@ MPU6050 Six-Axis (Gyro + Accelerometer) -================ +======================================= MPU6050 sensor reader. diff --git a/samples/Accel_Gyro_MPU6050/app/application.cpp b/samples/Accel_Gyro_MPU6050/app/application.cpp index 0190f99c03..f060d104f2 100644 --- a/samples/Accel_Gyro_MPU6050/app/application.cpp +++ b/samples/Accel_Gyro_MPU6050/app/application.cpp @@ -18,7 +18,8 @@ void init() Wire.begin(DEFAULT_SDA_PIN, DEFAULT_SCL_PIN); mpu.initialize(); - Serial.println(mpu.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed"); + bool success = mpu.testConnection(); + Serial << _F("MPU6050 connection ") << (success ? _F("successful") : _F("failed")) << endl; mainLoopTimer.initializeMs(mainLoop).start(); } diff --git a/samples/Accelerometer_MMA7455/app/application.cpp b/samples/Accelerometer_MMA7455/app/application.cpp index edff93d77a..2a02f7b75d 100644 --- a/samples/Accelerometer_MMA7455/app/application.cpp +++ b/samples/Accelerometer_MMA7455/app/application.cpp @@ -3,11 +3,11 @@ // For more information read: https://code.google.com/p/mma-7455-arduino-library/ MMA_7455 accel; -Timer procTimer; +SimpleTimer procTimer; void readSensor() { - Serial.println("Reading.."); + Serial.println(_F("Reading..")); int8_t x = accel.readAxis('x'); int8_t y = accel.readAxis('y'); @@ -29,5 +29,5 @@ void init() accel.initSensitivity(MMA_7455_2G_MODE); // Start reading loop - procTimer.initializeMs(300, readSensor).start(); + procTimer.initializeMs<300>(readSensor).start(); } diff --git a/samples/Basic_APA102/app/application.cpp b/samples/Basic_APA102/app/application.cpp index 9297b41639..0558482bc3 100644 --- a/samples/Basic_APA102/app/application.cpp +++ b/samples/Basic_APA102/app/application.cpp @@ -23,7 +23,9 @@ #define SPI_CS 2 -Timer procTimer; +namespace +{ +SimpleTimer procTimer; // in this demo, the same ports for HW and SW SPI are used #ifdef _USE_SOFTSPI @@ -34,12 +36,12 @@ APA102 LED(NUM_LED); // APA102 constructor, call with number of LEDs //APA102 LED(NUM_LED, SPI); #endif -static SPISettings SPI_1MHZ = SPISettings(1000000, MSBFIRST, SPI_MODE3); -static SPISettings SPI_2MHZ = SPISettings(2000000, MSBFIRST, SPI_MODE3); +SPISettings SPI_1MHZ{1000000, MSBFIRST, SPI_MODE3}; +SPISettings SPI_2MHZ{2000000, MSBFIRST, SPI_MODE3}; /* color wheel function: * (simple) three 120° shifted colors -> color transitions r-g-b-r */ -static col_t colorWheel(uint16_t step, uint16_t numStep) +col_t colorWheel(uint16_t step, uint16_t numStep) { col_t col = {0}; col.br = 10; @@ -63,10 +65,10 @@ static col_t colorWheel(uint16_t step, uint16_t numStep) return col; } -static void updateLED() +void updateLED() { - static unsigned state = 0; - static unsigned cnt = 0; + static unsigned state; + static unsigned cnt; switch(state++) { case 0: @@ -113,6 +115,8 @@ static void updateLED() } } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); diff --git a/samples/Basic_AWS/app/application.cpp b/samples/Basic_AWS/app/application.cpp index 03c637a0ab..7f2edde2f2 100644 --- a/samples/Basic_AWS/app/application.cpp +++ b/samples/Basic_AWS/app/application.cpp @@ -26,11 +26,11 @@ void startMqttClient() Url url; url.Scheme = URI_SCHEME_MQTT_SECURE; url.Host = awsEndpoint; - mqtt.connect(url, "Basic_AWS"); + mqtt.connect(url, F("Basic_AWS")); // Assign a disconnect callback function // mqtt.setCompleteDelegate(checkMQTTDisconnect); - mqtt.subscribe("thing/fish/test"); + mqtt.subscribe(F("thing/fish/test")); } // Publish our message @@ -41,8 +41,8 @@ void publishMessage() startMqttClient(); } - Serial.println("publish message"); - mqtt.publish("version", "ver.1.2"); + Serial.println(_F("publish message")); + mqtt.publish(F("version"), F("ver.1.2")); } // Callback for messages, arrived from MQTT server diff --git a/samples/Basic_AWS/component.mk b/samples/Basic_AWS/component.mk index 6e25c28d7d..88a0932e81 100644 --- a/samples/Basic_AWS/component.mk +++ b/samples/Basic_AWS/component.mk @@ -1,3 +1,3 @@ -ENABLE_SSL := 1 +ENABLE_SSL ?= 1 MQTT_NO_COMPAT := 1 ENABLE_CUSTOM_HEAP := 1 diff --git a/samples/Basic_AWS/include/ssl/cert.h b/samples/Basic_AWS/include/ssl/cert.h deleted file mode 100644 index b0569a1e1c..0000000000 --- a/samples/Basic_AWS/include/ssl/cert.h +++ /dev/null @@ -1,27 +0,0 @@ -unsigned char default_certificate[] = { - 0x30, 0x82, 0x01, 0xd7, 0x30, 0x82, 0x01, 0x40, 0x02, 0x09, 0x00, 0xf2, 0x26, 0x4c, 0x02, 0x27, 0x42, 0x08, 0x09, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x34, 0x31, 0x32, - 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x29, 0x61, 0x78, 0x54, 0x4c, 0x53, 0x20, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x20, 0x44, 0x6f, 0x64, 0x67, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x39, 0x30, - 0x39, 0x31, 0x34, 0x32, 0x30, 0x35, 0x32, 0x33, 0x36, 0x5a, 0x17, 0x0d, 0x33, 0x33, 0x30, 0x35, 0x32, 0x33, 0x32, - 0x30, 0x35, 0x32, 0x33, 0x36, 0x5a, 0x30, 0x2c, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, - 0x61, 0x78, 0x54, 0x4c, 0x53, 0x20, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x13, 0x09, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x30, 0x81, 0x9f, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, - 0x89, 0x02, 0x81, 0x81, 0x00, 0xb8, 0x03, 0x9f, 0xa7, 0x44, 0x83, 0xc9, 0x3d, 0x6d, 0xd3, 0x77, 0x93, 0x83, 0x54, - 0xed, 0x2e, 0xd6, 0xc3, 0xfb, 0xdf, 0xe3, 0x4d, 0x53, 0x0f, 0x26, 0x06, 0xb0, 0xb9, 0xc8, 0x8e, 0x7a, 0x38, 0x18, - 0x89, 0x2e, 0xe3, 0xa3, 0x53, 0xc2, 0xba, 0xe5, 0x3f, 0xa5, 0x25, 0x54, 0x8a, 0x67, 0x09, 0xf1, 0x9f, 0xf2, 0xad, - 0x2e, 0x42, 0xb7, 0x8d, 0x2c, 0x0b, 0x73, 0xf6, 0x5a, 0x89, 0x51, 0xac, 0xf0, 0x97, 0x77, 0x17, 0x4d, 0x66, 0xca, - 0x20, 0xc9, 0x17, 0xbf, 0x97, 0xd3, 0xfd, 0xf0, 0xf7, 0x4b, 0xad, 0x30, 0xa9, 0x09, 0x3c, 0x62, 0x85, 0xde, 0x47, - 0x60, 0x10, 0x2d, 0xe5, 0x0b, 0x9e, 0x50, 0x44, 0xb3, 0x99, 0xda, 0x51, 0xd4, 0xbe, 0x30, 0x4f, 0x6d, 0x9d, 0x23, - 0x49, 0x47, 0x4e, 0xe7, 0xcf, 0x2f, 0x1b, 0x5b, 0xa0, 0x49, 0xc0, 0xc2, 0x51, 0x35, 0xde, 0x61, 0x82, 0x35, 0xc1, - 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, - 0x00, 0x03, 0x81, 0x81, 0x00, 0x20, 0x37, 0xa2, 0xc0, 0xd5, 0x9c, 0x8d, 0xd0, 0x6f, 0x9d, 0x39, 0x2c, 0xb1, 0xb6, - 0xd7, 0x25, 0xc1, 0x92, 0xf3, 0x6d, 0x44, 0xad, 0x89, 0x33, 0xa4, 0xcb, 0xde, 0xc0, 0xeb, 0x58, 0xcb, 0xa2, 0xd5, - 0xc7, 0x54, 0xac, 0x8a, 0x29, 0xfd, 0x8e, 0x4e, 0x0e, 0x2a, 0x09, 0xec, 0xae, 0x3d, 0x40, 0xd0, 0x4c, 0xd0, 0xd6, - 0xa5, 0x8a, 0x97, 0x40, 0x92, 0x6b, 0x51, 0xc1, 0xf5, 0xe9, 0xa8, 0xdc, 0x99, 0xac, 0x35, 0xae, 0x59, 0x1f, 0x14, - 0x4d, 0x7e, 0xbb, 0xa7, 0x31, 0x76, 0x8c, 0xf3, 0xfc, 0xf8, 0x91, 0x91, 0x3d, 0x6b, 0x15, 0xec, 0xdd, 0x04, 0xb4, - 0x67, 0x81, 0xee, 0xd8, 0x31, 0xaf, 0xfc, 0xf2, 0x6a, 0x36, 0x87, 0xc1, 0x03, 0x49, 0xc4, 0x64, 0x17, 0x29, 0x8b, - 0x44, 0x50, 0x78, 0x3a, 0x2a, 0x0b, 0x6b, 0xf5, 0xf5, 0x38, 0x87, 0x4e, 0x86, 0x68, 0x3b, 0x7d, 0xae, 0x1f, 0xd7}; -unsigned int default_certificate_len = 475; diff --git a/samples/Basic_AWS/include/ssl/private_key.h b/samples/Basic_AWS/include/ssl/private_key.h deleted file mode 100644 index 1e8c08d258..0000000000 --- a/samples/Basic_AWS/include/ssl/private_key.h +++ /dev/null @@ -1,34 +0,0 @@ -unsigned char default_private_key[] = { - 0x30, 0x82, 0x02, 0x5c, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xb8, 0x03, 0x9f, 0xa7, 0x44, 0x83, 0xc9, 0x3d, - 0x6d, 0xd3, 0x77, 0x93, 0x83, 0x54, 0xed, 0x2e, 0xd6, 0xc3, 0xfb, 0xdf, 0xe3, 0x4d, 0x53, 0x0f, 0x26, 0x06, 0xb0, - 0xb9, 0xc8, 0x8e, 0x7a, 0x38, 0x18, 0x89, 0x2e, 0xe3, 0xa3, 0x53, 0xc2, 0xba, 0xe5, 0x3f, 0xa5, 0x25, 0x54, 0x8a, - 0x67, 0x09, 0xf1, 0x9f, 0xf2, 0xad, 0x2e, 0x42, 0xb7, 0x8d, 0x2c, 0x0b, 0x73, 0xf6, 0x5a, 0x89, 0x51, 0xac, 0xf0, - 0x97, 0x77, 0x17, 0x4d, 0x66, 0xca, 0x20, 0xc9, 0x17, 0xbf, 0x97, 0xd3, 0xfd, 0xf0, 0xf7, 0x4b, 0xad, 0x30, 0xa9, - 0x09, 0x3c, 0x62, 0x85, 0xde, 0x47, 0x60, 0x10, 0x2d, 0xe5, 0x0b, 0x9e, 0x50, 0x44, 0xb3, 0x99, 0xda, 0x51, 0xd4, - 0xbe, 0x30, 0x4f, 0x6d, 0x9d, 0x23, 0x49, 0x47, 0x4e, 0xe7, 0xcf, 0x2f, 0x1b, 0x5b, 0xa0, 0x49, 0xc0, 0xc2, 0x51, - 0x35, 0xde, 0x61, 0x82, 0x35, 0xc1, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x81, 0x80, 0x18, 0xfb, 0xd4, 0xf7, 0x5e, - 0xe4, 0x0d, 0xb4, 0x9b, 0x6e, 0xb4, 0xb3, 0x80, 0x87, 0x4d, 0x54, 0xa8, 0xb0, 0x1f, 0x48, 0x7c, 0x92, 0x09, 0x0e, - 0xeb, 0x78, 0xc9, 0x11, 0xd0, 0x5b, 0x17, 0xd8, 0xf9, 0xeb, 0xd6, 0x43, 0xed, 0xee, 0xf7, 0x67, 0x6c, 0xac, 0xc1, - 0x7d, 0x5a, 0x07, 0x18, 0x8a, 0x4f, 0x16, 0x0a, 0x5a, 0xdd, 0x07, 0x0d, 0xe8, 0xca, 0xec, 0x1b, 0x28, 0x7d, 0x8e, - 0x5b, 0x5a, 0x46, 0xab, 0xfe, 0x5b, 0xe8, 0x05, 0x03, 0x06, 0x66, 0xd6, 0xac, 0xc3, 0xea, 0x92, 0x96, 0x69, 0x0d, - 0x54, 0x81, 0x31, 0x5f, 0x11, 0xea, 0x3f, 0x4e, 0xf1, 0x11, 0xc8, 0xe7, 0xe3, 0x4a, 0x15, 0xa6, 0xc8, 0x7d, 0x19, - 0xba, 0x18, 0xa9, 0xfb, 0x19, 0x94, 0xdc, 0xc4, 0x47, 0x11, 0xea, 0xfa, 0x45, 0x15, 0x00, 0x39, 0xf9, 0xdd, 0x0b, - 0x50, 0x56, 0xd8, 0xb8, 0x24, 0x50, 0x75, 0x2b, 0x61, 0x02, 0x41, 0x00, 0xe1, 0xfc, 0x01, 0x09, 0x8c, 0x15, 0x9a, - 0x38, 0x1b, 0xc8, 0xe9, 0x0a, 0xdb, 0x97, 0x5f, 0xb9, 0x79, 0x00, 0x7d, 0x6c, 0x02, 0x5f, 0x7d, 0xaa, 0xe6, 0x4b, - 0x98, 0x41, 0xfc, 0xc6, 0x59, 0x99, 0x39, 0x2e, 0x78, 0x65, 0xc0, 0x9b, 0xf5, 0x49, 0x87, 0xc1, 0xd7, 0xb1, 0x34, - 0x51, 0x2d, 0xf5, 0x8e, 0x05, 0x8c, 0xe8, 0xbf, 0x11, 0xca, 0xd9, 0xaf, 0x57, 0xf7, 0x50, 0x1f, 0x4a, 0x91, 0x95, - 0x02, 0x41, 0x00, 0xd0, 0x74, 0x88, 0xa4, 0x71, 0xb6, 0x24, 0x3e, 0xb4, 0x69, 0x7d, 0xb0, 0xb8, 0xeb, 0x1d, 0x13, - 0x98, 0x65, 0xf7, 0x99, 0xc6, 0x7e, 0xb8, 0x0d, 0xa0, 0xcc, 0x49, 0xca, 0x93, 0x82, 0x6a, 0x2e, 0x7e, 0xa8, 0x19, - 0xe1, 0x8d, 0x5b, 0x4d, 0x14, 0x00, 0x88, 0xcc, 0xb9, 0xb4, 0x71, 0xbd, 0x47, 0x2a, 0x82, 0x88, 0x64, 0x26, 0xdb, - 0x1b, 0x42, 0x63, 0x19, 0x09, 0x3e, 0x33, 0xac, 0xa0, 0x7d, 0x02, 0x40, 0x60, 0x20, 0x16, 0xbc, 0xdd, 0xe6, 0x8e, - 0x7c, 0x11, 0x6d, 0x8b, 0x9b, 0x7f, 0xbe, 0xcb, 0x0c, 0x14, 0xe9, 0x5d, 0x70, 0x65, 0x2e, 0x03, 0x41, 0x7f, 0xc6, - 0x66, 0x14, 0xa3, 0x96, 0x27, 0xa4, 0xa2, 0x8b, 0x1e, 0xd1, 0x81, 0x75, 0x95, 0x87, 0xda, 0x84, 0x5c, 0xe0, 0x56, - 0xb5, 0xb5, 0x4b, 0xff, 0x46, 0x63, 0x22, 0xd9, 0xab, 0x92, 0xd2, 0xb7, 0xe0, 0x3e, 0x25, 0xc9, 0xb9, 0xa9, 0x65, - 0x02, 0x41, 0x00, 0xce, 0x9b, 0x72, 0x03, 0x6b, 0x21, 0x18, 0x73, 0x7d, 0xe5, 0x40, 0xca, 0xb3, 0xbd, 0x74, 0xa8, - 0x43, 0x58, 0x6d, 0x3c, 0x60, 0xdc, 0xa0, 0x18, 0x01, 0xd3, 0xf9, 0x1f, 0x6b, 0x6c, 0xcb, 0x49, 0x22, 0x08, 0x02, - 0xfe, 0xe7, 0x58, 0x22, 0xe1, 0x3c, 0x56, 0x5a, 0x73, 0x85, 0x41, 0x66, 0x54, 0xee, 0xf1, 0x49, 0xb5, 0xda, 0x3d, - 0x38, 0x9b, 0x68, 0x15, 0x1c, 0x70, 0x26, 0x4f, 0x67, 0x11, 0x02, 0x40, 0x02, 0x54, 0x5d, 0x63, 0x2c, 0x2c, 0x7c, - 0x4c, 0x09, 0x18, 0x38, 0xac, 0x0a, 0xec, 0xb7, 0x33, 0x86, 0x15, 0x23, 0x39, 0xab, 0x50, 0x22, 0x6f, 0x7a, 0x71, - 0xa8, 0x46, 0x13, 0x0f, 0xae, 0xb4, 0xa4, 0xc4, 0x63, 0x03, 0x35, 0x05, 0x51, 0x0b, 0x59, 0x8b, 0xcf, 0x60, 0xf2, - 0xa2, 0x15, 0xaf, 0x7e, 0x07, 0xb2, 0xb5, 0xc6, 0x08, 0x75, 0x84, 0xed, 0x58, 0xf0, 0xb7, 0x37, 0xa0, 0xcd, 0x21}; -unsigned int default_private_key_len = 608; diff --git a/samples/Basic_Audio/app/application.cpp b/samples/Basic_Audio/app/application.cpp index d0a2f3e1be..95becf40d8 100644 --- a/samples/Basic_Audio/app/application.cpp +++ b/samples/Basic_Audio/app/application.cpp @@ -19,6 +19,8 @@ // If using an external DAC, set this to 0 - you'll probably need to change other settings as well #define ENABLE_DELTA_SIGMA +namespace +{ // Set this to 0 to output fixed values for easier checking on a scope or signal analyzer //#define GENERATE_FIXED_VALUES constexpr i2s_sample_t fixedSampleValue = {0xF55F0AA0}; @@ -30,17 +32,17 @@ constexpr unsigned targetSampleRate = 44100; constexpr float sineWaveFrequency = 440; // Measure time taken to fill the I2S DMA buffers -static Profiling::MicroTimes fillTime("Fill Time"); +Profiling::MicroTimes fillTime("Fill Time"); // Measure time taken between I2S callback (interrupt) and our task callback getting executed -static Profiling::MicroTimes callbackLatency("Callback latency"); +Profiling::MicroTimes callbackLatency("Callback latency"); // Report status periodically -static SimpleTimer statusTimer; -static constexpr unsigned statusIntervalMs = 5000; +SimpleTimer statusTimer; +constexpr unsigned statusIntervalMs = 5000; // One full sine-wave cycle -static struct { +struct SineWaveTable { std::unique_ptr samples; unsigned sampleCount = 0; unsigned readPos = 0; @@ -57,7 +59,7 @@ static struct { Serial << _F("Generating sine wave table @ ") << frequency << _F(" Hz, ") << sampleCount << _F(" samples") << endl; - samples.reset(new uint16_t[sampleCount]); + samples = std::make_unique(sampleCount); if(!samples) { debug_e("Memory allocation failed"); return false; @@ -81,7 +83,24 @@ static struct { } return value; } -} sineWaveTable; +}; + +SineWaveTable sineWaveTable; + +#ifdef GENERATE_FIXED_VALUES + +void writeFixedValues() +{ + i2s_buffer_info_t info; + while(i2s_dma_write(&info, UINT_MAX)) { + memset(info.samples, 0, info.size); + // for(unsigned i = 0; i < info.size / sizeof(i2s_sample_t); ++i) { + // info.samples[i] = fixedSampleValue; + // } + } +} + +#else /* * Outputs a 172.266Hz sine wave (256 samples at 44100 samples/sec) @@ -105,16 +124,7 @@ void writeSine() } } -void writeFixedValues() -{ - i2s_buffer_info_t info; - while(i2s_dma_write(&info, UINT_MAX)) { - memset(info.samples, 0, info.size); - // for(unsigned i = 0; i < info.size / sizeof(i2s_sample_t); ++i) { - // info.samples[i] = fixedSampleValue; - // } - } -} +#endif // GENERATE_FIXED_VALUES void fillBuffers() { @@ -128,7 +138,7 @@ void fillBuffers() fillTime.update(); } -static void checkReceive() +void checkReceive() { unsigned total = 0; i2s_buffer_info_t info; @@ -139,7 +149,7 @@ static void checkReceive() debug_i("RX: %u bytes", total); } -void IRAM_ATTR i2sCallback(void* param, i2s_event_type_t event) +void IRAM_ATTR i2sCallback(void*, i2s_event_type_t event) { // For this sample, process the data in task context switch(event) { @@ -154,7 +164,7 @@ void IRAM_ATTR i2sCallback(void* param, i2s_event_type_t event) } } -static void initialiseI2S() +void initialiseI2S() { i2s_config_t config; memset(&config, 0, sizeof(config)); @@ -231,6 +241,8 @@ static void initialiseI2S() i2s_start(); } +} // namespace + void init() { /* diff --git a/samples/Basic_Blink/app/application.cpp b/samples/Basic_Blink/app/application.cpp index 65422d0701..1856c6e5c0 100644 --- a/samples/Basic_Blink/app/application.cpp +++ b/samples/Basic_Blink/app/application.cpp @@ -6,7 +6,7 @@ #define LED_PIN 2 // GPIO2 #endif -Timer procTimer; +SimpleTimer procTimer; bool state = true; void blink() @@ -18,5 +18,5 @@ void blink() void init() { pinMode(LED_PIN, OUTPUT); - procTimer.initializeMs(1000, blink).start(); + procTimer.initializeMs<1000>(blink).start(); } diff --git a/samples/Basic_Capsense/app/application.cpp b/samples/Basic_Capsense/app/application.cpp index 8fcab1a935..8d34b8a55a 100644 --- a/samples/Basic_Capsense/app/application.cpp +++ b/samples/Basic_Capsense/app/application.cpp @@ -7,17 +7,24 @@ // clock speed on the ESP means we need a higher charge current than arduino ?? // Further investigation required. -CapacitiveSensor cs_0_2 = CapacitiveSensor(0, 2); //Send pin 0, Receive Pin 2. +#define PIN_SEND 0 +#define PIN_RECEIVE 2 +#define SAMPLES_TO_READ 30 -Timer procTimer; +namespace +{ +CapacitiveSensor cs_0_2(PIN_SEND, PIN_RECEIVE); +SimpleTimer procTimer; void capsense() { - long total = cs_0_2.capacitiveSensor(30); //Read sensor with 30 samples - Serial << _F("Sense Value: ") << total << endl; // print sensor output + long total = cs_0_2.capacitiveSensor(SAMPLES_TO_READ); + Serial << _F("Sense Value: ") << total << endl; } +} // namespace + void init() { - procTimer.initializeMs(100, capsense).start(); + procTimer.initializeMs<100>(capsense).start(); } diff --git a/samples/Basic_DateTime/app/application.cpp b/samples/Basic_DateTime/app/application.cpp index c941d5354e..b3c42f620c 100644 --- a/samples/Basic_DateTime/app/application.cpp +++ b/samples/Basic_DateTime/app/application.cpp @@ -5,107 +5,123 @@ Prints each type of DateTime::format option */ #include +#include -static time_t timestamp = 0; -static size_t tsLength = 0; - +namespace +{ DEFINE_FSTR_LOCAL(commandPrompt, "Enter Unix timestamp: "); -void showTime(time_t timestamp) +void showTime(const DateTime& dt) { - DateTime dt(timestamp); - //Non-time - Serial.println(dt.format("%%%% Percent sign: %%")); - Serial.println(dt.format("%%n New-line character: %n")); - Serial.println(dt.format("%%t Horizontal-tab character: >|%t|<")); - //Year - Serial.println(dt.format("%%Y Full year (YYYY): %Y")); - Serial.println(dt.format("%%C Year, first two digits (00-99)%: %C")); - Serial.println(dt.format("%%y Year, last two digits (00-99): %y")); - //Month - Serial.println(dt.format("%%B Full month name (e.g. June): %B")); - Serial.println(dt.format("%%b Abbreviated month name (e.g. Jun): %b")); - Serial.println(dt.format("%%h Abbreviated month name (e.g. Jun): %h")); - Serial.println(dt.format("%%m Month as a decimal number (01-12): %m")); - //Week - Serial.println(dt.format("%%U Week number with the first Sunday as the first day of week one (00-53): %U")); //NYI - Serial.println(dt.format("%%W Week number with the first Monday as the first day of week one (00-53): %W")); //NYI - Serial.println(dt.format("%%V ISO 8601 week number (01-53): %V")); //NYI - //Day - Serial.println(dt.format("%%j Day of the year (001-366): %j")); - Serial.println(dt.format("%%d Day of the month, zero-padded (01-31)%: %d")); - Serial.println(dt.format("%%e Day of the month, space-padded ( 1-31): %e")); - Serial.println(dt.format("%%A Full weekday name (e.g. Monday): %A")); - Serial.println(dt.format("%%a Abbreviated weekday name (e.g. Mon): %a")); - Serial.println(dt.format("%%w Weekday as a decimal number with Sunday as 0 (0-6): %w")); - Serial.println(dt.format("%%u ISO 8601 weekday as number with Monday as 1 (1-7): %u")); - //Hour - Serial.println(dt.format("%%p Meridiem (AM|PM): %p")); - Serial.println(dt.format("%%H Hour in 24h format (00-23): %H")); - Serial.println(dt.format("%%h Hour in 12h format (01-12): %I")); - //Minute - Serial.println(dt.format("%%M Minute (00-59): %M")); - //Second - Serial.println(dt.format("%%S Second (00-61): %S")); - //Formatted strings - Serial.println(dt.format("%%R 24-hour time (HH:MM): %R")); - Serial.println(dt.format("%%r 12-hour time (hh:MM:SS AM): %r")); - Serial.println(dt.format("%%c Locale date and time: %c")); - Serial.println(dt.format("%%D US short date (MM/DD/YY): %D")); - Serial.println(dt.format("%%F ISO 8601 date (YYYY-MM-DD): %F")); - Serial.println(dt.format("%%T ISO 8601 time (HH:MM:SS): %T")); - Serial.println(dt.format("%%x Locale date: %x")); - Serial.println(dt.format("%%X Locale time: %X")); - //HTTP date - Serial << "toHTTPDate: " << dt.toHTTPDate() << endl; + auto printFormat = [&dt](const String& fmt, const String& msg) -> void { + Serial << fmt << ' ' << msg << ": " << dt.format(fmt) << endl; + }; + + // Non-time + printFormat("%%", F("Percent sign")); + printFormat("%n", F("New-line character")); + printFormat("|<", F("Horizontal-tab character: >|")); + // Year + printFormat("%Y", F("Full year (YYYY)")); + printFormat("%C", F("Year, first two digits (00-99)")); + printFormat("%y", F("Year, last two digits (00-99)")); + // Month + printFormat("%B", F("Full month name (e.g. June)")); + printFormat("%b", F("Abbreviated month name (e.g. Jun)")); + printFormat("%h", F("Abbreviated month name (e.g. Jun)")); + printFormat("%m", F("Month as a decimal number (01-12)")); + // Week + printFormat("%U", F("Week number with the first Sunday as the first day of week one (00-53)")); + printFormat("%W", F("Week number with the first Monday as the first day of week one (00-53)")); + printFormat("%V", F("ISO 8601 week number (01-53)")); + // Day + printFormat("%j", F("Day of the year (001-366)")); + printFormat("%d", F("Day of the month, zero-padded (01-31)")); + printFormat("%e", F("Day of the month, space-padded ( 1-31)")); + printFormat("%A", F("Full weekday name (e.g. Monday)")); + printFormat("%a", F("Abbreviated weekday name (e.g. Mon)")); + printFormat("%w", F("Weekday as a decimal number with Sunday as 0 (0-6)")); + printFormat("%u", F("ISO 8601 weekday as number with Monday as 1 (1-7)")); + // Hour + printFormat("%p", F("Meridiem (AM|PM)")); + printFormat("%H", F("Hour in 24h format (00-23)")); + printFormat("%I", F("Hour in 12h format (01-12)")); + // Minute + printFormat("%M", F("Minute (00-59)")); + // Second + printFormat("%S", F("Second (00-61)")); + // Formatted strings + printFormat("%R", F("24-hour time (HH:MM)")); + printFormat("%r", F("12-hour time (hh:MM:SS AM)")); + printFormat("%c", F("Locale date and time")); + printFormat("%D", F("US short date (MM/DD/YY)")); + printFormat("%F", F("ISO 8601 date (YYYY-MM-DD)")); + printFormat("%T", F("ISO 8601 time (HH:MM:SS)")); + printFormat("%x", F("Locale date")); + printFormat("%X", F("Locale time")); + + auto print = [](const String& tag, const String& value) { Serial << tag << ": " << value << endl; }; + + // HTTP date + print(F("toHTTPDate"), dt.toHTTPDate()); DateTime dt2; dt2.fromHttpDate(dt.toHTTPDate()); - Serial << "fromHTTPDate: " << dt2.toHTTPDate() << endl; - Serial << "toFullDateTimeString: " << dt.toFullDateTimeString() << endl; - Serial << "toISO8601: " << dt.toISO8601() << endl; - Serial << "toShortDateString: " << dt.toShortDateString() << endl; - Serial << "toShortTimeString: " << dt.toShortTimeString() << endl; + print(F("fromHTTPDate"), dt2.toHTTPDate()); + print(F("toFullDateTimeString"), dt.toFullDateTimeString()); + print(F("toISO8601"), dt.toISO8601()); + print(F("toShortDateString"), dt.toShortDateString()); + print(F("toShortTimeString"), dt.toShortTimeString()); } -void onRx(Stream& source, char arrivedChar, unsigned short availableCharsCount) +void onRx(Stream& source, char, uint16_t) { - switch(arrivedChar) { - case '\n': - Serial.println(); - Serial.println(); - Serial << _F("****Showing DateTime formatting options for Unix timestamp: ") << timestamp << endl; - showTime(timestamp); - Serial.print(commandPrompt); - timestamp = 0; - tsLength = 0; - break; - case '0' ... '9': - timestamp *= 10; - timestamp += arrivedChar - '0'; - ++tsLength; - Serial.print(arrivedChar); - break; - case '\b': - if(tsLength) { - Serial.print('\b'); - Serial.print(" "); - Serial.print('\b'); - --tsLength; - timestamp /= 10; + static LineBuffer<32> buffer; + + using Action = LineBufferBase::Action; + switch(buffer.process(source, Serial)) { + case Action::submit: { + if(!buffer) { + break; + } + String s(buffer); + buffer.clear(); + char* p; + time_t timestamp = strtoll(s.c_str(), &p, 0); + if(p == s.end()) { + Serial << endl << _F("****Showing DateTime formatting options for Unix timestamp: ") << timestamp << endl; + showTime(timestamp); + break; + } + + DateTime dt; + if(dt.fromHttpDate(s)) { + Serial << endl << _F("****Showing DateTime formatting options for Http time: ") << s << endl; + showTime(dt); + break; + } + + if(dt.fromISO8601(s)) { + Serial << endl << _F("****Showing DateTime formatting options for ISO8601 date/time: ") << s << endl; + showTime(dt); + break; } + + Serial << endl << _F("Please enter a valid numeric timestamp, HTTP or ISO8601 date/time string!") << endl; break; - case 27: - timestamp = 0; - tsLength = 0; - Serial.print('\r'); - Serial.print(_F(" ")); - Serial.print('\r'); - Serial.print(commandPrompt); + } + + case Action::clear: break; + + default:; + return; } - m_puts("\r\n"); + + Serial.print(commandPrompt); } +} // namespace + void init() { Serial.begin(COM_SPEED_SERIAL); diff --git a/samples/Basic_DateTime/component.mk b/samples/Basic_DateTime/component.mk index 250bb9a77d..5c4d4e7499 100644 --- a/samples/Basic_DateTime/component.mk +++ b/samples/Basic_DateTime/component.mk @@ -1,3 +1 @@ -# Emulate UART 0 -ENABLE_HOST_UARTID := 0 DISABLE_NETWORK := 1 diff --git a/samples/Basic_HwPWM/app/application.cpp b/samples/Basic_HwPWM/app/application.cpp index e04e7d050a..b1c29c4784 100644 --- a/samples/Basic_HwPWM/app/application.cpp +++ b/samples/Basic_HwPWM/app/application.cpp @@ -18,34 +18,46 @@ #include #include -uint8_t pins[8] = {4, 5, 0, 2, 15, 13, 12, 14}; // List of pins that you want to connect to pwm -HardwarePWM HW_pwm(pins, 8); +#define LED_PIN 2 -Timer procTimer; -int32 i = 0; -bool countUp = true; +namespace +{ +// List of pins that you want to connect to pwm +uint8_t pins[]{ + LED_PIN, 4, 5, 0, 15, 13, 12, 14, +}; +HardwarePWM HW_pwm(pins, ARRAY_SIZE(pins)); + +SimpleTimer procTimer; -int maxDuty = HW_pwm.getMaxDuty(); -int32 inc = maxDuty / 50; +const int maxDuty = HW_pwm.getMaxDuty(); void doPWM() { - if(countUp == true) { - i += inc; - if(i >= maxDuty) { - i = maxDuty; + static bool countUp = true; + static int duty; + + const int increment = maxDuty / 50; + + if(countUp) { + duty += increment; + if(duty >= maxDuty) { + duty = maxDuty; countUp = false; } } else { - i -= inc; - if(i <= 0) { - i = 0; + duty -= increment; + if(duty <= 0) { + duty = 0; countUp = true; } } - HW_pwm.analogWrite(2, i); + + HW_pwm.analogWrite(LED_PIN, duty); } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); // 115200 by default @@ -67,7 +79,7 @@ void init() HW_pwm.analogWrite(12, 2 * maxDuty / 3); HW_pwm.analogWrite(14, maxDuty); - debugf("PWM output set on all 8 Pins. Kindly check..."); - debugf("Now Pin 2 will go from 0 to VCC to 0 in cycles."); - procTimer.initializeMs(100, doPWM).start(); + Serial.println(_F("PWM output set on all 8 Pins. Kindly check...\r\n" + "Now LED_PIN will go from 0 to VCC to 0 in cycles.")); + procTimer.initializeMs<100>(doPWM).start(); } diff --git a/samples/Basic_HwPWM/component.mk b/samples/Basic_HwPWM/component.mk index ec78f78162..be6ff9c63a 100644 --- a/samples/Basic_HwPWM/component.mk +++ b/samples/Basic_HwPWM/component.mk @@ -1,4 +1,5 @@ COMPONENT_SOC := esp8266 +DISABLE_NETWORK := 1 # Uncomment the line below if you want to use Espressif's PWM library. #ENABLE_CUSTOM_PWM=0 diff --git a/samples/Basic_IFS/app/application.cpp b/samples/Basic_IFS/app/application.cpp index 5bdfc2787a..7f8b01064f 100644 --- a/samples/Basic_IFS/app/application.cpp +++ b/samples/Basic_IFS/app/application.cpp @@ -54,6 +54,8 @@ IMPORT_FSTR(listing_json, PROJECT_DIR "/resource/listing.json") HttpServer server; FtpServer ftp; int requestCount; +Profiling::TaskStat taskStat(Serial); +SimpleTimer statTimer; /* * Handle any custom fields here @@ -76,7 +78,7 @@ void onFile(HttpRequest& request, HttpResponse& response) ++requestCount; String file = request.uri.getRelativePath(); - String fmt = request.uri.Query["format"]; + String fmt = request.uri.getQueryParameter("format"); if(dirExist(file)) { if(fmt.equalsIgnoreCase("archive")) { @@ -465,9 +467,6 @@ void fstest() listAttributes(); } -Profiling::TaskStat taskStat(Serial); -Timer statTimer; - } // namespace void init() @@ -489,6 +488,6 @@ void init() WifiEvents.onStationGotIP(gotIP); - statTimer.initializeMs<2000>(InterruptCallback([]() { taskStat.update(); })); + statTimer.initializeMs<2000>([]() { taskStat.update(); }); statTimer.start(); } diff --git a/samples/Basic_IFS/basic_ifs.usbcfg b/samples/Basic_IFS/basic_ifs.usbcfg index 60dfe5cc7e..bb6d4a335e 100644 --- a/samples/Basic_IFS/basic_ifs.usbcfg +++ b/samples/Basic_IFS/basic_ifs.usbcfg @@ -1,5 +1,10 @@ { "host": { - "msc": 1 + "hub": { + "port-count": 4 + }, + "msc": { + "maxlun": 4 + } } } \ No newline at end of file diff --git a/samples/Basic_IFS/basic_ifs_Esp32.hw b/samples/Basic_IFS/basic_ifs_Esp32.hw index 3f3f6e9c17..60bec7563b 100644 --- a/samples/Basic_IFS/basic_ifs_Esp32.hw +++ b/samples/Basic_IFS/basic_ifs_Esp32.hw @@ -1,4 +1,5 @@ { + "name": "Basic IFS sample (ESP32)", "base_config": "basic_ifs", "arch": "Esp32", "partitions": { diff --git a/samples/Basic_IFS/basic_ifs_Esp8266.hw b/samples/Basic_IFS/basic_ifs_Esp8266.hw index 301edd0a72..ab5c5fb119 100644 --- a/samples/Basic_IFS/basic_ifs_Esp8266.hw +++ b/samples/Basic_IFS/basic_ifs_Esp8266.hw @@ -1,4 +1,5 @@ { + "name": "Basic IFS (ESP8266)", "base_config": "basic_ifs", "arch": "Esp8266", "partitions": { diff --git a/samples/Basic_IFS/basic_ifs_Host.hw b/samples/Basic_IFS/basic_ifs_Host.hw index 7b6468d01a..26fe7a3313 100644 --- a/samples/Basic_IFS/basic_ifs_Host.hw +++ b/samples/Basic_IFS/basic_ifs_Host.hw @@ -1,4 +1,5 @@ { + "name": "Basic IFS (HOST)", "base_config": "basic_ifs", "arch": "Host", "partitions": { diff --git a/samples/Basic_IFS/basic_ifs_Rp2040.hw b/samples/Basic_IFS/basic_ifs_Rp2040.hw index a63a50ea25..004bc45534 100644 --- a/samples/Basic_IFS/basic_ifs_Rp2040.hw +++ b/samples/Basic_IFS/basic_ifs_Rp2040.hw @@ -1,7 +1,7 @@ { - "name": "Rp2040 config", - "arch": "Rp2040", + "name": "Basic IFS sample (RP2040)", "base_config": "basic_ifs", + "arch": "Rp2040", "options": [ "2m", "cyw43_fw" diff --git a/samples/Basic_IFS/component.mk b/samples/Basic_IFS/component.mk index 33da075365..f14a80567c 100644 --- a/samples/Basic_IFS/component.mk +++ b/samples/Basic_IFS/component.mk @@ -24,7 +24,7 @@ endif CONFIG_VARS += ENABLE_USB_STORAGE ifeq ($(ENABLE_USB_STORAGE),1) COMPONENT_CXXFLAGS += -DENABLE_USB_STORAGE -COMPONENT_DEPENDS += USB +COMPONENT_DEPENDS += USB FatIFS USB_CONFIG := basic_ifs.usbcfg endif diff --git a/samples/Basic_NFC/app/application.cpp b/samples/Basic_NFC/app/application.cpp index 9d532ec4bd..1ecaba08bc 100644 --- a/samples/Basic_NFC/app/application.cpp +++ b/samples/Basic_NFC/app/application.cpp @@ -1,69 +1,56 @@ #include #include -Timer procTimer; -static Timer nfcScanTimer; -int helloCounter = 0; +#define SS_PIN 4 // D2 + +namespace +{ +SimpleTimer procTimer; -void scanNfc(byte scanner); +MFRC522 mfrc522(SS_PIN, SS_PIN); -#define SS_PIN 4 // D2 +// List of pins where NFC devices may be connected +const uint8_t ss_pin[]{4, 15}; -MFRC522 mfrc522(SS_PIN, SS_PIN); // Create MFRC522 instance -byte ss_pin[] = {4, 15}; +void scanNfc(uint8_t scanner); void sayHello() { - for(int pinNdx = 0; pinNdx < 2; pinNdx++) { - byte pin = ss_pin[pinNdx]; + for(auto pin : ss_pin) { mfrc522.setControlPins(pin, pin); - mfrc522.PCD_Init(); // Init MFRC522 + mfrc522.PCD_Init(); scanNfc(pin); } } -//--------------------------------- -static void dump_byte_array(byte* buffer, byte bufferSize) -{ - String hexOut; - for(byte i = 0; i < bufferSize; i++) { - hexOut += String(buffer[i], HEX); - } - debugf("%s", hexOut.c_str()); -} -//--------------------------------- -void scanNfc(byte scanner) + +void scanNfc(uint8_t scannerPin) { if(!mfrc522.PICC_IsNewCardPresent()) { - debugf("Scanning nfc Scanner:%d \r\n", scanner); + Serial << _F("Scanning NFC pin #") << scannerPin << _F(" not present") << endl; return; } - if(!mfrc522.PICC_ReadCardSerial()) { // Select one of the cards - debugf("Selecting card failed..."); + // Select one of the cards + if(!mfrc522.PICC_ReadCardSerial()) { + Serial << _F("Selecting card #") << scannerPin << _F(" failed...") << endl; } else { // Show some details of the PICC (that is: the tag/card) - debugf("Card UID on scanner:%d:", scanner); - dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size); - debugf(); + Serial << _F("Card UID on scanner: ") << scannerPin << endl; + m_printHex("UID", mfrc522.uid.uidByte, mfrc522.uid.size); } + mfrc522.PICC_HaltA(); + // Stop encryption on PCD mfrc522.PCD_StopCrypto1(); - mfrc522.PCD_Init(); // Init MFRC522 - - //nfcScanTimer.restart(); + mfrc522.PCD_Init(); } +} // namespace + void init() { - Serial.begin(SERIAL_BAUD_RATE); // 115200 by default - - procTimer.initializeMs(2000, sayHello).start(); - - //----- NFC - MFRC522 mfrc522(SS_PIN, SS_PIN); - SPI.begin(); - mfrc522.PCD_Init(); // Init MFRC522 + Serial.begin(SERIAL_BAUD_RATE); - //nfcScanTimer.initializeMs(50, scanNfc).startOnce(); + procTimer.initializeMs<2000>(sayHello).start(); } diff --git a/samples/Basic_Neopixel/app/application.cpp b/samples/Basic_Neopixel/app/application.cpp index 82a6a11f3f..86f5a1b6b8 100644 --- a/samples/Basic_Neopixel/app/application.cpp +++ b/samples/Basic_Neopixel/app/application.cpp @@ -13,71 +13,96 @@ // How many NeoPixels are attached to the Esp8266? #define NUMPIXELS 16 -Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); - -void StartDemo(void); - -Timer StripDemoTimer; -Timer ColorWipeTimer; -Timer TheaterChaseTimer; - -int StripDemoType = 0; -int StripColor = 0; -int StripNo = 0; -int ChaseCycle = 0; -int TheaterChaseQ = 0; +namespace +{ +Adafruit_NeoPixel strip(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); + +void startDemo(); + +SimpleTimer timer; +uint32_t stripColor; +uint8_t stripDemoType; // Defined by demoData below +uint8_t chaseCycle; + +enum ColorMap { + CLR_BLACK = 0x000000, + CLR_RED = 0xff0000, + CLR_GREEN = 0x00ff00, + CLR_BLUE = 0x0000ff, + CLR_DIM_WHITE = 0x7f7f7f, + CLR_DIM_RED = 0x7f0000, + CLR_DIM_BLUE = 0x00007f, +}; + +struct DemoData { + uint32_t color; + uint16_t stepMilliseconds; + uint8_t chase; +}; + +const DemoData demoData[]{ + {CLR_BLACK, 50, 0}, // 0 + {CLR_RED, 50, 0}, // 1 + {CLR_GREEN, 100, 0}, // 2 + {CLR_BLUE, 150, 0}, // 3 + {CLR_BLACK, 50, 0}, // 4 + {CLR_DIM_WHITE, 50, 10}, // 5 + {CLR_DIM_RED, 60, 15}, // 6 + {CLR_DIM_BLUE, 70, 20}, // 7 +}; // // Fill the dots one after the other with a color +// Timer callback // - -void ColorWipe() +void colorWipe() { - if(StripNo < strip.numPixels()) { - strip.setPixelColor(StripNo, StripColor); - strip.show(); - StripNo++; - } else { - StripDemoType++; // next demo type - ColorWipeTimer.stop(); // stop this demo timer - StripDemoTimer.initializeMs(2000, StartDemo).start(true); // start next demo after 2 seconds + static uint16_t stripNumber; + + if(stripNumber >= strip.numPixels()) { + stripNumber = 0; + // start next demo after 2 seconds + stripDemoType++; + timer.initializeMs<2000>(startDemo).startOnce(); + return; } + + strip.setPixelColor(stripNumber, stripColor); + strip.show(); + ++stripNumber; } // -//Theatre-style crawling lights. -//Timer callback - -void TheaterChase() +// Theatre-style crawling lights +// Timer callback +// +void theatreChase() { - int i, b = 0; - if(ChaseCycle > 0) { - if(TheaterChaseQ == 0) - b = 3; - if(TheaterChaseQ == 1) - b = 0; - if(TheaterChaseQ == 2) - b = 1; - if(TheaterChaseQ == 3) - b = 2; - - for(i = 0; i < strip.numPixels(); i = i + 4) - strip.setPixelColor(i + b, 0); //turn prev every third pixel off - - for(i = 0; i < strip.numPixels(); i = i + 4) - strip.setPixelColor(i + TheaterChaseQ, StripColor); //turn every third pixel on - - strip.show(); - TheaterChaseQ++; - if(TheaterChaseQ > 3) { - TheaterChaseQ = 0; - ChaseCycle--; - } - } else { - // finish this demo - StripDemoType++; // next demo type - TheaterChaseTimer.stop(); // stop this demo dimer - StripDemoTimer.initializeMs(2000, StartDemo).start(true); // start another demo after 2 seconds + static uint8_t theatreChaseQ; + + if(chaseCycle <= 0) { + assert(theatreChaseQ == 0); + // start another demo after 2 seconds + stripDemoType++; + timer.initializeMs<2000>(startDemo).startOnce(); + return; + } + + const uint8_t offsetList[]{3, 0, 1, 2}; + int b = offsetList[theatreChaseQ]; + + // Turn every third pixel off + for(unsigned i = 0; i < strip.numPixels(); i += 4) { + strip.setPixelColor(i + b, 0); + strip.setPixelColor(i + theatreChaseQ, stripColor); + } + + strip.show(); + + ++theatreChaseQ; + if(theatreChaseQ > 3) { + theatreChaseQ = 0; + --chaseCycle; } } @@ -85,71 +110,38 @@ void TheaterChase() // Demo timer callback // -void StartDemo() +void startDemo() { - Serial << _F("NeoPixel Demo type: ") << StripDemoType << endl; - - StripDemoTimer.stop(); // next demo wait until this demo ends - - StripNo = 0; //start from led index 0 - TheaterChaseQ = 0; //another counter - - switch(StripDemoType) { // select demo type - case 0: - StripColor = strip.Color(0, 0, 0); // black - ColorWipeTimer.initializeMs(50, ColorWipe).start(true); // 50 ms step - break; - case 1: - StripColor = strip.Color(255, 0, 0); // Red - ColorWipeTimer.initializeMs(50, ColorWipe).start(true); // 50 ms step - break; - case 2: - StripColor = strip.Color(0, 255, 0); // Green - ColorWipeTimer.initializeMs(100, ColorWipe).start(true); // 100 ms step - break; - case 3: - StripColor = strip.Color(0, 0, 255); // Blue - ColorWipeTimer.initializeMs(150, ColorWipe).start(true); // 150 ms step - break; - case 4: - StripColor = strip.Color(0, 0, 0); // black - ColorWipeTimer.initializeMs(50, ColorWipe).start(true); // 50 ms step - break; - - case 5: - ChaseCycle = 10; //do 10 cycles of chasing - StripColor = strip.Color(127, 127, 127); // White - TheaterChaseTimer.initializeMs(50, TheaterChase).start(true); // 50 ms step - break; - case 6: - ChaseCycle = 15; //do 15 cycles of chasing - StripColor = strip.Color(127, 0, 0); // Red - TheaterChaseTimer.initializeMs(60, TheaterChase).start(true); // 60 ms step - break; - case 7: - ChaseCycle = 20; //do 20 cycles of chasing - StripColor = strip.Color(0, 0, 127); // Blue - TheaterChaseTimer.initializeMs(70, TheaterChase).start(true); // 70 ms step - break; - - default: - StripDemoType = 0; - StripDemoTimer.initializeMs(1000, StartDemo).start(true); //demo loop restart - break; + Serial << _F("NeoPixel Demo type: ") << stripDemoType << endl; + + if(stripDemoType >= ARRAY_SIZE(demoData)) { + // Demo loop restart + stripDemoType = 0; + timer.initializeMs<1000>(startDemo).start(); + return; } + + auto& data = demoData[stripDemoType]; + chaseCycle = data.chase; + stripColor = data.color; + timer.initializeMs(data.stepMilliseconds, chaseCycle ? theatreChase : colorWipe).start(); } -void got_IP(IpAddress ip, IpAddress netmask, IpAddress gateway) +#ifndef DISABLE_WIFI +void gotIp(IpAddress ip, IpAddress netmask, IpAddress gateway) { Serial << "IP: " << ip << endl; // You can put here other job like web,tcp etc. } // Will be called when WiFi station loses connection -void connect_Fail(const String& ssid, MacAddress bssid, WifiDisconnectReason reason) +void connectFail(const String& ssid, MacAddress bssid, WifiDisconnectReason reason) { Serial.println(_F("I'm NOT CONNECTED!")); } +#endif + +} // namespace void init() { @@ -165,13 +157,12 @@ void init() WifiStation.config(WIFI_SSID, WIFI_PWD); WifiStation.enable(true); WifiAccessPoint.enable(false); - WifiEvents.onStationDisconnect(connect_Fail); - WifiEvents.onStationGotIP(got_IP); + WifiEvents.onStationDisconnect(connectFail); + WifiEvents.onStationGotIP(gotIp); #endif - StripDemoType = 0; //demo index to be displayed - - strip.begin(); //init port + stripDemoType = 0; + strip.begin(); - StripDemoTimer.initializeMs(1000, StartDemo).start(); //start demo + timer.initializeMs<1000>(startDemo).start(); } diff --git a/samples/Basic_Ota/README.rst b/samples/Basic_Ota/README.rst index 5cdec1dd46..76d1bb11a7 100644 --- a/samples/Basic_Ota/README.rst +++ b/samples/Basic_Ota/README.rst @@ -14,8 +14,8 @@ Esp8266 ~~~~~~~ On Esp8266 we use rBoot as bootloader. When using rBoot big flash support with multiple 1MB slots only one rom -image needs to be created. If you don’t want to use big flash support -(e.g. for a device with smaller flash) see the separate instructions +image needs to be created. If you don't want to use big flash support +(e.g. for a device with smaller flash) see the separate instructions below. You can easily take the ota files and add them to your own project to add OTA support. @@ -55,7 +55,7 @@ roms. If you are flashing a single rom to multiple 1MB flash blocks, all using the same offset inside their 1MB blocks, only a single rom is created. See :component:`rboot` for further details. -- If using a very small flash (e.g. 512k) there may be no room for a +- If using a very small flash (e.g. 512k) there may be no room for a spiffs filesystem, so use *HWCONFIG = standard* - After building copy all the rom*.bin files to the root of your web server. diff --git a/samples/Basic_Ota/app/application.cpp b/samples/Basic_Ota/app/application.cpp index 8b446c70b6..f4b7723177 100644 --- a/samples/Basic_Ota/app/application.cpp +++ b/samples/Basic_Ota/app/application.cpp @@ -3,6 +3,7 @@ #include #include #include +#include // If you want, you can define WiFi settings globally in Eclipse Environment Variables #ifndef WIFI_SSID @@ -10,9 +11,12 @@ #define WIFI_PWD "PleaseEnterPass" #endif +namespace +{ std::unique_ptr otaUpdater; Storage::Partition spiffsPartition; OtaUpgrader ota; +LineBuffer<16> commandBuffer; Storage::Partition findSpiffsPartition(Storage::Partition appPart) { @@ -25,7 +29,7 @@ Storage::Partition findSpiffsPartition(Storage::Partition appPart) return part; } -void upgradeCallback(Ota::Network::HttpUpgrader& client, bool result) +void upgradeCallback(Ota::Network::HttpUpgrader&, bool result) { Serial.println(_F("In callback...")); if(result == true) { @@ -49,11 +53,21 @@ void doUpgrade() Serial.println(F("Updating...")); // need a clean object, otherwise if run before and failed will not run again - otaUpdater.reset(new Ota::Network::HttpUpgrader); + otaUpdater = std::make_unique(); // select rom slot to flash auto part = ota.getNextBootPartition(); + /* + * Applications should always include a sanity check to ensure partitions being updated are + * not in use. This should always included the application partition but should also consider + * filing system partitions, etc. which may be actively in use. + */ + if(part == ota.getRunningPartition()) { + Serial << F("May be running in temporary mode. Please reboot and try again.") << endl; + return; + } + #ifndef RBOOT_TWO_ROMS // flash rom to position indicated in the rBoot config rom table otaUpdater->addItem(ROM_0_URL, part); @@ -67,7 +81,8 @@ void doUpgrade() auto spiffsPart = findSpiffsPartition(part); if(spiffsPart) { // use user supplied values (defaults for 4mb flash in hardware config) - otaUpdater->addItem(SPIFFS_URL, spiffsPart, new Storage::PartitionStream(spiffsPart)); + otaUpdater->addItem(SPIFFS_URL, spiffsPart, + new Storage::PartitionStream(spiffsPart, Storage::Mode::BlockErase)); } // request switch and reboot on success @@ -111,76 +126,114 @@ void showInfo() << " @ 0x" << String(after.address(), HEX) << endl; } -void serialCallBack(Stream& stream, char arrivedChar, unsigned short availableCharsCount) +void showPrompt() { - int pos = stream.indexOf('\n'); - if(pos > -1) { - char str[pos + 1]; - for(int i = 0; i < pos + 1; i++) { - str[i] = stream.read(); - if(str[i] == '\r' || str[i] == '\n') { - str[i] = '\0'; + Serial << _F("OTA> ") << commandBuffer; +} + +void handleCommand(const String& str) +{ + if(F("connect") == str) { + Serial << _F("Connecting to '") << WIFI_SSID << "'..." << endl; + WifiStation.config(WIFI_SSID, WIFI_PWD); + WifiStation.enable(true); + WifiStation.connect(); + return; + } + + if(F("ip") == str) { + Serial << "ip: " << WifiStation.getIP() << ", mac: " << WifiStation.getMacAddress() << endl; + return; + } + + if(F("ota") == str) { + doUpgrade(); + return; + } + + if(F("switch") == str) { + doSwitch(); + return; + } + + if(F("restart") == str) { + System.restart(); + return; + } + + if(F("ls") == str) { + Directory dir; + if(dir.open()) { + while(dir.next()) { + Serial << " " << dir.stat().name << endl; } } + Serial << _F("filecount ") << dir.count() << endl; + return; + } - if(F("connect") == str) { - // connect to wifi - WifiStation.config(WIFI_SSID, WIFI_PWD); - WifiStation.enable(true); - WifiStation.connect(); - } else if(F("ip") == str) { - Serial << "ip: " << WifiStation.getIP() << ", mac: " << WifiStation.getMacAddress() << endl; - } else if(F("ota") == str) { - doUpgrade(); - } else if(F("switch") == str) { - doSwitch(); - } else if(F("restart") == str) { - System.restart(); - } else if(F("ls") == str) { - Directory dir; - if(dir.open()) { - while(dir.next()) { - Serial << " " << dir.stat().name << endl; - } - } - Serial << _F("filecount ") << dir.count() << endl; - } else if(F("cat") == str) { - Directory dir; - if(dir.open() && dir.next()) { - auto filename = dir.stat().name.c_str(); - Serial << "dumping file " << filename << ": " << endl; - // We don't know how big the is, so streaming it is safest - FileStream fs; - fs.open(filename); - Serial.copyFrom(&fs); - Serial.println(); - } else { - Serial.println(F("Empty spiffs!")); - } - } else if(F("info") == str) { - showInfo(); - } else if(F("help") == str) { - Serial.print(_F("\r\n" - "available commands:\r\n" - " help - display this message\r\n" - " ip - show current ip address\r\n" - " connect - connect to wifi\r\n" - " restart - restart the device\r\n" - " switch - switch to the other rom and reboot\r\n" - " ota - perform ota update, switch rom and reboot\r\n" - " info - show device info\r\n")); - - if(spiffsPartition) { - Serial.print(_F(" ls - list files in spiffs\r\n" - " cat - show first file in spiffs\r\n")); - } + if(F("cat") == str) { + Directory dir; + if(dir.open() && dir.next()) { + auto filename = dir.stat().name.c_str(); + Serial << "dumping file " << filename << ": " << endl; + // We don't know how big the is, so streaming it is safest + FileStream fs; + fs.open(filename); + Serial.copyFrom(&fs); Serial.println(); } else { - Serial.println("unknown command"); + Serial.println(F("Empty spiffs!")); + } + return; + } + + if(F("info") == str) { + showInfo(); + return; + } + + if(F("help") == str) { + Serial.print(_F("\r\n" + "available commands:\r\n" + " help - display this message\r\n" + " ip - show current ip address\r\n" + " connect - connect to wifi\r\n" + " restart - restart the device\r\n" + " switch - switch to the other rom and reboot\r\n" + " ota - perform ota update, switch rom and reboot\r\n" + " info - show device info\r\n")); + + if(spiffsPartition) { + Serial.print(_F(" ls - list files in spiffs\r\n" + " cat - show first file in spiffs\r\n")); } + Serial.println(); + return; + } + + Serial << _F("unknown command: ") << str << endl; +} + +void serialCallBack(Stream& stream, char, uint16_t) +{ + switch(commandBuffer.process(stream, Serial)) { + case LineBufferBase::Action::submit: + if(commandBuffer) { + handleCommand(String(commandBuffer)); + commandBuffer.clear(); + } + showPrompt(); + break; + case LineBufferBase::Action::clear: + showPrompt(); + break; + default:; } } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); // 115200 by default @@ -196,10 +249,14 @@ void init() } WifiAccessPoint.enable(false); + WifiEvents.onStationGotIP([](IpAddress ip, IpAddress netmask, IpAddress gateway) { showPrompt(); }); - Serial << _F("\r\nCurrently running ") << partition.name() << " @ 0x" << String(partition.address(), HEX) << '.' + Serial << endl + << _F("Currently running ") << partition.name() << " @ 0x" << String(partition.address(), HEX) << '.' << endl + << _F("Type 'help' and press enter for instructions.") << endl << endl; - Serial << _F("Type 'help' and press enter for instructions.") << endl << endl; + + showPrompt(); Serial.onDataReceived(serialCallBack); } diff --git a/samples/Basic_Ota/component.mk b/samples/Basic_Ota/component.mk index b46c243c8c..b6f8b1d241 100644 --- a/samples/Basic_Ota/component.mk +++ b/samples/Basic_Ota/component.mk @@ -1,4 +1,4 @@ -COMPONENT_SOC := esp* +COMPONENT_SOC := esp* host COMPONENT_DEPENDS := OtaNetwork HWCONFIG := ota diff --git a/samples/Basic_Ota/ota.hw b/samples/Basic_Ota/ota.hw index a6a64f6186..ed59f038c9 100644 --- a/samples/Basic_Ota/ota.hw +++ b/samples/Basic_Ota/ota.hw @@ -1,4 +1,5 @@ { + "name": "Basic OTA sample", "base_config": "spiffs-two-roms", "partitions": { "rom0": { diff --git a/samples/Basic_ProgMem/app/TestProgmem.cpp b/samples/Basic_ProgMem/app/TestProgmem.cpp index aac4f916b1..fe86770329 100644 --- a/samples/Basic_ProgMem/app/TestProgmem.cpp +++ b/samples/Basic_ProgMem/app/TestProgmem.cpp @@ -49,7 +49,10 @@ void testPSTR(Print& out) // Note that characters after first nul won't be shown ... out.print("> demoPSTR1 (print char*): "); - out << '"' << _FLOAD(demoPSTR1) << '"' << endl; + { + LOAD_PSTR(s, demoPSTR1) + out << '"' << s << '"' << endl; + } // ... now they will: note buf will be aligned up to next dword boundary though out.print("> demoPSTR1 (write): "); @@ -131,7 +134,10 @@ void testFSTR(Print& out) // Test equality operators #define TEST(_test) out.printf(_F("%s: %s\n"), (_test) ? _F("PASS") : _F("FAIL"), _F(#_test)); TEST(demoFSTR1 == demoFSTR2) - TEST(demoFSTR1 != _FLOAD(demoPSTR1)) + { + LOAD_PSTR(s, demoPSTR1); + TEST(demoFSTR1 != s) + } TEST(String(demoFSTR1) == demoFSTR2) TEST(demoFSTR1 == String(demoFSTR2)) #undef TEST @@ -161,50 +167,54 @@ void testSpeed(Print& out) out.printf("Speed tests, %u iterations, times in microseconds\n", iterations); ElapseTimer timer; - unsigned tmp = 0; uint32_t baseline, elapsed; _FPUTS("Baseline test, read string in RAM..."); + unsigned sum = 0; timer.start(); for(unsigned i = 0; i < iterations; ++i) { - tmp += sumBuffer(demoText, sizeof(demoText)); + sum += sumBuffer(demoText, sizeof(demoText)); } baseline = timer.elapsedTime(); - out << "Elapsed: " << baseline << endl; + out << "Elapsed: " << baseline << ", sum " << sum << endl; #define END() \ elapsed = timer.elapsedTime(); \ - out << "Elapsed: " << elapsed << " (baseline + " << elapsed - baseline << ')' << endl; + out << "Elapsed: " << elapsed << " (baseline + " << elapsed - baseline << "), sum " << sum << endl; _FPUTS("Load PSTR into stack buffer..."); + sum = 0; timer.start(); for(unsigned i = 0; i < iterations; ++i) { LOAD_PSTR(buf, demoPSTR1); - tmp += sumBuffer(buf, sizeof(buf)); + sum += sumBuffer(buf, sizeof(buf)); } END() _FPUTS("Load PSTR into String..."); + sum = 0; timer.start(); for(unsigned i = 0; i < iterations; ++i) { String s(demoFSTR1.data()); - tmp += sumBuffer(s.c_str(), s.length() + 1); + sum += sumBuffer(s.c_str(), s.length() + 1); } END() _FPUTS("Load FlashString into stack buffer..."); + sum = 0; timer.start(); for(unsigned i = 0; i < iterations; ++i) { LOAD_FSTR(buf, demoFSTR1); - tmp += sumBuffer(buf, sizeof(buf)); + sum += sumBuffer(buf, sizeof(buf)); } END() _FPUTS("Load FlashString into String..."); + sum = 0; timer.start(); for(unsigned i = 0; i < iterations; ++i) { String s(demoFSTR1); - tmp += sumBuffer(s.c_str(), s.length() + 1); + sum += sumBuffer(s.c_str(), s.length() + 1); } END() } diff --git a/samples/Basic_ProgMem/app/application.cpp b/samples/Basic_ProgMem/app/application.cpp index 498cdf68ef..8bccf27b0d 100644 --- a/samples/Basic_ProgMem/app/application.cpp +++ b/samples/Basic_ProgMem/app/application.cpp @@ -16,7 +16,6 @@ const uint8_t demoRam[] = {1, 2, 3, 4, 5}; const PROGMEM uint8_t demoPgm[] = {1, 2, 3, 4, 5}; const PROGMEM char demoString[] = "Demo"; -const PROGMEM char demoString2[] = "Demo"; const PROGMEM char demoFormat[] = "Demo %d"; const PROGMEM uint8_t bytes[] = {1, 2, 3, 4, 5, 6, 7, 8}; @@ -120,6 +119,6 @@ void init() Serial.println("> 0x3FFE8000 ~ 0x3FFFBFFF - User data RAM, 80kb. Available to applications."); Serial.println("> 0x40200000 ~ ... - SPI Flash."); - Serial << "> demoRam array address: 0x" << String(uint32_t(demoRam), HEX) << " is in the RAM" << endl; - Serial << "> demoPgm array address: 0x" << String(uint32_t(demoPgm), HEX) << " is in the Flash" << endl; + Serial << "> demoRam array address: 0x" << String(uintptr_t(demoRam), HEX) << " is in the RAM" << endl; + Serial << "> demoPgm array address: 0x" << String(uintptr_t(demoPgm), HEX) << " is in the Flash" << endl; } diff --git a/samples/Basic_ScannerI2C/app/application.cpp b/samples/Basic_ScannerI2C/app/application.cpp index 81ecd50d4f..c155894ac7 100644 --- a/samples/Basic_ScannerI2C/app/application.cpp +++ b/samples/Basic_ScannerI2C/app/application.cpp @@ -29,22 +29,22 @@ #include -Timer procTimer; +namespace +{ +SimpleTimer procTimer; +} void scanBus() { - byte error, address; - int nDevices; - Serial.println("Scanning..."); - nDevices = 0; - for(address = 1; address < 127; address++) { + unsigned nDevices{0}; + for(uint8_t address = 1; address < 127; address++) { // The i2c_scanner uses the return value of // the Write.endTransmisstion to see if // a device did acknowledge to the address. Wire.beginTransmission(address); - error = Wire.endTransmission(); + auto error = Wire.endTransmission(); WDT.alive(); // Second option: notify Watch Dog what you are alive (feed it) @@ -55,11 +55,8 @@ void scanBus() Serial << _F("Unknown error at address 0x") << String(address, HEX, 2) << endl; } } - if(nDevices == 0) { - Serial.println("No I2C devices found\n"); - } else { - Serial.println("done\n"); - } + + Serial << nDevices << _F(" I2C devices found.") << endl << endl; } void init() @@ -75,5 +72,5 @@ void init() //Wire.pins(14, 12); // SDA, SCL Wire.begin(); - procTimer.initializeMs(3000, scanBus).start(); + procTimer.initializeMs<3000>(scanBus).start(); } diff --git a/samples/Basic_Serial/app/SerialReadingDelegateDemo.cpp b/samples/Basic_Serial/app/SerialReadingDelegateDemo.cpp index 4e9b346b9e..3e73508fac 100644 --- a/samples/Basic_Serial/app/SerialReadingDelegateDemo.cpp +++ b/samples/Basic_Serial/app/SerialReadingDelegateDemo.cpp @@ -50,6 +50,11 @@ void SerialReadingDelegateDemo::onData(Stream& stream, char arrivedChar, unsigne numCallback++; + /* + * A more functional serial command-line interface can be implemented using the `LineBuffer` class. + * See `Basic_DateTime` sample application for a demonstration. + */ + if(arrivedChar == '\n') // Lets show data! { serial->println(_F("")); diff --git a/samples/Basic_Serial/app/application.cpp b/samples/Basic_Serial/app/application.cpp index 0faceff2a4..a33a47bf68 100644 --- a/samples/Basic_Serial/app/application.cpp +++ b/samples/Basic_Serial/app/application.cpp @@ -5,6 +5,8 @@ #include "SerialReadingDelegateDemo.h" #include "SerialTransmitDemo.h" +namespace +{ struct SerialPins { uint8_t tx; uint8_t rx; @@ -128,9 +130,9 @@ DEFINE_FSTR(testFlashData, "The following are the graphical (non-control) charac "\r\n" "END OF TEXT\r\n"); -Timer procTimer; +SimpleTimer procTimer; SerialReadingDelegateDemo delegateDemoClass; -int helloCounter = 0; +int helloCounter; /** * Serial1 uses UART1, TX pin is GPIO2. @@ -229,6 +231,8 @@ void handleCommand(const String& command) } } +} // namespace + void init() { /* @@ -312,7 +316,7 @@ void init() debugf("(DEBUG) message printed on UART1"); // You should see the debug message in UART1 only. - procTimer.initializeMs(2000, sayHello).start(); + procTimer.initializeMs<2000>(sayHello).start(); testPrintf(); diff --git a/samples/Basic_Serial/include/SerialTransmitDemo.h b/samples/Basic_Serial/include/SerialTransmitDemo.h index 2e9d032cb7..0b0afa31c9 100644 --- a/samples/Basic_Serial/include/SerialTransmitDemo.h +++ b/samples/Basic_Serial/include/SerialTransmitDemo.h @@ -8,9 +8,8 @@ class SerialTransmitDemo { public: - SerialTransmitDemo(HardwareSerial& serial, IDataSourceStream* stream) : serial(serial) + SerialTransmitDemo(HardwareSerial& serial, IDataSourceStream* stream) : serial(serial), stream(stream) { - this->stream.reset(stream); serial.onTransmitComplete(TransmitCompleteDelegate(&SerialTransmitDemo::onTransmitComplete, this)); } diff --git a/samples/Basic_Servo/app/application.cpp b/samples/Basic_Servo/app/application.cpp index 9fb66c4390..d3d18c1afa 100644 --- a/samples/Basic_Servo/app/application.cpp +++ b/samples/Basic_Servo/app/application.cpp @@ -7,6 +7,8 @@ #include #include +namespace +{ // Un-comment to use raw time values instead of degrees for servo positioning //#define UPDATE_RAW @@ -31,13 +33,11 @@ class MyServoChannel : public ServoChannel private: Timer timer; - uint16 centerdelay = 0; - uint32 value = 0; + uint16_t centerdelay = 0; + uint32_t value = 0; int degree = 0; }; -static MyServoChannel channels[4]; - void MyServoChannel::calcValue() { const char indent[] = " "; @@ -63,10 +63,10 @@ void MyServoChannel::calcValue() value = 0; // overflow and restart linear ramp } - Serial << " value = " << value; + Serial << _F(" value = ") << value; if(!setValue(value)) { - Serial << ": setValue(" << value << ") failed!"; + Serial << _F(": setValue(") << value << _F(") failed!"); } #else @@ -77,10 +77,10 @@ void MyServoChannel::calcValue() ++degree; } - Serial << " degree = " << degree; + Serial << _F(" degree = ") << degree; if(!setDegree(degree)) { - Serial << ": setDegree(" << degree << ") failed!"; + Serial << _F(": setDegree(") << degree << _F(") failed!"); } #endif @@ -102,6 +102,10 @@ void MyServoChannel::calcValue() Serial.println(); } +MyServoChannel channels[4]; + +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); @@ -109,7 +113,7 @@ void init() Serial.setTxWait(false); Serial.setTxBufferSize(1024); - Serial.println("Init Basic Servo Sample"); + Serial.println(_F("Init Basic Servo Sample")); System.setCpuFrequency(CpuCycleClockNormal::cpuFrequency()); #ifdef ARCH_HOST diff --git a/samples/Basic_SmartConfig/app/application.cpp b/samples/Basic_SmartConfig/app/application.cpp index 05f9eec4ca..7e0909b529 100644 --- a/samples/Basic_SmartConfig/app/application.cpp +++ b/samples/Basic_SmartConfig/app/application.cpp @@ -1,24 +1,30 @@ #include +namespace +{ bool smartConfigCallback(SmartConfigEvent event, const SmartConfigEventInfo& info) { switch(event) { case SCE_Wait: - debugf("SCE_Wait\n"); + Serial.println(_F("SCE_Wait")); break; + case SCE_FindChannel: - debugf("SCE_FindChannel\n"); + Serial.println(_F("SCE_FindChannel")); break; + case SCE_GettingSsid: - debugf("SCE_GettingSsid, type = %d\n", info.type); + Serial << _F("SCE_GettingSsid, type = ") << info.type << endl; break; + case SCE_Link: - debugf("SCE_Link\n"); + Serial.println(_F("SCE_Link")); WifiStation.config(info.ssid, info.password); WifiStation.connect(); break; + case SCE_LinkOver: - debugf("SCE_LinkOver\n"); + Serial.println(_F("SCE_LinkOver")); WifiStation.smartConfigStop(); break; } @@ -29,9 +35,11 @@ bool smartConfigCallback(SmartConfigEvent event, const SmartConfigEventInfo& inf void gotIP(IpAddress ip, IpAddress netmask, IpAddress gateway) { - Serial << "Connected: " << ip << endl; + Serial << _F("Connected: ") << ip << endl; } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); // 115200 by default @@ -40,8 +48,9 @@ void init() WifiEvents.onStationGotIP(gotIP); WifiAccessPoint.enable(false); WifiStation.enable(true); + // automatic (acts as the sample callback above) - //WifiStation.smartConfigStart(SCT_EspTouch); + // WifiStation.smartConfigStart(SCT_EspTouch); // manual, use callback above WifiStation.smartConfigStart(SCT_EspTouch, smartConfigCallback); } diff --git a/samples/Basic_Ssl/README.rst b/samples/Basic_Ssl/README.rst index d82e88e76f..1449e98133 100644 --- a/samples/Basic_Ssl/README.rst +++ b/samples/Basic_Ssl/README.rst @@ -9,7 +9,7 @@ Compilation In Sming the SSL support is not enabled by default. In order to enable it you should compile your project with the -:envvar:`ENABLE_SSL` =1 directive. This can be done using the following command:: +:envvar:`ENABLE_SSL=1 ` directive:: make ENABLE_SSL=1 @@ -19,7 +19,7 @@ Debug Information ----------------- If you want to see more debug information during compile type you should -add the directive :envvar:`SSL_DEBUG` =1, like this:: +enable :envvar:`SSL_DEBUG`, like this:: make ENABLE_SSL=1 SSL_DEBUG=1 diff --git a/samples/Basic_Ssl/app/application.cpp b/samples/Basic_Ssl/app/application.cpp index 6c89546433..d6c16c1b51 100644 --- a/samples/Basic_Ssl/app/application.cpp +++ b/samples/Basic_Ssl/app/application.cpp @@ -11,13 +11,35 @@ #define WIFI_PWD "PleaseEnterPass" #endif -Timer procTimer; +namespace +{ +// Use the Gibson Research fingerprints web page as an example. Unlike Google, these fingerprints change very infrequently. +DEFINE_FSTR(REQUEST_URL, "https://www.grc.com/fingerprints.htm") + +const Ssl::Fingerprint::Cert::Sha1 sha1Fingerprint PROGMEM = { + 0xA6, 0x8F, 0x8C, 0x47, 0x6B, 0xD0, 0xDE, 0x9E, 0x1D, 0x18, + 0x4A, 0x0A, 0x51, 0x4D, 0x90, 0x11, 0x31, 0x93, 0x40, 0x6D, + +}; + +const Ssl::Fingerprint::Cert::Sha256 certSha256Fingerprint PROGMEM = { + 0xDA, 0x2C, 0xF7, 0x62, 0x09, 0x2C, 0x0A, 0x7B, 0x88, 0xA0, 0xDA, 0x65, 0xF9, 0x29, 0x45, 0x97, + 0xA6, 0xDB, 0xAA, 0x2C, 0x80, 0xFD, 0x75, 0x0A, 0xD9, 0xA0, 0x75, 0xEE, 0x64, 0xEE, 0x06, 0x68, +}; + +const Ssl::Fingerprint::Pki::Sha256 publicKeyFingerprint PROGMEM = { + // Out of date + 0xad, 0xcc, 0x21, 0x92, 0x8e, 0x65, 0xc7, 0x54, 0xac, 0xac, 0xb8, 0x2f, 0x12, 0x95, 0x2e, 0x19, + 0x7d, 0x15, 0x7e, 0x32, 0xbe, 0x90, 0x27, 0x43, 0xab, 0xfe, 0xf1, 0xf2, 0xf2, 0xe1, 0x9c, 0x35, +}; + HttpClient downloadClient; OneShotFastMs connectTimer; +SimpleTimer heapTimer; void printHeap() { - Serial.println(_F("Heap statistics")); + Serial << _F("Heap statistics") << endl; Serial << _F(" Free bytes: ") << system_get_free_heap_size() << endl; #ifdef ENABLE_MALLOC_COUNT Serial << _F(" Used: ") << MallocCount::getCurrent() << endl; @@ -40,8 +62,8 @@ int onDownload(HttpConnection& connection, bool success) Serial << _F(", received ") << stream->available() << _F(" bytes") << endl; auto& headers = connection.getResponse()->headers; - for(unsigned i = 0; i < headers.count(); ++i) { - Serial.print(headers[i]); + for(auto hdr : headers) { + Serial.print(hdr); } auto ssl = connection.getSsl(); @@ -61,22 +83,6 @@ void grcSslInit(Ssl::Session& session, HttpRequest& request) { debug_i("Initialising SSL session for GRC"); - // Use the Gibson Research fingerprints web page as an example. Unlike Google, these fingerprints change very infrequently. - static const Ssl::Fingerprint::Cert::Sha1 sha1Fingerprint PROGMEM = { - 0xC3, 0xFB, 0x91, 0x85, 0xCC, 0x6B, 0x4C, 0x7D, 0xE7, 0x18, - 0xED, 0xD8, 0x00, 0xD2, 0x84, 0xE7, 0x6E, 0x97, 0x06, 0x07, - }; - - static const Ssl::Fingerprint::Cert::Sha256 certSha256Fingerprint PROGMEM = { - 0xC3, 0xFB, 0x91, 0x85, 0xCC, 0x6B, 0x4C, 0x7D, 0xE7, 0x18, - 0xED, 0xD8, 0x00, 0xD2, 0x84, 0xE7, 0x6E, 0x97, 0x06, 0x07, - }; - - static const Ssl::Fingerprint::Pki::Sha256 publicKeyFingerprint PROGMEM = { - 0xad, 0xcc, 0x21, 0x92, 0x8e, 0x65, 0xc7, 0x54, 0xac, 0xac, 0xb8, 0x2f, 0x12, 0x95, 0x2e, 0x19, - 0x7d, 0x15, 0x7e, 0x32, 0xbe, 0x90, 0x27, 0x43, 0xab, 0xfe, 0xf1, 0xf2, 0xf2, 0xe1, 0x9c, 0x35, - }; - // Trust certificate only if it matches the SHA1 fingerprint... session.validators.pin(sha1Fingerprint); @@ -95,12 +101,11 @@ void grcSslInit(Ssl::Session& session, HttpRequest& request) void gotIP(IpAddress ip, IpAddress netmask, IpAddress gateway) { - Serial.print(F("Connected. Got IP: ")); - Serial.println(ip); + Serial << _F("Connected. Got IP: ") << ip << endl; connectTimer.start(); - auto request = new HttpRequest(F("https://www.grc.com/fingerprints.htm")); + auto request = new HttpRequest(String(REQUEST_URL)); request->onSslInit(grcSslInit); request->onRequestComplete(onDownload); request->setResponseStream(new CounterStream); @@ -112,6 +117,8 @@ void connectFail(const String& ssid, MacAddress bssid, WifiDisconnectReason reas Serial.println(F("I'm NOT CONNECTED!")); } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); @@ -122,8 +129,7 @@ void init() MallocCount::enableLogging(true); #endif - auto heapTimer = new Timer; - heapTimer->initializeMs<5000>(printHeap).start(); + heapTimer.initializeMs<5000>(printHeap).start(); // Setup the WIFI connection WifiStation.enable(true); diff --git a/samples/Basic_Ssl/component.mk b/samples/Basic_Ssl/component.mk index b994d8280f..e068be8488 100644 --- a/samples/Basic_Ssl/component.mk +++ b/samples/Basic_Ssl/component.mk @@ -4,4 +4,4 @@ COMPONENT_DEPENDS += malloc_count COMPONENT_CXXFLAGS += -DENABLE_MALLOC_COUNT=1 endif -ENABLE_SSL = 1 +ENABLE_SSL ?= Bearssl diff --git a/samples/Basic_Ssl/include/CounterStream.h b/samples/Basic_Ssl/include/CounterStream.h index 07b0c66cf1..b33f9676d3 100644 --- a/samples/Basic_Ssl/include/CounterStream.h +++ b/samples/Basic_Ssl/include/CounterStream.h @@ -9,7 +9,7 @@ class CounterStream : public ReadWriteStream { public: - size_t write(const uint8_t* buffer, size_t size) + size_t write(const uint8_t* buffer, size_t size) override { streamSize += size; return size; diff --git a/samples/Basic_Ssl/include/ssl/cert.h b/samples/Basic_Ssl/include/ssl/cert.h deleted file mode 100644 index 61ca8a654e..0000000000 --- a/samples/Basic_Ssl/include/ssl/cert.h +++ /dev/null @@ -1,27 +0,0 @@ -unsigned char default_certificate[] = { - 0x30, 0x82, 0x01, 0xd7, 0x30, 0x82, 0x01, 0x40, 0x02, 0x09, 0x00, 0xab, 0x08, 0x18, 0xa7, 0x03, 0x07, 0x27, 0xfd, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x34, 0x31, 0x32, - 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x29, 0x61, 0x78, 0x54, 0x4c, 0x53, 0x20, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x20, 0x44, 0x6f, 0x64, 0x67, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x31, - 0x32, 0x32, 0x36, 0x32, 0x32, 0x33, 0x33, 0x33, 0x39, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x39, 0x30, 0x33, 0x32, - 0x32, 0x33, 0x33, 0x33, 0x39, 0x5a, 0x30, 0x2c, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, - 0x61, 0x78, 0x54, 0x4c, 0x53, 0x20, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x13, 0x09, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x30, 0x81, 0x9f, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, - 0x89, 0x02, 0x81, 0x81, 0x00, 0xcd, 0xfd, 0x89, 0x48, 0xbe, 0x36, 0xb9, 0x95, 0x76, 0xd4, 0x13, 0x30, 0x0e, 0xbf, - 0xb2, 0xed, 0x67, 0x0a, 0xc0, 0x16, 0x3f, 0x51, 0x09, 0x9d, 0x29, 0x2f, 0xb2, 0x6d, 0x3f, 0x3e, 0x6c, 0x2f, 0x90, - 0x80, 0xa1, 0x71, 0xdf, 0xbe, 0x38, 0xc5, 0xcb, 0xa9, 0x9a, 0x40, 0x14, 0x90, 0x0a, 0xf9, 0xb7, 0x07, 0x0b, 0xe1, - 0xda, 0xe7, 0x09, 0xbf, 0x0d, 0x57, 0x41, 0x86, 0x60, 0xa1, 0xc1, 0x27, 0x91, 0x5b, 0x0a, 0x98, 0x46, 0x1b, 0xf6, - 0xa2, 0x84, 0xf8, 0x65, 0xc7, 0xce, 0x2d, 0x96, 0x17, 0xaa, 0x91, 0xf8, 0x61, 0x04, 0x50, 0x70, 0xeb, 0xb4, 0x43, - 0xb7, 0xdc, 0x9a, 0xcc, 0x31, 0x01, 0x14, 0xd4, 0xcd, 0xcc, 0xc2, 0x37, 0x6d, 0x69, 0x82, 0xd6, 0xc6, 0xc4, 0xbe, - 0xf2, 0x34, 0xa5, 0xc9, 0xa6, 0x19, 0x53, 0x32, 0x7a, 0x86, 0x0e, 0x91, 0x82, 0x0f, 0xa1, 0x42, 0x54, 0xaa, 0x01, - 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, - 0x00, 0x03, 0x81, 0x81, 0x00, 0x40, 0xb4, 0x94, 0x9a, 0xa8, 0x89, 0x72, 0x1d, 0x07, 0xe5, 0xb3, 0x6b, 0x88, 0x21, - 0xc2, 0x38, 0x36, 0x9e, 0x7a, 0x8c, 0x49, 0x48, 0x68, 0x0c, 0x06, 0xe8, 0xdb, 0x1f, 0x4e, 0x05, 0xe6, 0x31, 0xe3, - 0xfd, 0xe6, 0x0d, 0x6b, 0xd8, 0x13, 0x17, 0xe0, 0x2d, 0x0d, 0xb8, 0x7e, 0xcb, 0x20, 0x6c, 0xa8, 0x73, 0xa7, 0xfd, - 0xe3, 0xa7, 0xfa, 0xf3, 0x02, 0x60, 0x78, 0x1f, 0x13, 0x40, 0x45, 0xee, 0x75, 0xf5, 0x10, 0xfd, 0x8f, 0x68, 0x74, - 0xd4, 0xac, 0xae, 0x04, 0x09, 0x55, 0x2c, 0xdb, 0xd8, 0x07, 0x07, 0x65, 0x69, 0x27, 0x6e, 0xbf, 0x5e, 0x61, 0x40, - 0x56, 0x8b, 0xd7, 0x33, 0x3b, 0xff, 0x6e, 0x53, 0x7e, 0x9d, 0x3f, 0xc0, 0x40, 0x3a, 0xab, 0xa0, 0x50, 0x4e, 0x80, - 0x47, 0x46, 0x0d, 0x1e, 0xdb, 0x4c, 0xf1, 0x1b, 0x5d, 0x3c, 0x2a, 0x54, 0xa7, 0x4d, 0xfa, 0x7b, 0x72, 0x66, 0xc5}; -unsigned int default_certificate_len = 475; diff --git a/samples/Basic_Ssl/include/ssl/private_key.h b/samples/Basic_Ssl/include/ssl/private_key.h deleted file mode 100644 index 31de50cb53..0000000000 --- a/samples/Basic_Ssl/include/ssl/private_key.h +++ /dev/null @@ -1,35 +0,0 @@ -unsigned char default_private_key[] = { - 0x30, 0x82, 0x02, 0x5d, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xcd, 0xfd, 0x89, 0x48, 0xbe, 0x36, 0xb9, 0x95, - 0x76, 0xd4, 0x13, 0x30, 0x0e, 0xbf, 0xb2, 0xed, 0x67, 0x0a, 0xc0, 0x16, 0x3f, 0x51, 0x09, 0x9d, 0x29, 0x2f, 0xb2, - 0x6d, 0x3f, 0x3e, 0x6c, 0x2f, 0x90, 0x80, 0xa1, 0x71, 0xdf, 0xbe, 0x38, 0xc5, 0xcb, 0xa9, 0x9a, 0x40, 0x14, 0x90, - 0x0a, 0xf9, 0xb7, 0x07, 0x0b, 0xe1, 0xda, 0xe7, 0x09, 0xbf, 0x0d, 0x57, 0x41, 0x86, 0x60, 0xa1, 0xc1, 0x27, 0x91, - 0x5b, 0x0a, 0x98, 0x46, 0x1b, 0xf6, 0xa2, 0x84, 0xf8, 0x65, 0xc7, 0xce, 0x2d, 0x96, 0x17, 0xaa, 0x91, 0xf8, 0x61, - 0x04, 0x50, 0x70, 0xeb, 0xb4, 0x43, 0xb7, 0xdc, 0x9a, 0xcc, 0x31, 0x01, 0x14, 0xd4, 0xcd, 0xcc, 0xc2, 0x37, 0x6d, - 0x69, 0x82, 0xd6, 0xc6, 0xc4, 0xbe, 0xf2, 0x34, 0xa5, 0xc9, 0xa6, 0x19, 0x53, 0x32, 0x7a, 0x86, 0x0e, 0x91, 0x82, - 0x0f, 0xa1, 0x42, 0x54, 0xaa, 0x01, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x81, 0x81, 0x00, 0x95, 0xaa, 0x6e, 0x11, - 0xf5, 0x6a, 0x8b, 0xa2, 0xc6, 0x48, 0xc6, 0x7c, 0x37, 0x6b, 0x1f, 0x55, 0x10, 0x76, 0x26, 0x24, 0xc3, 0xf2, 0x5c, - 0x5a, 0xdd, 0x2e, 0xf3, 0xa4, 0x1e, 0xbc, 0x7b, 0x1c, 0x80, 0x10, 0x85, 0xbc, 0xd8, 0x45, 0x3c, 0xb8, 0xb2, 0x06, - 0x53, 0xb5, 0xd5, 0x7a, 0xe7, 0x0e, 0x92, 0xe6, 0x42, 0xc2, 0xe2, 0x2a, 0xd5, 0xd1, 0x03, 0x9f, 0x6f, 0x53, 0x74, - 0x68, 0x72, 0x8e, 0xbf, 0x03, 0xbb, 0xab, 0xbd, 0xa1, 0xf9, 0x81, 0x7d, 0x12, 0xd4, 0x9d, 0xb6, 0xae, 0x4c, 0xad, - 0xca, 0xa8, 0xc9, 0x80, 0x8d, 0x0d, 0xd5, 0xd0, 0xa1, 0xbf, 0xec, 0x60, 0x48, 0x49, 0xed, 0x97, 0x0f, 0x5e, 0xed, - 0xfc, 0x39, 0x15, 0x96, 0x9e, 0x5d, 0xe2, 0xb4, 0x5d, 0x2e, 0x04, 0xdc, 0x08, 0xa2, 0x65, 0x29, 0x2d, 0x37, 0xfb, - 0x62, 0x90, 0x1b, 0x7b, 0xe5, 0x3a, 0x58, 0x05, 0x55, 0xc1, 0x02, 0x41, 0x00, 0xfc, 0x69, 0x28, 0xc9, 0xa8, 0xc4, - 0x5c, 0xe3, 0xd0, 0x5e, 0xaa, 0xda, 0xde, 0x87, 0x74, 0xdb, 0xcb, 0x40, 0x78, 0x8e, 0x1d, 0x12, 0x96, 0x16, 0x61, - 0x3f, 0xb3, 0x3e, 0xa3, 0x0d, 0xdc, 0x49, 0xa5, 0x25, 0x87, 0xc5, 0x97, 0x85, 0x9d, 0xbb, 0xb4, 0xf0, 0x44, 0xfd, - 0x6c, 0xe8, 0xd2, 0x8c, 0xec, 0x33, 0x81, 0x46, 0x1e, 0x10, 0x12, 0x33, 0x16, 0x95, 0x00, 0x4f, 0x75, 0xb4, 0xe5, - 0x79, 0x02, 0x41, 0x00, 0xd0, 0xeb, 0x65, 0x07, 0x10, 0x3b, 0xd9, 0x03, 0xeb, 0xdc, 0x6f, 0x4b, 0x8f, 0xc3, 0x87, - 0xce, 0x76, 0xd6, 0xc5, 0x14, 0x21, 0x4e, 0xe7, 0x4f, 0x1b, 0xe8, 0x05, 0xf8, 0x84, 0x1a, 0xe0, 0xc5, 0xd6, 0xe3, - 0x08, 0xb3, 0x54, 0x57, 0x02, 0x1f, 0xd4, 0xd9, 0xfb, 0xff, 0x40, 0xb1, 0x56, 0x1c, 0x60, 0xf7, 0xac, 0x91, 0xf3, - 0xd3, 0xc6, 0x7f, 0x84, 0xfd, 0x84, 0x9d, 0xea, 0x26, 0xee, 0xc9, 0x02, 0x41, 0x00, 0xa6, 0xcf, 0x1c, 0x6c, 0x81, - 0x03, 0x1c, 0x5c, 0x56, 0x05, 0x6a, 0x26, 0x70, 0xef, 0xd6, 0x13, 0xb7, 0x74, 0x28, 0xf7, 0xca, 0x50, 0xd1, 0x2d, - 0x83, 0x21, 0x64, 0xe4, 0xdd, 0x3f, 0x38, 0xb8, 0xd6, 0xd2, 0x41, 0xb3, 0x1c, 0x9a, 0xea, 0x0d, 0xf5, 0xda, 0xdf, - 0xcd, 0x17, 0x9f, 0x9a, 0x1e, 0x15, 0xaf, 0x48, 0x1c, 0xbd, 0x9b, 0x63, 0x5b, 0xad, 0xed, 0xd4, 0xa1, 0xae, 0xa9, - 0x59, 0x09, 0x02, 0x40, 0x4e, 0x08, 0xce, 0xa8, 0x8f, 0xc0, 0xba, 0xf3, 0x83, 0x02, 0xc8, 0x33, 0x62, 0x14, 0x77, - 0xc2, 0x7f, 0x93, 0x02, 0xf3, 0xdc, 0xe9, 0x1a, 0xee, 0xea, 0x8e, 0x84, 0xc4, 0x69, 0x9b, 0x9c, 0x7f, 0x69, 0x1f, - 0x4e, 0x1d, 0xa5, 0x90, 0x06, 0x44, 0x1b, 0x7d, 0xfc, 0x69, 0x40, 0x21, 0xbc, 0xf7, 0x46, 0xa4, 0xdc, 0x39, 0x7b, - 0xe8, 0x8b, 0x49, 0x10, 0x44, 0x9d, 0x67, 0x5a, 0x91, 0x86, 0x39, 0x02, 0x40, 0x41, 0x2c, 0x4e, 0xfe, 0xd9, 0x90, - 0x89, 0x00, 0x5c, 0x94, 0x0a, 0x4a, 0x7e, 0x1b, 0x1a, 0x80, 0x06, 0x01, 0x37, 0xda, 0x50, 0x61, 0x9d, 0x9c, 0xfe, - 0x25, 0x7f, 0xd8, 0xd4, 0xc4, 0x9e, 0x81, 0xf2, 0x0c, 0x1e, 0x38, 0x21, 0x1e, 0x90, 0x3f, 0xd4, 0xba, 0x6c, 0x53, - 0xcb, 0xf0, 0x77, 0x79, 0x9b, 0xf1, 0xfa, 0x3f, 0x81, 0xdc, 0xf3, 0x21, 0x02, 0x6d, 0xb7, 0x95, 0xc3, 0x2e, 0xce, - 0xd5}; -unsigned int default_private_key_len = 609; diff --git a/samples/Basic_Storage/app/application.cpp b/samples/Basic_Storage/app/application.cpp index e9fa62b362..a642aa6906 100644 --- a/samples/Basic_Storage/app/application.cpp +++ b/samples/Basic_Storage/app/application.cpp @@ -3,6 +3,9 @@ #include #include +namespace +{ +// Use this source file as contents of our test partitions IMPORT_FSTR(FS_app, PROJECT_DIR "/app/application.cpp") void listSpiffsPartitions() @@ -12,16 +15,17 @@ void listSpiffsPartitions() Serial << _F(">> Mounting '") << part.name() << "' ..." << endl; bool ok = spiffs_mount(part); Serial.println(ok ? "OK, listing files:" : "Mount failed!"); - if(ok) { - Directory dir; - if(dir.open()) { - while(dir.next()) { - Serial.print(" "); - Serial.println(dir.stat().name); - } + if(!ok) { + continue; + } + + Directory dir; + if(dir.open()) { + while(dir.next()) { + Serial << " " << dir.stat().name << endl; } - Serial << dir.count() << _F(" files found") << endl << endl; } + Serial << dir.count() << _F(" files found") << endl << endl; } } @@ -37,7 +41,7 @@ void printPart(Storage::Partition part) String s = part.getDeviceName(); s += '/'; s += part.name(); - m_printHex(s.c_str(), buf, std::min(128U, bufSize)); + m_printHex(s.c_str(), buf, std::min(size_t(128U), bufSize)); Serial << _F("Elapsed: ") << elapsed.toString() << endl; if(elapsed != 0) { Serial << _F("Speed: ") << 1000 * bufSize / elapsed << " KB/s" << endl; @@ -56,6 +60,8 @@ void printPart(const String& partitionName) } } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); @@ -86,7 +92,11 @@ void init() printPart(part); Serial.println(_F("** Reading SysMem device (RAM)")); - part = Storage::sysMem.editablePartitions().add(F("fs_app RAM"), FS_app, {Storage::Partition::Type::data, 100}); + const size_t bufferSize{4096}; + auto buffer = std::make_unique(bufferSize); + FS_app.readFlash(0, buffer.get(), bufferSize); + part = Storage::sysMem.editablePartitions().add(F("fs_app RAM"), {Storage::Partition::Type::data, 100}, + storage_size_t(buffer.get()), bufferSize); printPart(part); printPart(part); printPart(part); diff --git a/samples/Basic_Templates/app/CsvTemplate.h b/samples/Basic_Templates/app/CsvTemplate.h index b29b4ae349..cdf56fdd8a 100644 --- a/samples/Basic_Templates/app/CsvTemplate.h +++ b/samples/Basic_Templates/app/CsvTemplate.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include /** @@ -35,5 +35,5 @@ class CsvTemplate : public SectionTemplate } private: - CsvReader csv; + CSV::Reader csv; }; diff --git a/samples/Basic_Templates/app/application.cpp b/samples/Basic_Templates/app/application.cpp index efca95a384..a2bbae2d40 100644 --- a/samples/Basic_Templates/app/application.cpp +++ b/samples/Basic_Templates/app/application.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include "CsvTemplate.h" namespace @@ -51,7 +50,7 @@ void printCars() void printClassics(const FlashString& templateSource, Format::Formatter& formatter) { // The CSV data source - CsvReader csv(new FileStream(Filename::classics_csv)); + CSV::Reader csv(new FileStream(Filename::classics_csv)); // Use a regular SectionTemplate class to process the template SectionTemplate tmpl(new FSTR::Stream(templateSource)); diff --git a/samples/Basic_Templates/component.mk b/samples/Basic_Templates/component.mk index 092ca88129..bcb5ca8f81 100644 --- a/samples/Basic_Templates/component.mk +++ b/samples/Basic_Templates/component.mk @@ -1,3 +1,4 @@ +COMPONENT_DEPENDS := CsvReader HWCONFIG := basic_templates DISABLE_NETWORK := 1 diff --git a/samples/Basic_Utility/app/utility.cpp b/samples/Basic_Utility/app/utility.cpp index 4a60753e4c..cfd203822d 100644 --- a/samples/Basic_Utility/app/utility.cpp +++ b/samples/Basic_Utility/app/utility.cpp @@ -1,12 +1,11 @@ #include #include +#include + +auto& output = Host::standardOutput; namespace { -#define XX(name, ext, mime) ext "\0" -DEFINE_FSTR_LOCAL(fstr_ext, "htm\0" MIME_TYPE_MAP(XX)) -#undef XX - namespace Command { DEFINE_FSTR(testWebConstants, "testWebConstants") @@ -14,21 +13,20 @@ DEFINE_FSTR(testWebConstants, "testWebConstants") void testWebConstants() { - m_printf("%s\n", __FUNCTION__); + output << __FUNCTION__ << endl; const char* extensions[] = { "htm", "html", "txt", "js", "css", "xml", "json", "jpg", "gif", "png", "svg", "ico", "gzip", "zip", "git", "sh", "bin", "exe", }; - for(unsigned i = 0; i < ARRAY_SIZE(extensions); ++i) { - auto ext = extensions[i]; + for(auto ext : extensions) { String contentType = ContentType::fromFileExtension(ext); if(!contentType) { - contentType = "(NOT FOUND)"; + contentType = F("(NOT FOUND)"); } MimeType mimeType = ContentType::fromString(contentType); - m_printf(" %u %s: %s (#%u)\n", i, ext, contentType.c_str(), mimeType); + output << " " << ext << ": " << contentType << " (#" << unsigned(mimeType) << ')' << endl; } } @@ -36,44 +34,38 @@ void testWebConstants() void init() { - // Hook up debug output - Serial.begin(COM_SPEED_SERIAL); - Serial.systemDebugOutput(true); - /* * In a real utility we'd probably need to parse command-line arguments. * See Arch/Host/Components/hostlib/options.h for one way to do this. */ - m_printf("\n** Basic Host utility sample **\n"); + output << endl << "** Basic Host utility sample **" << endl; auto parameters = commandLine.getParameters(); if(parameters.count() == 0) { - m_printf("No command line parameters\n" - "Try doing this:\n" - " make run HOST_PARAMETERS='command=%s'\n", - String(Command::testWebConstants).c_str()); + output << "No command line parameters" << endl + << "Try doing this:" << endl + << " make run HOST_PARAMETERS='command=" << String(Command::testWebConstants) << "'" << endl; } else { - m_printf("Command-line parameters:\n", parameters.count()); - for(int i = 0; i < parameters.count(); ++i) { - auto param = parameters[i]; - m_printf(" %u: text = '%s'\n", i, param.text); - m_printf(" name = '%s'\n", param.getName().c_str()); - m_printf(" value = '%s'\n", param.getValue().c_str()); + output << "Command-line parameters: " << parameters.count() << endl; + for(auto& param : parameters) { + output << param.text << endl; + output << " name = '" << param.getName() << "'" << endl; + output << " value = '" << param.getValue() << "'" << endl; } - m_putc('\n'); + output.println(); auto param = parameters.findIgnoreCase("command"); if(param) { if(Command::testWebConstants.equalsIgnoreCase(param.getValue())) { testWebConstants(); } else { - m_printf("Command '%s' not recognised. Try '%s'.\n", param.getValue().c_str(), - String(Command::testWebConstants).c_str()); + output << "Command '" << param.getValue() << "' not recognised. Try '" + << String(Command::testWebConstants) << "'." << endl; } } } - m_putc('\n'); + output.println(); System.restart(); } diff --git a/samples/Basic_WebSkeletonApp/app/application.cpp b/samples/Basic_WebSkeletonApp/app/application.cpp index dcdbc84d42..9175976292 100644 --- a/samples/Basic_WebSkeletonApp/app/application.cpp +++ b/samples/Basic_WebSkeletonApp/app/application.cpp @@ -1,29 +1,35 @@ -#include +#include +#include +#include -static Timer counterTimer; -unsigned long counter = 0; +// Global +unsigned long counter; -static void counterLoop() +namespace +{ +SimpleTimer counterTimer; + +void counterCallback() { counter++; } -static void STADisconnect(const String& ssid, MacAddress bssid, WifiDisconnectReason reason) +void STADisconnect(const String& ssid, MacAddress bssid, WifiDisconnectReason reason) { - debugf("DISCONNECT - SSID: %s, REASON: %s\n", ssid.c_str(), WifiEvents.getDisconnectReasonDesc(reason).c_str()); + Serial << _F("DISCONNECT - SSID: ") << ssid << _F(", REASON: ") << WifiEvents.getDisconnectReasonDesc(reason) + << endl; if(!WifiAccessPoint.isEnabled()) { - debugf("Starting OWN AP"); + Serial << _F("Starting OWN AP"); WifiStation.disconnect(); WifiAccessPoint.enable(true); WifiStation.connect(); } } -static void STAGotIP(IpAddress ip, IpAddress mask, IpAddress gateway) +void STAGotIP(IpAddress ip, IpAddress mask, IpAddress gateway) { - debugf("GOTIP - IP: %s, MASK: %s, GW: %s\n", ip.toString().c_str(), mask.toString().c_str(), - gateway.toString().c_str()); + Serial << _F("GOTIP - IP: ") << ip << _F(", MASK: ") << mask << _F(", GW: ") << gateway << endl; if(WifiAccessPoint.isEnabled()) { debugf("Shutdown OWN AP"); @@ -32,11 +38,12 @@ static void STAGotIP(IpAddress ip, IpAddress mask, IpAddress gateway) // Add commands to be executed after successfully connecting to AP and got IP from it } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); // 115200 by default Serial.systemDebugOutput(true); - Serial.commandProcessing(false); #ifndef ENABLE_FLASHSTRING_MAP spiffs_mount(); // Mount file system, in order to work with files @@ -58,5 +65,5 @@ void init() System.onReady(startWebServer); - counterTimer.initializeMs(1000, counterLoop).start(); + counterTimer.initializeMs<1000>(counterCallback).start(); } diff --git a/samples/Basic_WebSkeletonApp/app/configuration.cpp b/samples/Basic_WebSkeletonApp/app/configuration.cpp index a97aa3227a..6795908354 100644 --- a/samples/Basic_WebSkeletonApp/app/configuration.cpp +++ b/samples/Basic_WebSkeletonApp/app/configuration.cpp @@ -7,6 +7,14 @@ #define WIFI_PWD "PleaseEnterPass" #endif +namespace +{ +DEFINE_FSTR(KEY_NETWORK, "network") +DEFINE_FSTR(KEY_SSID, "StaSSID") +DEFINE_FSTR(KEY_PASS, "StaPassword") +DEFINE_FSTR(KEY_ENABLE, "StaEnable") +} // namespace + ThermConfig activeConfig; ThermConfig loadConfig() @@ -14,14 +22,14 @@ ThermConfig loadConfig() StaticJsonDocument doc; ThermConfig cfg; if(Json::loadFromFile(doc, THERM_CONFIG_FILE)) { - JsonObject network = doc["network"]; - cfg.StaSSID = network["StaSSID"].as(); - cfg.StaPassword = network["StaPassword"].as(); - cfg.StaEnable = network["StaEnable"]; + JsonObject network = doc[KEY_NETWORK]; + cfg.StaSSID = network[KEY_SSID].as(); + cfg.StaPassword = network[KEY_PASS].as(); + cfg.StaEnable = network[KEY_ENABLE]; } else { // Factory defaults if no config file present, or could not access it - cfg.StaSSID = WIFI_SSID; - cfg.StaPassword = WIFI_PWD; + cfg.StaSSID = F(WIFI_SSID); + cfg.StaPassword = F(WIFI_PWD); } return cfg; } @@ -30,10 +38,10 @@ void saveConfig(ThermConfig& cfg) { StaticJsonDocument doc; - JsonObject network = doc.createNestedObject("network"); - network["StaSSID"] = cfg.StaSSID; - network["StaPassword"] = cfg.StaPassword; - network["StaEnable"] = cfg.StaEnable; + JsonObject network = doc.createNestedObject(KEY_NETWORK); + network[KEY_SSID] = cfg.StaSSID; + network[KEY_PASS] = cfg.StaPassword; + network[KEY_ENABLE] = cfg.StaEnable; Json::saveToFile(doc, THERM_CONFIG_FILE, Json::Pretty); } diff --git a/samples/Basic_WebSkeletonApp/app/webserver.cpp b/samples/Basic_WebSkeletonApp/app/webserver.cpp index 5e19982205..228c45d4cb 100644 --- a/samples/Basic_WebSkeletonApp/app/webserver.cpp +++ b/samples/Basic_WebSkeletonApp/app/webserver.cpp @@ -1,8 +1,10 @@ -#include #include #include #include #include "DelayStream.h" +#include + +extern unsigned long counter; // Kind of heartbeat counter namespace { @@ -40,20 +42,20 @@ void sendFile(const String& fileName, HttpServerConnection& connection) auto response = connection.getResponse(); String compressed = fileName + ".gz"; - auto v = fileMap[compressed]; - if(v) { + auto content = fileMap[compressed]; + if(content) { response->headers[HTTP_HEADER_CONTENT_ENCODING] = _F("gzip"); } else { - v = fileMap[fileName]; - if(!v) { + content = fileMap[fileName]; + if(!content) { debug_w("File '%s' not found", fileName.c_str()); response->code = HTTP_STATUS_NOT_FOUND; return; } } - debug_i("found %s in fileMap", String(v.key()).c_str()); - auto stream = new FSTR::Stream(v.content()); + debug_i("found %s in fileMap", String(content.key()).c_str()); + auto stream = new FSTR::Stream(content.content()); response->sendDataStream(stream, ContentType::fromFullFileName(fileName)); // Use client caching for better performance. diff --git a/samples/Basic_WebSkeletonApp/include/configuration.h b/samples/Basic_WebSkeletonApp/include/configuration.h index 555e69c3a3..25de6c43d1 100644 --- a/samples/Basic_WebSkeletonApp/include/configuration.h +++ b/samples/Basic_WebSkeletonApp/include/configuration.h @@ -1,6 +1,6 @@ #pragma once -#include +#include const char THERM_CONFIG_FILE[] = ".therm.conf"; // leading point for security reasons :) @@ -8,16 +8,9 @@ const char THERM_CONFIG_FILE[] = ".therm.conf"; // leading point for security re const uint8_t ConfigJsonBufferSize = 200; struct ThermConfig { - ThermConfig() - { - StaEnable = 1; //Enable WIFI Client - } - String StaSSID; String StaPassword; - uint8_t StaEnable; - - // ThermControl settings + bool StaEnable{true}; // Enable WIFI Client }; ThermConfig loadConfig(); diff --git a/samples/Basic_WebSkeletonApp/include/tytherm.h b/samples/Basic_WebSkeletonApp/include/tytherm.h deleted file mode 100644 index 5239e3df42..0000000000 --- a/samples/Basic_WebSkeletonApp/include/tytherm.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include "configuration.h" - -extern unsigned long counter; // Kind of heartbeat counter - -// Webserver -void startWebServer(); diff --git a/samples/Basic_WebSkeletonApp/include/webserver.h b/samples/Basic_WebSkeletonApp/include/webserver.h new file mode 100644 index 0000000000..0ea88af3fd --- /dev/null +++ b/samples/Basic_WebSkeletonApp/include/webserver.h @@ -0,0 +1,3 @@ +#pragma once + +void startWebServer(); diff --git a/samples/Basic_WebSkeletonApp_LTS/app/application.cpp b/samples/Basic_WebSkeletonApp_LTS/app/application.cpp index 2d3d341db2..6224c65df9 100644 --- a/samples/Basic_WebSkeletonApp_LTS/app/application.cpp +++ b/samples/Basic_WebSkeletonApp_LTS/app/application.cpp @@ -12,7 +12,6 @@ void init() spiffs_mount(); // Mount file system, in order to work with files Serial.begin(SERIAL_BAUD_RATE); // 115200 by default Serial.systemDebugOutput(false); - Serial.commandProcessing(false); // Set higher CPU freq & disable wifi sleep System.setCpuFrequency(CpuCycleClockFast::cpuFrequency()); @@ -26,7 +25,7 @@ void init() System.onReady(startWebServer); - counterTimer.initializeMs(1000, counterLoop).start(); + counterTimer.initializeMs<1000>(counterLoop).start(); } void counterLoop() diff --git a/samples/Basic_WiFi/app/application.cpp b/samples/Basic_WiFi/app/application.cpp index a9eed2e2b9..7de448f2ee 100644 --- a/samples/Basic_WiFi/app/application.cpp +++ b/samples/Basic_WiFi/app/application.cpp @@ -6,6 +6,8 @@ #define WIFI_PWD "PleaseEnterPass" #endif +namespace +{ // Will be called when WiFi station network scan was completed void listNetworks(bool succeeded, BssList& list) { @@ -14,9 +16,9 @@ void listNetworks(bool succeeded, BssList& list) return; } - for(unsigned i = 0; i < list.count(); i++) { - Serial << _F("\tWiFi: ") << list[i].ssid << ", " << list[i].getAuthorizationMethodName(); - if(list[i].hidden) { + for(auto& bss : list) { + Serial << _F("\tWiFi: ") << bss.ssid << ", " << bss.getAuthorizationMethodName(); + if(bss.hidden) { Serial << _F(" (hidden)"); } Serial.println(); @@ -60,6 +62,8 @@ void ready() } } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); diff --git a/samples/CanBus/app/application.cpp b/samples/CanBus/app/application.cpp index b616aae340..e36dbe58fd 100644 --- a/samples/CanBus/app/application.cpp +++ b/samples/CanBus/app/application.cpp @@ -3,9 +3,11 @@ #include #include -unsigned long rxId = 0; -uint8_t len = 0; -uint8_t rxBuf[8] = {0}; +namespace +{ +unsigned long rxId; +uint8_t len; +uint8_t rxBuf[8]; uint8_t txBuf0[] = {0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55}; uint8_t txBuf1[] = {0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA}; @@ -13,7 +15,7 @@ uint8_t txBuf1[] = {0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA}; MCP_CAN canBus0(10); // CAN0 interface using CS on digital pin 10 MCP_CAN canBus1(9); // CAN1 interface using CS on digital pin 9 -Timer loopTimer; +SimpleTimer loopTimer; SPISettings spiSettings{8000000, MSBFIRST, SPI_MODE3}; @@ -29,6 +31,8 @@ void loop() } } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); @@ -55,5 +59,5 @@ void init() canBus0.sendMsgBuf(0x1000000, 1, 8, txBuf0); canBus1.sendMsgBuf(0x1000001, 1, 8, txBuf1); - loopTimer.initializeMs(1000, loop).start(); + loopTimer.initializeMs<1000>(loop).start(); } diff --git a/samples/Compass_HMC5883L/app/application.cpp b/samples/Compass_HMC5883L/app/application.cpp index 471dfebccf..ee674bb2d3 100644 --- a/samples/Compass_HMC5883L/app/application.cpp +++ b/samples/Compass_HMC5883L/app/application.cpp @@ -1,15 +1,34 @@ #include #include +namespace +{ // class default I2C address is 0x1E // specific I2C addresses may be passed as a parameter here // this device only supports one I2C address (0x1E) HMC5883L mag; int16_t mx, my, mz; -Timer procTimer; +SimpleTimer procTimer; + +void readCompass() +{ + // read raw heading measurements from device + mag.getHeading(&mx, &my, &mz); + + // To calculate heading in degrees. 0 degree indicates North + float heading = atan2(my, mx); + if(heading < 0) { + heading += 2 * PI; + } else if(heading > 2 * PI) { + heading -= 2 * PI; + } + + // display tab-separated gyro x/y/z values and heading + Serial << "mag:\t" << mx << '\t' << my << '\t' << mz << "\theading:\t" << heading * RAD_TO_DEG << endl; +} -void readCompass(); +} // namespace void init() { @@ -28,22 +47,5 @@ void init() } // Start reading loop - procTimer.initializeMs(100, readCompass).start(); -} - -void readCompass() -{ - // read raw heading measurements from device - mag.getHeading(&mx, &my, &mz); - - // To calculate heading in degrees. 0 degree indicates North - float heading = atan2(my, mx); - if(heading < 0) { - heading += 2 * PI; - } else if(heading > 2 * PI) { - heading -= 2 * PI; - } - - // display tab-separated gyro x/y/z values and heading - Serial << "mag:\t" << mx << '\t' << my << '\t' << mz << "\theading:\t" << heading * RAD_TO_DEG << endl; + procTimer.initializeMs<100>(readCompass).start(); } diff --git a/samples/DFPlayerMini/README.rst b/samples/DFPlayerMini/README.rst index 49617dacac..97ecf8dbc9 100644 --- a/samples/DFPlayerMini/README.rst +++ b/samples/DFPlayerMini/README.rst @@ -15,8 +15,9 @@ https://www.dfrobot.com/wiki/index.php/DFPlayer_Mini_SKU:DFR0299 Building -------- -Steps to test this sample: \* Connect DFPlayer Mini using RX/TX pins to -TX/RX pins respectively of ESP8266. \* Copy one or more mp3 files to your -SD card. The example playes one file for some time and moves to the next -one. \* Insert your SD card in the slot of the DF Player module. \* -Flash and run the sample code. +Steps to test this sample: + +- Connect DFPlayer Mini using RX/TX pins to TX/RX pins respectively of ESP8266. +- Copy one or more mp3 files to your SD card. The example playes one file for some time and moves to the next one. +- Insert your SD card in the slot of the DF Player module. +- Flash and run the sample code. diff --git a/samples/DFPlayerMini/app/application.cpp b/samples/DFPlayerMini/app/application.cpp index 4dcdea9666..29580239b4 100644 --- a/samples/DFPlayerMini/app/application.cpp +++ b/samples/DFPlayerMini/app/application.cpp @@ -3,37 +3,40 @@ #define GPIO_LED 2 -Timer timerDFPlayer; -Timer timerLedBlink; -DFRobotDFPlayerMini player; -bool ledState = true; - -void blink() +namespace { - digitalWrite(GPIO_LED, ledState); - ledState = !ledState; -} +SimpleTimer timer; +DFRobotDFPlayerMini player; void nextSong() { player.next(); } -void init() +void checkReady() { - Serial.begin(9600); + static bool ledState; - pinMode(GPIO_LED, OUTPUT); - timerLedBlink.initializeMs(100, blink).start(); + ledState = !ledState; + digitalWrite(GPIO_LED, ledState); - while(!player.begin(Serial)) { - delay(500); + if(!player.begin(Serial)) { + return; } - timerLedBlink.stop(); digitalWrite(GPIO_LED, 0); player.volume(15); - timerDFPlayer.initializeMs(10000, nextSong).start(); + timer.initializeMs<10000>(nextSong).start(); +} + +} // namespace + +void init() +{ + Serial.begin(9600); + + pinMode(GPIO_LED, OUTPUT); + timer.initializeMs<250>(checkReady).start(); } diff --git a/samples/DS3232RTC_NTP_Setter/app/application.cpp b/samples/DS3232RTC_NTP_Setter/app/application.cpp index 802812dbfe..fba95fbf86 100644 --- a/samples/DS3232RTC_NTP_Setter/app/application.cpp +++ b/samples/DS3232RTC_NTP_Setter/app/application.cpp @@ -1,5 +1,4 @@ #include - #include #include @@ -9,39 +8,44 @@ #define WIFI_PWD "ENTER_YOUR_PASSWORD" #endif +namespace +{ // Change as required static constexpr uint8_t SDA_PIN{4}; static constexpr uint8_t SCL_PIN{5}; void onNtpReceive(NtpClient& client, time_t timestamp); -Timer printTimer; - NtpClient ntpClient(onNtpReceive); +SimpleTimer printTimer; void onPrintSystemTime() { DateTime rtcNow = DSRTC.get(); Serial.println(_F("Current time")); - Serial << _F(" System(LOCAL TZ): ") << SystemClock.getSystemTimeString() << endl; - Serial << _F(" UTC(UTC TZ): ") << SystemClock.getSystemTimeString(eTZ_UTC) << endl; - Serial << _F(" DSRTC(UTC TZ): ") << rtcNow.toFullDateTimeString() << endl; + Serial << _F(" System (LOCAL TZ): ") << SystemClock.getSystemTimeString() << endl; + Serial << _F(" UTC (UTC TZ): ") << SystemClock.getSystemTimeString(eTZ_UTC) << endl; + Serial << _F(" DSRTC (UTC TZ): ") << rtcNow.toFullDateTimeString() << endl; } void onNtpReceive(NtpClient& client, time_t timestamp) { - SystemClock.setTime(timestamp, eTZ_UTC); //System timezone is LOCAL so to set it from UTC we specify TZ - DSRTC.set(timestamp); //DSRTC timezone is UTC so we need TZ-correct DSRTC.get() + // Both System and DSRTC timezones are UTC + SystemClock.setTime(timestamp, eTZ_UTC); + DSRTC.set(timestamp); + // Display LOCAL time Serial << _F("Time synchronized: ") << SystemClock.getSystemTimeString() << endl; } void gotIP(IpAddress ip, IpAddress netmask, IpAddress gateway) { - debug_i("Got IP %s", ip.toString().c_str()); + Serial << _F("Got IP ") << ip << endl; ntpClient.requestTime(); } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); diff --git a/samples/Display_TM1637/app/application.cpp b/samples/Display_TM1637/app/application.cpp index 011a5fd917..14ae2294c8 100644 --- a/samples/Display_TM1637/app/application.cpp +++ b/samples/Display_TM1637/app/application.cpp @@ -8,105 +8,164 @@ // The amount of time (in milliseconds) between tests #define TEST_DELAY 500 -const uint8_t SEG_DONE[] = { +namespace +{ +const uint8_t SEG_DONE[4]{ SEG_B | SEG_C | SEG_D | SEG_E | SEG_G, // d SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F, // O SEG_C | SEG_E | SEG_G, // n SEG_A | SEG_D | SEG_E | SEG_F | SEG_G // E }; +const uint8_t SEG_ALL_OFF[4]{}; +const uint8_t SEG_ALL_ON[4]{0xff, 0xff, 0xff, 0xff}; TM1637Display display(CLK, DIO); +SimpleTimer stateTimer; -void testDisplay() +bool testDisplay() { - int k; - uint8_t data[] = {0xff, 0xff, 0xff, 0xff}; - display.setBrightness(0x0f); - - // All segments on - display.setSegments(data); - delay(TEST_DELAY); - - // Selectively set different digits - data[0] = 0b01001001; - data[1] = display.encodeDigit(1); - data[2] = display.encodeDigit(2); - data[3] = display.encodeDigit(3); - - for(k = 3; k >= 0; k--) { - display.setSegments(data, 1, k); - delay(TEST_DELAY); + static uint8_t state; + static uint8_t subState; + +#define STATE(fmt, ...) debug_i("#%u.%u " fmt, state, subState, ##__VA_ARGS__); + + switch(state) { + case 0: { + // All segments on + STATE("All segments on"); + display.setBrightness(7); + display.setSegments(SEG_ALL_ON); + break; } - - display.setSegments(data + 2, 2, 2); - delay(TEST_DELAY); - - display.setSegments(data + 2, 2, 1); - delay(TEST_DELAY); - - display.setSegments(data + 1, 3, 1); - delay(TEST_DELAY); - - // Show decimal numbers with/without leading zeros - bool lz = false; - for(uint8_t z = 0; z < 2; z++) { - for(k = 0; k < 10000; k += k * 4 + 7) { - display.showNumberDec(k, lz); - delay(TEST_DELAY); + case 1: { + // Selectively set different digits + uint8_t pos = 3 - subState; + STATE("setSegments(data, 1, %u)", pos); + const uint8_t seg = 0b01001001; + display.setSegments(&seg, 1, pos); + if(subState++ < 3) { + return false; } - lz = true; + break; } - - // Show decimal number whose length is smaller than 4 - for(k = 0; k < 4; k++) { - data[k] = 0; + case 2: { + uint8_t data[]{ + display.encodeDigit(1), + display.encodeDigit(2), + display.encodeDigit(3), + }; + uint8_t length = (subState == 2) ? 3 : 2; + uint8_t pos = (subState == 0) ? 2 : 1; + STATE("setSegments([0x%02x, 0x%02x, 0x%02x], %u, %u)", data[0], data[1], data[2], length, pos); + display.setSegments(data, length, pos); + if(subState++ < 3) { + return false; + } + break; } - display.setSegments(data); - - // Run through all the dots - for(k = 0; k <= 4; k++) { - display.showNumberDecEx(0, (0x80 >> k), true); - delay(TEST_DELAY); + case 3: + case 4: { + // Show decimal numbers with/without leading zeros + static unsigned k; + if(subState == 0) { + k = 0; + ++subState; + } + bool showLeadingZeroes = (state == 4); + STATE("showNumberDec(%u, %u)", k, showLeadingZeroes); + display.showNumberDec(k, showLeadingZeroes); + k += k * 4 + 7; + if(k < 10000) { + return false; + } + break; } - - display.showNumberDec(153, false, 3, 1); - delay(TEST_DELAY); - display.showNumberDec(22, false, 2, 2); - delay(TEST_DELAY); - display.showNumberDec(0, true, 1, 3); - delay(TEST_DELAY); - display.showNumberDec(0, true, 1, 2); - delay(TEST_DELAY); - display.showNumberDec(0, true, 1, 1); - delay(TEST_DELAY); - display.showNumberDec(0, true, 1, 0); - delay(TEST_DELAY); - - // Brightness Test - for(k = 0; k < 4; k++) { - data[k] = 0xff; + case 5: { + // Run through all the dots + display.setSegments(SEG_ALL_OFF); + uint8_t dots = 0x80 >> subState; + STATE("showNumberDec(0, 0x%02x, true)", dots); + display.showNumberDecEx(0, dots, true); + if(subState++ < 4) { + return false; + } + break; } - for(k = 0; k < 7; k++) { - display.setBrightness(k); - display.setSegments(data); - delay(TEST_DELAY); + case 6: { + // Show decimal number whose length is smaller than 4 + struct NumberArgs { + uint8_t num; + bool leadingZero; + uint8_t length; + uint8_t pos; + }; + const NumberArgs arglist[]{ + {153, false, 3, 1}, // + {22, false, 2, 2}, // + {0, true, 1, 3}, // + {0, true, 1, 2}, // + {0, true, 1, 1}, // + {0, true, 1, 0}, // + }; + auto& args = arglist[subState]; + STATE("showNumberDec(%u, %u, %u, %u)", args.num, args.leadingZero, args.length, args.pos); + display.showNumberDec(args.num, args.leadingZero, args.length, args.pos); + if(subState++ < ARRAY_SIZE(arglist)) { + return false; + } + break; } - - // On/Off test - for(k = 0; k < 4; k++) { - display.setBrightness(7, false); // Turn off - display.setSegments(data); - delay(TEST_DELAY); - display.setBrightness(7, true); // Turn on - display.setSegments(data); - delay(TEST_DELAY); + case 7: { + // Brightness Test + uint8_t brightness = subState; + STATE("setBrightness(%u)", brightness); + display.setBrightness(brightness); + display.setSegments(SEG_ALL_ON); + if(++subState < 7) { + return false; + } + break; + } + case 8: { + // On/Off test + bool onOff = subState & 0x01; + debug_i("setBrightness(7, %u)", onOff); + display.setBrightness(7, onOff); + display.setSegments(SEG_ALL_ON); + if(++subState < 8) { + return false; + } + break; + } + case 9: + // Done! + debug_i("Done!"); + display.setSegments(SEG_DONE); + return true; } - // Done! - display.setSegments(SEG_DONE); + ++state; + subState = 0; + return false; } +} // namespace + void init() { - testDisplay(); + Serial.begin(SERIAL_BAUD_RATE); + Serial.systemDebugOutput(true); + + Serial << _F("Sample TM1637 application") << endl; + +#ifdef ARCH_HOST + setDigitalHooks(nullptr); +#endif + + stateTimer.initializeMs([]() { + if(!testDisplay()) { + stateTimer.startOnce(); + } + }); + stateTimer.startOnce(); } diff --git a/samples/Distance_Vl53l0x/app/application.cpp b/samples/Distance_Vl53l0x/app/application.cpp index 3a5e97a96b..2a5e2251c0 100644 --- a/samples/Distance_Vl53l0x/app/application.cpp +++ b/samples/Distance_Vl53l0x/app/application.cpp @@ -1,15 +1,16 @@ #include #include -Adafruit_VL53L0X lox; - // GPIO - NodeMCU pins #define SDA 4 // D2 #define SCL 5 // D1 #define XSHUT 14 // D5 #define INT 12 // D6 -Timer loopTimer; +namespace +{ +Adafruit_VL53L0X lox; +SimpleTimer loopTimer; void loop() { @@ -25,6 +26,8 @@ void loop() } } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); // 115200 by default diff --git a/samples/DnsCaptivePortal/app/application.cpp b/samples/DnsCaptivePortal/app/application.cpp index c06c947f1f..5e599afcc2 100644 --- a/samples/DnsCaptivePortal/app/application.cpp +++ b/samples/DnsCaptivePortal/app/application.cpp @@ -1,14 +1,16 @@ #include +#define DNS_PORT 53 + +namespace +{ DnsServer dnsServer; HttpServer server; -#define DNS_PORT 53 - void onIndex(HttpRequest& request, HttpResponse& response) { response.setContentType(MIME_HTML); - response.sendString("SMING captive portal"); + response.sendString(F("SMING captive portal")); } void startWebServer() @@ -25,6 +27,8 @@ void startServers() startWebServer(); } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); // 115200 by default @@ -33,7 +37,7 @@ void init() // Start AP WifiStation.enable(false); WifiAccessPoint.enable(true); - WifiAccessPoint.config("DNSCaptive Portal", "", AUTH_OPEN); + WifiAccessPoint.config(F("DNSCaptive Portal"), nullptr, AUTH_OPEN); System.onReady(startServers); } diff --git a/samples/Echo_Ssl/app/application.cpp b/samples/Echo_Ssl/app/application.cpp index 348cede4e6..87f582a348 100644 --- a/samples/Echo_Ssl/app/application.cpp +++ b/samples/Echo_Ssl/app/application.cpp @@ -19,7 +19,9 @@ #define SERVER_IP "127.0.0.1" #endif -Timer procTimer; +namespace +{ +SimpleTimer procTimer; TcpClient* client; bool showMeta = true; @@ -53,12 +55,14 @@ void connectFail(const String& ssid, MacAddress bssid, WifiDisconnectReason reas void gotIP(IpAddress ip, IpAddress netmask, IpAddress gateway) { - debugf("IP: %s", ip.toString().c_str()); + Serial << _F("Got IP ") << ip << endl; client = new TcpClient(TcpClientDataDelegate(onReceive)); client->setSslInitHandler([](Ssl::Session& session) { session.options.verifyLater = true; }); client->connect(IpAddress(SERVER_IP), 4444, true); } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); @@ -66,7 +70,7 @@ void init() // Setup the WIFI connection WifiStation.enable(true); - WifiStation.config(WIFI_SSID, WIFI_PWD); // Put your SSID and password here + WifiStation.config(WIFI_SSID, WIFI_PWD); // Run our method when station was connected to AP (or not connected) WifiEvents.onStationDisconnect(connectFail); diff --git a/samples/Echo_Ssl/component.mk b/samples/Echo_Ssl/component.mk index ae82bad52a..a252892ef8 100644 --- a/samples/Echo_Ssl/component.mk +++ b/samples/Echo_Ssl/component.mk @@ -1 +1 @@ -ENABLE_SSL = 1 +ENABLE_SSL ?= 1 diff --git a/samples/Echo_Ssl/include/ssl/cert.h b/samples/Echo_Ssl/include/ssl/cert.h deleted file mode 100644 index 61ca8a654e..0000000000 --- a/samples/Echo_Ssl/include/ssl/cert.h +++ /dev/null @@ -1,27 +0,0 @@ -unsigned char default_certificate[] = { - 0x30, 0x82, 0x01, 0xd7, 0x30, 0x82, 0x01, 0x40, 0x02, 0x09, 0x00, 0xab, 0x08, 0x18, 0xa7, 0x03, 0x07, 0x27, 0xfd, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x34, 0x31, 0x32, - 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x29, 0x61, 0x78, 0x54, 0x4c, 0x53, 0x20, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x20, 0x44, 0x6f, 0x64, 0x67, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x31, - 0x32, 0x32, 0x36, 0x32, 0x32, 0x33, 0x33, 0x33, 0x39, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x39, 0x30, 0x33, 0x32, - 0x32, 0x33, 0x33, 0x33, 0x39, 0x5a, 0x30, 0x2c, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, - 0x61, 0x78, 0x54, 0x4c, 0x53, 0x20, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x13, 0x09, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x30, 0x81, 0x9f, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, - 0x89, 0x02, 0x81, 0x81, 0x00, 0xcd, 0xfd, 0x89, 0x48, 0xbe, 0x36, 0xb9, 0x95, 0x76, 0xd4, 0x13, 0x30, 0x0e, 0xbf, - 0xb2, 0xed, 0x67, 0x0a, 0xc0, 0x16, 0x3f, 0x51, 0x09, 0x9d, 0x29, 0x2f, 0xb2, 0x6d, 0x3f, 0x3e, 0x6c, 0x2f, 0x90, - 0x80, 0xa1, 0x71, 0xdf, 0xbe, 0x38, 0xc5, 0xcb, 0xa9, 0x9a, 0x40, 0x14, 0x90, 0x0a, 0xf9, 0xb7, 0x07, 0x0b, 0xe1, - 0xda, 0xe7, 0x09, 0xbf, 0x0d, 0x57, 0x41, 0x86, 0x60, 0xa1, 0xc1, 0x27, 0x91, 0x5b, 0x0a, 0x98, 0x46, 0x1b, 0xf6, - 0xa2, 0x84, 0xf8, 0x65, 0xc7, 0xce, 0x2d, 0x96, 0x17, 0xaa, 0x91, 0xf8, 0x61, 0x04, 0x50, 0x70, 0xeb, 0xb4, 0x43, - 0xb7, 0xdc, 0x9a, 0xcc, 0x31, 0x01, 0x14, 0xd4, 0xcd, 0xcc, 0xc2, 0x37, 0x6d, 0x69, 0x82, 0xd6, 0xc6, 0xc4, 0xbe, - 0xf2, 0x34, 0xa5, 0xc9, 0xa6, 0x19, 0x53, 0x32, 0x7a, 0x86, 0x0e, 0x91, 0x82, 0x0f, 0xa1, 0x42, 0x54, 0xaa, 0x01, - 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, - 0x00, 0x03, 0x81, 0x81, 0x00, 0x40, 0xb4, 0x94, 0x9a, 0xa8, 0x89, 0x72, 0x1d, 0x07, 0xe5, 0xb3, 0x6b, 0x88, 0x21, - 0xc2, 0x38, 0x36, 0x9e, 0x7a, 0x8c, 0x49, 0x48, 0x68, 0x0c, 0x06, 0xe8, 0xdb, 0x1f, 0x4e, 0x05, 0xe6, 0x31, 0xe3, - 0xfd, 0xe6, 0x0d, 0x6b, 0xd8, 0x13, 0x17, 0xe0, 0x2d, 0x0d, 0xb8, 0x7e, 0xcb, 0x20, 0x6c, 0xa8, 0x73, 0xa7, 0xfd, - 0xe3, 0xa7, 0xfa, 0xf3, 0x02, 0x60, 0x78, 0x1f, 0x13, 0x40, 0x45, 0xee, 0x75, 0xf5, 0x10, 0xfd, 0x8f, 0x68, 0x74, - 0xd4, 0xac, 0xae, 0x04, 0x09, 0x55, 0x2c, 0xdb, 0xd8, 0x07, 0x07, 0x65, 0x69, 0x27, 0x6e, 0xbf, 0x5e, 0x61, 0x40, - 0x56, 0x8b, 0xd7, 0x33, 0x3b, 0xff, 0x6e, 0x53, 0x7e, 0x9d, 0x3f, 0xc0, 0x40, 0x3a, 0xab, 0xa0, 0x50, 0x4e, 0x80, - 0x47, 0x46, 0x0d, 0x1e, 0xdb, 0x4c, 0xf1, 0x1b, 0x5d, 0x3c, 0x2a, 0x54, 0xa7, 0x4d, 0xfa, 0x7b, 0x72, 0x66, 0xc5}; -unsigned int default_certificate_len = 475; diff --git a/samples/Echo_Ssl/include/ssl/private_key.h b/samples/Echo_Ssl/include/ssl/private_key.h deleted file mode 100644 index 31de50cb53..0000000000 --- a/samples/Echo_Ssl/include/ssl/private_key.h +++ /dev/null @@ -1,35 +0,0 @@ -unsigned char default_private_key[] = { - 0x30, 0x82, 0x02, 0x5d, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xcd, 0xfd, 0x89, 0x48, 0xbe, 0x36, 0xb9, 0x95, - 0x76, 0xd4, 0x13, 0x30, 0x0e, 0xbf, 0xb2, 0xed, 0x67, 0x0a, 0xc0, 0x16, 0x3f, 0x51, 0x09, 0x9d, 0x29, 0x2f, 0xb2, - 0x6d, 0x3f, 0x3e, 0x6c, 0x2f, 0x90, 0x80, 0xa1, 0x71, 0xdf, 0xbe, 0x38, 0xc5, 0xcb, 0xa9, 0x9a, 0x40, 0x14, 0x90, - 0x0a, 0xf9, 0xb7, 0x07, 0x0b, 0xe1, 0xda, 0xe7, 0x09, 0xbf, 0x0d, 0x57, 0x41, 0x86, 0x60, 0xa1, 0xc1, 0x27, 0x91, - 0x5b, 0x0a, 0x98, 0x46, 0x1b, 0xf6, 0xa2, 0x84, 0xf8, 0x65, 0xc7, 0xce, 0x2d, 0x96, 0x17, 0xaa, 0x91, 0xf8, 0x61, - 0x04, 0x50, 0x70, 0xeb, 0xb4, 0x43, 0xb7, 0xdc, 0x9a, 0xcc, 0x31, 0x01, 0x14, 0xd4, 0xcd, 0xcc, 0xc2, 0x37, 0x6d, - 0x69, 0x82, 0xd6, 0xc6, 0xc4, 0xbe, 0xf2, 0x34, 0xa5, 0xc9, 0xa6, 0x19, 0x53, 0x32, 0x7a, 0x86, 0x0e, 0x91, 0x82, - 0x0f, 0xa1, 0x42, 0x54, 0xaa, 0x01, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x81, 0x81, 0x00, 0x95, 0xaa, 0x6e, 0x11, - 0xf5, 0x6a, 0x8b, 0xa2, 0xc6, 0x48, 0xc6, 0x7c, 0x37, 0x6b, 0x1f, 0x55, 0x10, 0x76, 0x26, 0x24, 0xc3, 0xf2, 0x5c, - 0x5a, 0xdd, 0x2e, 0xf3, 0xa4, 0x1e, 0xbc, 0x7b, 0x1c, 0x80, 0x10, 0x85, 0xbc, 0xd8, 0x45, 0x3c, 0xb8, 0xb2, 0x06, - 0x53, 0xb5, 0xd5, 0x7a, 0xe7, 0x0e, 0x92, 0xe6, 0x42, 0xc2, 0xe2, 0x2a, 0xd5, 0xd1, 0x03, 0x9f, 0x6f, 0x53, 0x74, - 0x68, 0x72, 0x8e, 0xbf, 0x03, 0xbb, 0xab, 0xbd, 0xa1, 0xf9, 0x81, 0x7d, 0x12, 0xd4, 0x9d, 0xb6, 0xae, 0x4c, 0xad, - 0xca, 0xa8, 0xc9, 0x80, 0x8d, 0x0d, 0xd5, 0xd0, 0xa1, 0xbf, 0xec, 0x60, 0x48, 0x49, 0xed, 0x97, 0x0f, 0x5e, 0xed, - 0xfc, 0x39, 0x15, 0x96, 0x9e, 0x5d, 0xe2, 0xb4, 0x5d, 0x2e, 0x04, 0xdc, 0x08, 0xa2, 0x65, 0x29, 0x2d, 0x37, 0xfb, - 0x62, 0x90, 0x1b, 0x7b, 0xe5, 0x3a, 0x58, 0x05, 0x55, 0xc1, 0x02, 0x41, 0x00, 0xfc, 0x69, 0x28, 0xc9, 0xa8, 0xc4, - 0x5c, 0xe3, 0xd0, 0x5e, 0xaa, 0xda, 0xde, 0x87, 0x74, 0xdb, 0xcb, 0x40, 0x78, 0x8e, 0x1d, 0x12, 0x96, 0x16, 0x61, - 0x3f, 0xb3, 0x3e, 0xa3, 0x0d, 0xdc, 0x49, 0xa5, 0x25, 0x87, 0xc5, 0x97, 0x85, 0x9d, 0xbb, 0xb4, 0xf0, 0x44, 0xfd, - 0x6c, 0xe8, 0xd2, 0x8c, 0xec, 0x33, 0x81, 0x46, 0x1e, 0x10, 0x12, 0x33, 0x16, 0x95, 0x00, 0x4f, 0x75, 0xb4, 0xe5, - 0x79, 0x02, 0x41, 0x00, 0xd0, 0xeb, 0x65, 0x07, 0x10, 0x3b, 0xd9, 0x03, 0xeb, 0xdc, 0x6f, 0x4b, 0x8f, 0xc3, 0x87, - 0xce, 0x76, 0xd6, 0xc5, 0x14, 0x21, 0x4e, 0xe7, 0x4f, 0x1b, 0xe8, 0x05, 0xf8, 0x84, 0x1a, 0xe0, 0xc5, 0xd6, 0xe3, - 0x08, 0xb3, 0x54, 0x57, 0x02, 0x1f, 0xd4, 0xd9, 0xfb, 0xff, 0x40, 0xb1, 0x56, 0x1c, 0x60, 0xf7, 0xac, 0x91, 0xf3, - 0xd3, 0xc6, 0x7f, 0x84, 0xfd, 0x84, 0x9d, 0xea, 0x26, 0xee, 0xc9, 0x02, 0x41, 0x00, 0xa6, 0xcf, 0x1c, 0x6c, 0x81, - 0x03, 0x1c, 0x5c, 0x56, 0x05, 0x6a, 0x26, 0x70, 0xef, 0xd6, 0x13, 0xb7, 0x74, 0x28, 0xf7, 0xca, 0x50, 0xd1, 0x2d, - 0x83, 0x21, 0x64, 0xe4, 0xdd, 0x3f, 0x38, 0xb8, 0xd6, 0xd2, 0x41, 0xb3, 0x1c, 0x9a, 0xea, 0x0d, 0xf5, 0xda, 0xdf, - 0xcd, 0x17, 0x9f, 0x9a, 0x1e, 0x15, 0xaf, 0x48, 0x1c, 0xbd, 0x9b, 0x63, 0x5b, 0xad, 0xed, 0xd4, 0xa1, 0xae, 0xa9, - 0x59, 0x09, 0x02, 0x40, 0x4e, 0x08, 0xce, 0xa8, 0x8f, 0xc0, 0xba, 0xf3, 0x83, 0x02, 0xc8, 0x33, 0x62, 0x14, 0x77, - 0xc2, 0x7f, 0x93, 0x02, 0xf3, 0xdc, 0xe9, 0x1a, 0xee, 0xea, 0x8e, 0x84, 0xc4, 0x69, 0x9b, 0x9c, 0x7f, 0x69, 0x1f, - 0x4e, 0x1d, 0xa5, 0x90, 0x06, 0x44, 0x1b, 0x7d, 0xfc, 0x69, 0x40, 0x21, 0xbc, 0xf7, 0x46, 0xa4, 0xdc, 0x39, 0x7b, - 0xe8, 0x8b, 0x49, 0x10, 0x44, 0x9d, 0x67, 0x5a, 0x91, 0x86, 0x39, 0x02, 0x40, 0x41, 0x2c, 0x4e, 0xfe, 0xd9, 0x90, - 0x89, 0x00, 0x5c, 0x94, 0x0a, 0x4a, 0x7e, 0x1b, 0x1a, 0x80, 0x06, 0x01, 0x37, 0xda, 0x50, 0x61, 0x9d, 0x9c, 0xfe, - 0x25, 0x7f, 0xd8, 0xd4, 0xc4, 0x9e, 0x81, 0xf2, 0x0c, 0x1e, 0x38, 0x21, 0x1e, 0x90, 0x3f, 0xd4, 0xba, 0x6c, 0x53, - 0xcb, 0xf0, 0x77, 0x79, 0x9b, 0xf1, 0xfa, 0x3f, 0x81, 0xdc, 0xf3, 0x21, 0x02, 0x6d, 0xb7, 0x95, 0xc3, 0x2e, 0xce, - 0xd5}; -unsigned int default_private_key_len = 609; diff --git a/samples/FtpServer_Files/app/application.cpp b/samples/FtpServer_Files/app/application.cpp index 0b659e560b..9cace75c77 100644 --- a/samples/FtpServer_Files/app/application.cpp +++ b/samples/FtpServer_Files/app/application.cpp @@ -6,11 +6,13 @@ #define WIFI_PWD "PleaseEnterPass" #endif +namespace +{ FtpServer ftp; void gotIP(IpAddress ip, IpAddress netmask, IpAddress gateway) { - Serial << "IP: " << ip << endl; + Serial << _F("Got IP ") << ip << endl; // Start FTP server ftp.listen(21); // Add user accounts @@ -26,6 +28,8 @@ void connectFail(const String& ssid, MacAddress bssid, WifiDisconnectReason reas Serial.println(_F("I'm NOT CONNECTED. Need help!!! :(")); } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); // 115200 by default @@ -51,7 +55,7 @@ void init() * When a file is opened for writing it is transparently copied to the SPIFFS partition so it can be updated. * Wiping the SPIFFS partition reverts the filesystem to its original state. * - * Note that files marked as ‘read-only’ may not be written in this manner. + * Note that files marked as 'read-only' may not be written in this manner. */ hyfs_mount(); diff --git a/samples/FtpServer_Files/ftpserver-esp32.hw b/samples/FtpServer_Files/ftpserver-esp32.hw index 3fd3cdb1e4..b655c3b0db 100644 --- a/samples/FtpServer_Files/ftpserver-esp32.hw +++ b/samples/FtpServer_Files/ftpserver-esp32.hw @@ -1,5 +1,5 @@ { - "name": "FTP Server sample", + "name": "FTP Server sample (ESP32)", "base_config": "ftpserver", "partitions": { "factory": { diff --git a/samples/FtpServer_Files/ftpserver-esp8266.hw b/samples/FtpServer_Files/ftpserver-esp8266.hw index c1aedd3b6b..8a8c73f151 100644 --- a/samples/FtpServer_Files/ftpserver-esp8266.hw +++ b/samples/FtpServer_Files/ftpserver-esp8266.hw @@ -1,5 +1,5 @@ { - "name": "FTP Server sample", + "name": "FTP Server sample (ESP8266)", "base_config": "ftpserver", "partitions": { "rom0": { diff --git a/samples/Gesture_APDS-9960/app/application.cpp b/samples/Gesture_APDS-9960/app/application.cpp index 3018d2b7c0..1ecd19215a 100644 --- a/samples/Gesture_APDS-9960/app/application.cpp +++ b/samples/Gesture_APDS-9960/app/application.cpp @@ -1,49 +1,59 @@ #include -#include +#include -SparkFun_APDS9960 apds = SparkFun_APDS9960(); +namespace +{ +SparkFun_APDS9960 apds; // For I2C // Default I2C pins 0 and 2. Pin 4 - interrupt pin // -#define APDS9960_INT 4 // Needs to be an interrupt pin +#define APDS9960_INT 4 + +String dirToString(unsigned dir) +{ + switch(dir) { + case DIR_NONE: + return F("NONE"); + case DIR_LEFT: + return F("LEFT"); + case DIR_RIGHT: + return F("RIGHT"); + case DIR_UP: + return F("UP"); + case DIR_DOWN: + return F("DOWN"); + case DIR_NEAR: + return F("NEAR"); + case DIR_FAR: + return F("FAR"); + case DIR_ALL: + return F("ALL"); + default: + return nullptr; + } +} void handleGesture() { - if(apds.isGestureAvailable()) { - switch(apds.readGesture()) { - case DIR_UP: - Serial.println(_F("UP")); - break; - case DIR_DOWN: - Serial.println(_F("DOWN")); - break; - case DIR_LEFT: - Serial.println(_F("LEFT")); - break; - case DIR_RIGHT: - Serial.println(_F("RIGHT")); - break; - case DIR_NEAR: - Serial.println(_F("NEAR")); - break; - case DIR_FAR: - Serial.println(_F("FAR")); - break; - default: - Serial.println(_F("NONE")); - } + if(!apds.isGestureAvailable()) { + return; } + + auto dir = apds.readGesture(); + Serial.println(dirToString(dir)); } -void interruptRoutine() +void interruptDelegate() { detachInterrupt(APDS9960_INT); handleGesture(); - attachInterrupt(APDS9960_INT, InterruptDelegate(interruptRoutine), FALLING); + attachInterrupt(APDS9960_INT, InterruptDelegate(interruptDelegate), FALLING); } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); // 115200 by default @@ -61,20 +71,22 @@ void init() "--------------------------------\r\n")); // Initialize APDS-9960 (configure I2C and initial values) - if(apds.init()) { - Serial.println(_F("APDS-9960 initialization complete")); - } else { + if(!apds.init()) { Serial.println(_F("Something went wrong during APDS-9960 init!")); + return; } + Serial.println(_F("APDS-9960 initialization complete")); + // Start running the APDS-9960 gesture sensor engine - if(apds.enableGestureSensor(true)) { - Serial.println(_F("Gesture sensor is now running")); - } else { + if(!apds.enableGestureSensor(true)) { Serial.println(_F("Something went wrong during gesture sensor init!")); + return; } + Serial.println(_F("Gesture sensor is now running")); + // Initialize interrupt service routine - pinMode(APDS9960_INT, (GPIO_INT_TYPE)GPIO_PIN_INTR_ANYEDGE); - attachInterrupt(APDS9960_INT, InterruptDelegate(interruptRoutine), FALLING); + pinMode(APDS9960_INT, GPIO_PIN_INTR_ANYEDGE); + attachInterrupt(APDS9960_INT, InterruptDelegate(interruptDelegate), FALLING); } diff --git a/samples/HttpClient/app/application.cpp b/samples/HttpClient/app/application.cpp index ed50d78ad8..ed64810044 100644 --- a/samples/HttpClient/app/application.cpp +++ b/samples/HttpClient/app/application.cpp @@ -7,19 +7,25 @@ #define WIFI_PWD "PleaseEnterPass" #endif +namespace +{ HttpClient httpClient; int onDownload(HttpConnection& connection, bool success) { - debugf("\n=========[ URL: %s ]============", connection.getRequest()->uri.toString().c_str()); - debugf("RemoteIP: %s", connection.getRemoteIp().toString().c_str()); - debugf("Got response code: %d", connection.getResponse()->code); - debugf("Success: %d", success); - if(connection.getRequest()->method != HTTP_HEAD) { + auto& request = *connection.getRequest(); + auto& response = *connection.getResponse(); + + Serial << endl << _F("=========[ URL: ") << request.uri << _F(" ]============") << endl; + Serial << _F("RemoteIP: ") << connection.getRemoteIp() << endl; + Serial << _F("Got response code: ") << response.code << " " << toString(response.code) << endl; + Serial << _F("Success: ") << success << " " << (success ? "OK" : "FAIL") << endl; + + if(request.method != HTTP_HEAD) { Serial.print(_F("Got content: ")); - auto stream = connection.getResponse()->stream; + auto stream = response.stream; if(stream == nullptr || stream->available() == 0) { - Serial.println("EMPTY!"); + Serial.println(_F("EMPTY!")); } else { Serial.copyFrom(stream); Serial.println(); @@ -146,6 +152,8 @@ void connectOk(IpAddress ip, IpAddress mask, IpAddress gateway) httpClient.send(putRequest); } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); diff --git a/samples/HttpClient/include/ssl/cert.h b/samples/HttpClient/include/ssl/cert.h deleted file mode 100644 index 61ca8a654e..0000000000 --- a/samples/HttpClient/include/ssl/cert.h +++ /dev/null @@ -1,27 +0,0 @@ -unsigned char default_certificate[] = { - 0x30, 0x82, 0x01, 0xd7, 0x30, 0x82, 0x01, 0x40, 0x02, 0x09, 0x00, 0xab, 0x08, 0x18, 0xa7, 0x03, 0x07, 0x27, 0xfd, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x34, 0x31, 0x32, - 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x29, 0x61, 0x78, 0x54, 0x4c, 0x53, 0x20, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x20, 0x44, 0x6f, 0x64, 0x67, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x31, - 0x32, 0x32, 0x36, 0x32, 0x32, 0x33, 0x33, 0x33, 0x39, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x39, 0x30, 0x33, 0x32, - 0x32, 0x33, 0x33, 0x33, 0x39, 0x5a, 0x30, 0x2c, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, - 0x61, 0x78, 0x54, 0x4c, 0x53, 0x20, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x13, 0x09, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x30, 0x81, 0x9f, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, - 0x89, 0x02, 0x81, 0x81, 0x00, 0xcd, 0xfd, 0x89, 0x48, 0xbe, 0x36, 0xb9, 0x95, 0x76, 0xd4, 0x13, 0x30, 0x0e, 0xbf, - 0xb2, 0xed, 0x67, 0x0a, 0xc0, 0x16, 0x3f, 0x51, 0x09, 0x9d, 0x29, 0x2f, 0xb2, 0x6d, 0x3f, 0x3e, 0x6c, 0x2f, 0x90, - 0x80, 0xa1, 0x71, 0xdf, 0xbe, 0x38, 0xc5, 0xcb, 0xa9, 0x9a, 0x40, 0x14, 0x90, 0x0a, 0xf9, 0xb7, 0x07, 0x0b, 0xe1, - 0xda, 0xe7, 0x09, 0xbf, 0x0d, 0x57, 0x41, 0x86, 0x60, 0xa1, 0xc1, 0x27, 0x91, 0x5b, 0x0a, 0x98, 0x46, 0x1b, 0xf6, - 0xa2, 0x84, 0xf8, 0x65, 0xc7, 0xce, 0x2d, 0x96, 0x17, 0xaa, 0x91, 0xf8, 0x61, 0x04, 0x50, 0x70, 0xeb, 0xb4, 0x43, - 0xb7, 0xdc, 0x9a, 0xcc, 0x31, 0x01, 0x14, 0xd4, 0xcd, 0xcc, 0xc2, 0x37, 0x6d, 0x69, 0x82, 0xd6, 0xc6, 0xc4, 0xbe, - 0xf2, 0x34, 0xa5, 0xc9, 0xa6, 0x19, 0x53, 0x32, 0x7a, 0x86, 0x0e, 0x91, 0x82, 0x0f, 0xa1, 0x42, 0x54, 0xaa, 0x01, - 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, - 0x00, 0x03, 0x81, 0x81, 0x00, 0x40, 0xb4, 0x94, 0x9a, 0xa8, 0x89, 0x72, 0x1d, 0x07, 0xe5, 0xb3, 0x6b, 0x88, 0x21, - 0xc2, 0x38, 0x36, 0x9e, 0x7a, 0x8c, 0x49, 0x48, 0x68, 0x0c, 0x06, 0xe8, 0xdb, 0x1f, 0x4e, 0x05, 0xe6, 0x31, 0xe3, - 0xfd, 0xe6, 0x0d, 0x6b, 0xd8, 0x13, 0x17, 0xe0, 0x2d, 0x0d, 0xb8, 0x7e, 0xcb, 0x20, 0x6c, 0xa8, 0x73, 0xa7, 0xfd, - 0xe3, 0xa7, 0xfa, 0xf3, 0x02, 0x60, 0x78, 0x1f, 0x13, 0x40, 0x45, 0xee, 0x75, 0xf5, 0x10, 0xfd, 0x8f, 0x68, 0x74, - 0xd4, 0xac, 0xae, 0x04, 0x09, 0x55, 0x2c, 0xdb, 0xd8, 0x07, 0x07, 0x65, 0x69, 0x27, 0x6e, 0xbf, 0x5e, 0x61, 0x40, - 0x56, 0x8b, 0xd7, 0x33, 0x3b, 0xff, 0x6e, 0x53, 0x7e, 0x9d, 0x3f, 0xc0, 0x40, 0x3a, 0xab, 0xa0, 0x50, 0x4e, 0x80, - 0x47, 0x46, 0x0d, 0x1e, 0xdb, 0x4c, 0xf1, 0x1b, 0x5d, 0x3c, 0x2a, 0x54, 0xa7, 0x4d, 0xfa, 0x7b, 0x72, 0x66, 0xc5}; -unsigned int default_certificate_len = 475; diff --git a/samples/HttpClient/include/ssl/private_key.h b/samples/HttpClient/include/ssl/private_key.h deleted file mode 100644 index 31de50cb53..0000000000 --- a/samples/HttpClient/include/ssl/private_key.h +++ /dev/null @@ -1,35 +0,0 @@ -unsigned char default_private_key[] = { - 0x30, 0x82, 0x02, 0x5d, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xcd, 0xfd, 0x89, 0x48, 0xbe, 0x36, 0xb9, 0x95, - 0x76, 0xd4, 0x13, 0x30, 0x0e, 0xbf, 0xb2, 0xed, 0x67, 0x0a, 0xc0, 0x16, 0x3f, 0x51, 0x09, 0x9d, 0x29, 0x2f, 0xb2, - 0x6d, 0x3f, 0x3e, 0x6c, 0x2f, 0x90, 0x80, 0xa1, 0x71, 0xdf, 0xbe, 0x38, 0xc5, 0xcb, 0xa9, 0x9a, 0x40, 0x14, 0x90, - 0x0a, 0xf9, 0xb7, 0x07, 0x0b, 0xe1, 0xda, 0xe7, 0x09, 0xbf, 0x0d, 0x57, 0x41, 0x86, 0x60, 0xa1, 0xc1, 0x27, 0x91, - 0x5b, 0x0a, 0x98, 0x46, 0x1b, 0xf6, 0xa2, 0x84, 0xf8, 0x65, 0xc7, 0xce, 0x2d, 0x96, 0x17, 0xaa, 0x91, 0xf8, 0x61, - 0x04, 0x50, 0x70, 0xeb, 0xb4, 0x43, 0xb7, 0xdc, 0x9a, 0xcc, 0x31, 0x01, 0x14, 0xd4, 0xcd, 0xcc, 0xc2, 0x37, 0x6d, - 0x69, 0x82, 0xd6, 0xc6, 0xc4, 0xbe, 0xf2, 0x34, 0xa5, 0xc9, 0xa6, 0x19, 0x53, 0x32, 0x7a, 0x86, 0x0e, 0x91, 0x82, - 0x0f, 0xa1, 0x42, 0x54, 0xaa, 0x01, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x81, 0x81, 0x00, 0x95, 0xaa, 0x6e, 0x11, - 0xf5, 0x6a, 0x8b, 0xa2, 0xc6, 0x48, 0xc6, 0x7c, 0x37, 0x6b, 0x1f, 0x55, 0x10, 0x76, 0x26, 0x24, 0xc3, 0xf2, 0x5c, - 0x5a, 0xdd, 0x2e, 0xf3, 0xa4, 0x1e, 0xbc, 0x7b, 0x1c, 0x80, 0x10, 0x85, 0xbc, 0xd8, 0x45, 0x3c, 0xb8, 0xb2, 0x06, - 0x53, 0xb5, 0xd5, 0x7a, 0xe7, 0x0e, 0x92, 0xe6, 0x42, 0xc2, 0xe2, 0x2a, 0xd5, 0xd1, 0x03, 0x9f, 0x6f, 0x53, 0x74, - 0x68, 0x72, 0x8e, 0xbf, 0x03, 0xbb, 0xab, 0xbd, 0xa1, 0xf9, 0x81, 0x7d, 0x12, 0xd4, 0x9d, 0xb6, 0xae, 0x4c, 0xad, - 0xca, 0xa8, 0xc9, 0x80, 0x8d, 0x0d, 0xd5, 0xd0, 0xa1, 0xbf, 0xec, 0x60, 0x48, 0x49, 0xed, 0x97, 0x0f, 0x5e, 0xed, - 0xfc, 0x39, 0x15, 0x96, 0x9e, 0x5d, 0xe2, 0xb4, 0x5d, 0x2e, 0x04, 0xdc, 0x08, 0xa2, 0x65, 0x29, 0x2d, 0x37, 0xfb, - 0x62, 0x90, 0x1b, 0x7b, 0xe5, 0x3a, 0x58, 0x05, 0x55, 0xc1, 0x02, 0x41, 0x00, 0xfc, 0x69, 0x28, 0xc9, 0xa8, 0xc4, - 0x5c, 0xe3, 0xd0, 0x5e, 0xaa, 0xda, 0xde, 0x87, 0x74, 0xdb, 0xcb, 0x40, 0x78, 0x8e, 0x1d, 0x12, 0x96, 0x16, 0x61, - 0x3f, 0xb3, 0x3e, 0xa3, 0x0d, 0xdc, 0x49, 0xa5, 0x25, 0x87, 0xc5, 0x97, 0x85, 0x9d, 0xbb, 0xb4, 0xf0, 0x44, 0xfd, - 0x6c, 0xe8, 0xd2, 0x8c, 0xec, 0x33, 0x81, 0x46, 0x1e, 0x10, 0x12, 0x33, 0x16, 0x95, 0x00, 0x4f, 0x75, 0xb4, 0xe5, - 0x79, 0x02, 0x41, 0x00, 0xd0, 0xeb, 0x65, 0x07, 0x10, 0x3b, 0xd9, 0x03, 0xeb, 0xdc, 0x6f, 0x4b, 0x8f, 0xc3, 0x87, - 0xce, 0x76, 0xd6, 0xc5, 0x14, 0x21, 0x4e, 0xe7, 0x4f, 0x1b, 0xe8, 0x05, 0xf8, 0x84, 0x1a, 0xe0, 0xc5, 0xd6, 0xe3, - 0x08, 0xb3, 0x54, 0x57, 0x02, 0x1f, 0xd4, 0xd9, 0xfb, 0xff, 0x40, 0xb1, 0x56, 0x1c, 0x60, 0xf7, 0xac, 0x91, 0xf3, - 0xd3, 0xc6, 0x7f, 0x84, 0xfd, 0x84, 0x9d, 0xea, 0x26, 0xee, 0xc9, 0x02, 0x41, 0x00, 0xa6, 0xcf, 0x1c, 0x6c, 0x81, - 0x03, 0x1c, 0x5c, 0x56, 0x05, 0x6a, 0x26, 0x70, 0xef, 0xd6, 0x13, 0xb7, 0x74, 0x28, 0xf7, 0xca, 0x50, 0xd1, 0x2d, - 0x83, 0x21, 0x64, 0xe4, 0xdd, 0x3f, 0x38, 0xb8, 0xd6, 0xd2, 0x41, 0xb3, 0x1c, 0x9a, 0xea, 0x0d, 0xf5, 0xda, 0xdf, - 0xcd, 0x17, 0x9f, 0x9a, 0x1e, 0x15, 0xaf, 0x48, 0x1c, 0xbd, 0x9b, 0x63, 0x5b, 0xad, 0xed, 0xd4, 0xa1, 0xae, 0xa9, - 0x59, 0x09, 0x02, 0x40, 0x4e, 0x08, 0xce, 0xa8, 0x8f, 0xc0, 0xba, 0xf3, 0x83, 0x02, 0xc8, 0x33, 0x62, 0x14, 0x77, - 0xc2, 0x7f, 0x93, 0x02, 0xf3, 0xdc, 0xe9, 0x1a, 0xee, 0xea, 0x8e, 0x84, 0xc4, 0x69, 0x9b, 0x9c, 0x7f, 0x69, 0x1f, - 0x4e, 0x1d, 0xa5, 0x90, 0x06, 0x44, 0x1b, 0x7d, 0xfc, 0x69, 0x40, 0x21, 0xbc, 0xf7, 0x46, 0xa4, 0xdc, 0x39, 0x7b, - 0xe8, 0x8b, 0x49, 0x10, 0x44, 0x9d, 0x67, 0x5a, 0x91, 0x86, 0x39, 0x02, 0x40, 0x41, 0x2c, 0x4e, 0xfe, 0xd9, 0x90, - 0x89, 0x00, 0x5c, 0x94, 0x0a, 0x4a, 0x7e, 0x1b, 0x1a, 0x80, 0x06, 0x01, 0x37, 0xda, 0x50, 0x61, 0x9d, 0x9c, 0xfe, - 0x25, 0x7f, 0xd8, 0xd4, 0xc4, 0x9e, 0x81, 0xf2, 0x0c, 0x1e, 0x38, 0x21, 0x1e, 0x90, 0x3f, 0xd4, 0xba, 0x6c, 0x53, - 0xcb, 0xf0, 0x77, 0x79, 0x9b, 0xf1, 0xfa, 0x3f, 0x81, 0xdc, 0xf3, 0x21, 0x02, 0x6d, 0xb7, 0x95, 0xc3, 0x2e, 0xce, - 0xd5}; -unsigned int default_private_key_len = 609; diff --git a/samples/HttpClient_Instapush/app/application.cpp b/samples/HttpClient_Instapush/app/application.cpp index f7c2d0333c..12e1f22de0 100644 --- a/samples/HttpClient_Instapush/app/application.cpp +++ b/samples/HttpClient_Instapush/app/application.cpp @@ -1,6 +1,5 @@ #include -#include -#include +#include /*** Direct PUSH notifications on your mobile phone! * @@ -14,29 +13,27 @@ * 3. Update Application ID and Application Secret below: */ -#define APP_ID "55719abba4c48a802c881205" -#define APP_SECRET "5300adbe3f906938950fc0cdbc301986" - // If you want, you can define WiFi settings globally in Eclipse Environment Variables #ifndef WIFI_SSID #define WIFI_SSID "PleaseEnterSSID" // Put your SSID and password here #define WIFI_PWD "PleaseEnterPass" #endif -class InstapushTrackers : public HashMap +namespace { -}; +DEFINE_FSTR(APP_ID, "55719abba4c48a802c881205") +DEFINE_FSTR(APP_SECRET, "5300adbe3f906938950fc0cdbc301986") + +using InstapushTrackers = HashMap; class InstapushApplication : protected HttpClient { public: - InstapushApplication(String appId, String appSecret) + InstapushApplication(const String& appId, const String& appSecret) : app(appId), secret(appSecret) { - app = appId; - secret = appSecret; } - void notify(String event, InstapushTrackers& trackersInfo) + void notify(const String& event, InstapushTrackers& trackersInfo) { debugf("preparing request"); @@ -47,16 +44,15 @@ class InstapushApplication : protected HttpClient requestHeaders[F("x-instapush-appid")] = app; requestHeaders[F("x-instapush-appsecret")] = secret; - DynamicJsonDocument root(1024); + auto stream = new JsonObjectStream(1024); + auto root = stream->getRoot(); root["event"] = event; JsonObject trackers = root.createNestedObject("trackers"); - for(unsigned i = 0; i < trackersInfo.count(); i++) { - debugf("%s: %s", trackersInfo.keyAt(i).c_str(), trackersInfo.valueAt(i).c_str()); - trackers[trackersInfo.keyAt(i)] = trackersInfo[trackersInfo.keyAt(i)]; + for(auto info : trackersInfo) { + debugf("%s: %s", info.key().c_str(), info.value().c_str()); + trackers[info.key()] = info.value(); } - auto stream = new MemoryDataStream; - Json::serialize(root, stream); request->setBody(stream); request->onRequestComplete(RequestCompletedDelegate(&InstapushApplication::processed, this)); @@ -73,10 +69,10 @@ class InstapushApplication : protected HttpClient private: String app; String secret; - const char* url = "http://api.instapush.im/v1/post"; + DEFINE_FSTR_LOCAL(url, "http://api.instapush.im/v1/post"); }; -Timer procTimer; +SimpleTimer procTimer; InstapushApplication pusher(APP_ID, APP_SECRET); // Publish our message @@ -98,6 +94,8 @@ void gotIP(IpAddress ip, IpAddress netmask, IpAddress gateway) procTimer.initializeMs<10 * 1000>(publishMessage).start(); } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); // 115200 by default diff --git a/samples/HttpClient_ThingSpeak/app/application.cpp b/samples/HttpClient_ThingSpeak/app/application.cpp index ee6424f537..e11ca1f162 100644 --- a/samples/HttpClient_ThingSpeak/app/application.cpp +++ b/samples/HttpClient_ThingSpeak/app/application.cpp @@ -6,8 +6,10 @@ #define WIFI_PWD "PleaseEnterPass" #endif -Timer procTimer; -int sensorValue = 0; +namespace +{ +SimpleTimer procTimer; +int sensorValue; HttpClient thingSpeak; int onDataSent(HttpConnection& client, bool successful) @@ -40,8 +42,8 @@ void sendData() */ Url url; url.Scheme = URI_SCHEME_HTTP; - url.Host = "api.thingspeak.com"; - url.Path = "/update"; + url.Host = F("api.thingspeak.com"); + url.Path = F("/update"); url.Query["key"] = F("7XXUJWCWYTMXKN3L"); url.Query["field1"] = String(sensorValue); thingSpeak.downloadString(url, onDataSent); @@ -62,9 +64,11 @@ void connectFail(const String& ssid, MacAddress bssid, WifiDisconnectReason reas void gotIP(IpAddress ip, IpAddress netmask, IpAddress gateway) { // Start send data loop - procTimer.initializeMs(25 * 1000, sendData).start(); // every 25 seconds + procTimer.initializeMs<25 * 1000>(sendData).start(); // every 25 seconds } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); // 115200 by default diff --git a/samples/HttpServer_AJAX/README.rst b/samples/HttpServer_AJAX/README.rst index 6dba8d0155..532fc311d6 100644 --- a/samples/HttpServer_AJAX/README.rst +++ b/samples/HttpServer_AJAX/README.rst @@ -3,5 +3,5 @@ AJAX Http Server Demonstration of a simple web server with page updates using `AJAX `__. -.. :image:: esp8266-ajax-server.png - :height:192px +.. image:: esp8266-ajax-server.png + :height: 192px diff --git a/samples/HttpServer_AJAX/app/application.cpp b/samples/HttpServer_AJAX/app/application.cpp index fda5a63e4c..205c72e578 100644 --- a/samples/HttpServer_AJAX/app/application.cpp +++ b/samples/HttpServer_AJAX/app/application.cpp @@ -7,18 +7,26 @@ #define WIFI_PWD "PleaseEnterPass" #endif +namespace +{ HttpServer server; FtpServer ftp; -int inputs[] = {0, 2}; // Set input GPIO pins here -Vector namesInput; -const int countInputs = sizeof(inputs) / sizeof(inputs[0]); +// Set input GPIO pins here +const uint8_t inputs[] = {5, 2}; void onIndex(HttpRequest& request, HttpResponse& response) { TemplateFileStream* tmpl = new TemplateFileStream("index.html"); auto& vars = tmpl->variables(); - //vars["counter"] = String(counter); + String gpioList; + for(unsigned i = 0; i < ARRAY_SIZE(inputs); ++i) { + String s = F("GPIO{gpio} "); + s.replace("{id}", String(i)); + s.replace("{gpio}", String(inputs[i])); + gpioList += s; + } + vars["gpio_list"] = gpioList; response.sendNamedStream(tmpl); // this template object will be deleted automatically } @@ -40,8 +48,8 @@ void onAjaxInput(HttpRequest& request, HttpResponse& response) JsonObject json = stream->getRoot(); json["status"] = (bool)true; - String stringKey = "StringKey"; - String stringValue = "StringValue"; + String stringKey = F("StringKey"); + String stringValue = F("StringValue"); json[stringKey] = stringValue; @@ -51,8 +59,9 @@ void onAjaxInput(HttpRequest& request, HttpResponse& response) } JsonObject gpio = json.createNestedObject("gpio"); - for(int i = 0; i < countInputs; i++) - gpio[namesInput[i].c_str()] = digitalRead(inputs[i]); + for(unsigned i = 0; i < ARRAY_SIZE(inputs); ++i) { + gpio[String(i)] = digitalRead(inputs[i]); + } response.sendDataStream(stream, MIME_JSON); } @@ -64,7 +73,7 @@ void onAjaxFrequency(HttpRequest& request, HttpResponse& response) JsonObjectStream* stream = new JsonObjectStream(); JsonObject json = stream->getRoot(); - json["status"] = (bool)true; + json["status"] = true; json["value"] = (int)System.getCpuFrequency(); response.sendDataStream(stream, MIME_JSON); @@ -78,10 +87,11 @@ void startWebServer() server.paths.set("/ajax/frequency", onAjaxFrequency); server.paths.setDefault(onFile); - Serial.println(_F("\r\n" - "=== WEB SERVER STARTED ===")); - Serial.println(WifiStation.getIP()); - Serial.println(_F("==========================\r\n")); + Serial << endl + << _F("=== WEB SERVER STARTED ===") << endl + << WifiStation.getIP() << endl + << _F("==========================") << endl + << endl; } void startFTP() @@ -101,6 +111,8 @@ void gotIP(IpAddress ip, IpAddress netmask, IpAddress gateway) startWebServer(); } +} // namespace + void init() { spiffs_mount(); // Mount file system, in order to work with files @@ -112,9 +124,8 @@ void init() WifiStation.config(WIFI_SSID, WIFI_PWD); WifiAccessPoint.enable(false); - for(int i = 0; i < countInputs; i++) { - namesInput.add(String(inputs[i])); - pinMode(inputs[i], INPUT); + for(auto pin : inputs) { + pinMode(pin, INPUT); } // Run our method when station was connected to AP diff --git a/samples/HttpServer_AJAX/web/build/index.html b/samples/HttpServer_AJAX/web/build/index.html index 1fab1be6ed..cb23240030 100644 --- a/samples/HttpServer_AJAX/web/build/index.html +++ b/samples/HttpServer_AJAX/web/build/index.html @@ -71,8 +71,7 @@

Sming AJAX Example

Reading Input value

-

GPIO0 -

GPIO2 + {gpio_list}

diff --git a/samples/HttpServer_AJAX/web/dev/index.html b/samples/HttpServer_AJAX/web/dev/index.html index 1fab1be6ed..cb23240030 100644 --- a/samples/HttpServer_AJAX/web/dev/index.html +++ b/samples/HttpServer_AJAX/web/dev/index.html @@ -71,8 +71,7 @@

Sming AJAX Example

Reading Input value

-

GPIO0 -

GPIO2 + {gpio_list}

diff --git a/samples/HttpServer_Bootstrap/app/application.cpp b/samples/HttpServer_Bootstrap/app/application.cpp index bf75ae9fba..cdc1fdbb99 100644 --- a/samples/HttpServer_Bootstrap/app/application.cpp +++ b/samples/HttpServer_Bootstrap/app/application.cpp @@ -8,8 +8,11 @@ #define LED_PIN 0 // GPIO number +namespace +{ HttpServer server; int counter = 0; +HttpClient downloadClient; void onIndex(HttpRequest& request, HttpResponse& response) { @@ -56,26 +59,24 @@ void startWebServer() server.paths.set("/hello", onHello); server.paths.setDefault(onFile); - Serial.println(_F("\r\n" - "=== WEB SERVER STARTED ===")); - Serial.println(WifiStation.getIP()); - Serial.println(_F("==========================\r\n")); + Serial << endl + << _F("=== WEB SERVER STARTED ===") << endl + << WifiStation.getIP() << endl + << _F("==========================") << endl + << endl; } -Timer downloadTimer; -HttpClient downloadClient; -int dowfid = 0; void downloadContentFiles() { downloadClient.downloadFile(F("http://simple.anakod.ru/templates/index.html")); downloadClient.downloadFile(F("http://simple.anakod.ru/templates/bootstrap.css.gz")); downloadClient.downloadFile(F("http://simple.anakod.ru/templates/jquery.js.gz"), - (RequestCompletedDelegate)([](HttpConnection& connection, bool success) -> int { + [](HttpConnection& connection, bool success) -> int { if(success) { startWebServer(); } return 0; - })); + }); } void gotIP(IpAddress ip, IpAddress netmask, IpAddress gateway) @@ -88,15 +89,17 @@ void gotIP(IpAddress ip, IpAddress netmask, IpAddress gateway) } } +} // namespace + void init() { + Serial.begin(SERIAL_BAUD_RATE); // 115200 by default + Serial.systemDebugOutput(true); // Enable debug output to serial + spiffs_mount(); // Mount file system, in order to work with files pinMode(LED_PIN, OUTPUT); - Serial.begin(SERIAL_BAUD_RATE); // 115200 by default - Serial.systemDebugOutput(true); // Enable debug output to serial - WifiStation.enable(true); WifiStation.config(WIFI_SSID, WIFI_PWD); WifiAccessPoint.enable(false); diff --git a/samples/HttpServer_ConfigNetwork/app/application.cpp b/samples/HttpServer_ConfigNetwork/app/application.cpp index b9bf939fce..2c1e3d882a 100644 --- a/samples/HttpServer_ConfigNetwork/app/application.cpp +++ b/samples/HttpServer_ConfigNetwork/app/application.cpp @@ -5,23 +5,32 @@ namespace { +ApplicationSettingsStorage AppSettings; + HttpServer server; FtpServer ftp; HashMap networks; -String network, password; -Timer connectionTimer; +String network; +String password; +SimpleTimer connectionTimer; String lastModified; SimpleTimer scanTimer; +DEFINE_FSTR(DEFAULT_IP, "192.168.1.77") +DEFINE_FSTR(DEFAULT_NETMASK, "255.255.255.0") +DEFINE_FSTR(DEFAULT_GATEWAY, "192.168.1.1") + // Instead of using a SPIFFS file, here we demonstrate usage of imported Flash Strings IMPORT_FSTR_LOCAL(flashSettings, PROJECT_DIR "/web/build/settings.html") +#ifdef ENABLE_SSL IMPORT_FSTR_LOCAL(serverKey, PROJECT_DIR "/cert/key_1024"); IMPORT_FSTR_LOCAL(serverCert, PROJECT_DIR "/cert/x509_1024.cer"); +#endif void onIndex(HttpRequest& request, HttpResponse& response) { @@ -31,7 +40,7 @@ void onIndex(HttpRequest& request, HttpResponse& response) int onIpConfig(HttpServerConnection& connection, HttpRequest& request, HttpResponse& response) { if(request.method == HTTP_POST) { - debugf("Request coming from IP: %s", connection.getRemoteIp().toString().c_str()); + Serial << _F("Request coming from IP: ") << connection.getRemoteIp() << endl; // If desired you can also limit the access based on remote IP. Example below: // if(IpAddress("192.168.4.23") != connection.getRemoteIp()) { // return 1; // error @@ -41,7 +50,7 @@ int onIpConfig(HttpServerConnection& connection, HttpRequest& request, HttpRespo AppSettings.ip = request.getPostParameter("ip"); AppSettings.netmask = request.getPostParameter("netmask"); AppSettings.gateway = request.getPostParameter("gateway"); - debugf("Updating IP settings: %d", AppSettings.ip.isNull()); + Serial << _F("Updating IP settings: ") << AppSettings.ip.isNull() << endl; AppSettings.save(); } @@ -54,18 +63,13 @@ int onIpConfig(HttpServerConnection& connection, HttpRequest& request, HttpRespo auto& vars = tmpl->variables(); bool dhcp = WifiStation.isEnabledDHCP(); - vars["dhcpon"] = dhcp ? "checked='checked'" : ""; - vars["dhcpoff"] = !dhcp ? "checked='checked'" : ""; + vars["dhcpon"] = dhcp ? _F("checked='checked'") : ""; + vars["dhcpoff"] = !dhcp ? _F("checked='checked'") : ""; - if(!WifiStation.getIP().isNull()) { - vars["ip"] = WifiStation.getIP().toString(); - vars["netmask"] = WifiStation.getNetworkMask().toString(); - vars["gateway"] = WifiStation.getNetworkGateway().toString(); - } else { - vars["ip"] = "192.168.1.77"; - vars["netmask"] = "255.255.255.0"; - vars["gateway"] = "192.168.1.1"; - } + auto set = !WifiStation.getIP().isNull(); + vars["ip"] = set ? WifiStation.getIP().toString() : DEFAULT_IP; + vars["netmask"] = set ? WifiStation.getNetworkMask().toString() : DEFAULT_NETMASK; + vars["gateway"] = set ? WifiStation.getNetworkGateway().toString() : DEFAULT_GATEWAY; response.sendNamedStream(tmpl); // will be automatically deleted @@ -160,7 +164,7 @@ void onAjaxConnect(HttpRequest& request, HttpResponse& response) password = curPass; debugf("CONNECT TO: %s %s", network.c_str(), password.c_str()); json["connected"] = false; - connectionTimer.initializeMs(1200, makeConnection).startOnce(); + connectionTimer.initializeMs<1200>(makeConnection).startOnce(); } else { json["connected"] = WifiStation.isConnected(); debugf("Network already selected. Current status: %s", WifiStation.getConnectionStatusName().c_str()); @@ -186,9 +190,9 @@ void startWebServer() server.listen(80); #endif server.paths.set("/", onIndex); - server.paths.set("/ipconfig", onIpConfig); - server.paths.set("/ajax/get-networks", onAjaxNetworkList); - server.paths.set("/ajax/connect", onAjaxConnect); + server.paths.set(F("/ipconfig"), onIpConfig); + server.paths.set(F("/ajax/get-networks"), onAjaxNetworkList); + server.paths.set(F("/ajax/connect"), onAjaxConnect); server.paths.setDefault(onFile); } @@ -196,7 +200,7 @@ void startFTP() { if(!fileExist("index.html")) fileSetContent("index.html", - "

Please connect to FTP and upload files from folder 'web/build' (details in code)

"); + F("

Please connect to FTP and upload files from folder 'web/build' (details in code)

")); // Start FTP server ftp.listen(21); diff --git a/samples/HttpServer_ConfigNetwork/include/AppSettings.h b/samples/HttpServer_ConfigNetwork/include/AppSettings.h index 66a32fcb89..0c97b586ef 100644 --- a/samples/HttpServer_ConfigNetwork/include/AppSettings.h +++ b/samples/HttpServer_ConfigNetwork/include/AppSettings.h @@ -5,11 +5,10 @@ * Author: Anakod */ -#include -#include +#pragma once -#ifndef INCLUDE_APPSETTINGS_H_ -#define INCLUDE_APPSETTINGS_H_ +#include +#include #define APP_SETTINGS_FILE ".settings.conf" // leading point for security reasons :) @@ -61,7 +60,3 @@ struct ApplicationSettingsStorage { return fileExist(APP_SETTINGS_FILE); } }; - -static ApplicationSettingsStorage AppSettings; - -#endif /* INCLUDE_APPSETTINGS_H_ */ diff --git a/samples/HttpServer_ConfigNetwork/include/ssl/cert.h b/samples/HttpServer_ConfigNetwork/include/ssl/cert.h deleted file mode 100644 index 8515409e43..0000000000 --- a/samples/HttpServer_ConfigNetwork/include/ssl/cert.h +++ /dev/null @@ -1,27 +0,0 @@ -unsigned char x509_1024_cer[] = { - 0x30, 0x82, 0x01, 0xd7, 0x30, 0x82, 0x01, 0x40, 0x02, 0x09, 0x00, 0xaa, 0x8d, 0xd9, 0xdc, 0x30, 0x3f, 0xda, 0x4d, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x34, 0x31, 0x32, - 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x29, 0x53, 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x20, 0x44, 0x6f, 0x64, 0x67, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x39, 0x31, - 0x32, 0x32, 0x38, 0x32, 0x33, 0x31, 0x36, 0x31, 0x35, 0x5a, 0x17, 0x0d, 0x33, 0x33, 0x30, 0x39, 0x30, 0x35, 0x32, - 0x33, 0x31, 0x36, 0x31, 0x35, 0x5a, 0x30, 0x2c, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, - 0x53, 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x13, 0x09, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x30, 0x81, 0x9f, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, - 0x89, 0x02, 0x81, 0x81, 0x00, 0xcf, 0xe2, 0x20, 0xf1, 0xd8, 0x18, 0x5f, 0x22, 0x09, 0xa8, 0x34, 0x00, 0xca, 0x15, - 0x39, 0xfc, 0x7b, 0xf3, 0x68, 0xd5, 0xb7, 0xd3, 0xbc, 0xb6, 0xa7, 0xb6, 0xbe, 0x0c, 0x4f, 0xfa, 0x98, 0x77, 0xe9, - 0x3f, 0x2c, 0x33, 0x0b, 0x5f, 0xb4, 0x3b, 0xc3, 0xc1, 0x7f, 0x91, 0x45, 0x46, 0xd7, 0x22, 0x9e, 0x81, 0x45, 0x80, - 0xb5, 0x71, 0x0c, 0xb0, 0xd7, 0x47, 0x48, 0xad, 0xe2, 0x9f, 0x6c, 0x55, 0x3c, 0x1c, 0xe9, 0x4a, 0x39, 0x78, 0xc6, - 0xa2, 0x0a, 0x46, 0xa2, 0xb8, 0x51, 0xaa, 0xa5, 0x88, 0xac, 0x8e, 0x1e, 0x90, 0x16, 0x4c, 0xac, 0x23, 0x2c, 0xfa, - 0x25, 0x62, 0x88, 0xb0, 0xa7, 0x6b, 0x83, 0x6a, 0x68, 0xed, 0x9c, 0xc5, 0xf6, 0xd0, 0x69, 0x1d, 0x49, 0x04, 0xe1, - 0x0e, 0xf8, 0x25, 0xfe, 0xa6, 0x53, 0x5b, 0x00, 0x09, 0x59, 0xaa, 0x2d, 0x71, 0x28, 0x68, 0x1a, 0x63, 0x0a, 0x93, - 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, - 0x00, 0x03, 0x81, 0x81, 0x00, 0x57, 0x3a, 0xc7, 0xc5, 0x7a, 0x3d, 0x9b, 0x45, 0x6c, 0xcc, 0x18, 0x29, 0xa7, 0x54, - 0x10, 0x51, 0xd4, 0x1e, 0xe0, 0xf6, 0x18, 0xee, 0x93, 0xa5, 0xfc, 0x12, 0xf7, 0x5e, 0x93, 0x16, 0xed, 0x7d, 0xc3, - 0x2a, 0x2d, 0x0e, 0xc6, 0x3a, 0x03, 0x05, 0x85, 0x13, 0xc8, 0xfb, 0x50, 0xf4, 0x91, 0x23, 0xb2, 0x93, 0x6a, 0x45, - 0x9d, 0x15, 0x72, 0x8a, 0x09, 0x15, 0xae, 0x39, 0x71, 0xa6, 0xe7, 0x4c, 0xe7, 0xf5, 0x3a, 0x8a, 0xdc, 0xb7, 0xfd, - 0x20, 0x86, 0x94, 0x9e, 0x52, 0x3a, 0x44, 0x03, 0xd4, 0xdc, 0x9c, 0xbd, 0xbc, 0xcc, 0x3b, 0x03, 0x55, 0xed, 0x96, - 0x68, 0x35, 0x93, 0x3e, 0xbf, 0x74, 0x38, 0x87, 0x9b, 0x61, 0xb7, 0xf5, 0x0e, 0x16, 0x98, 0xbe, 0x14, 0x49, 0x73, - 0x15, 0xf2, 0x70, 0xf5, 0x48, 0xb6, 0x05, 0x8b, 0xbf, 0x89, 0x69, 0x73, 0x18, 0x8f, 0x85, 0xee, 0xca, 0x80, 0x4d}; -unsigned int x509_1024_cer_len = 475; diff --git a/samples/HttpServer_ConfigNetwork/include/ssl/private_key.h b/samples/HttpServer_ConfigNetwork/include/ssl/private_key.h deleted file mode 100644 index da28f9a732..0000000000 --- a/samples/HttpServer_ConfigNetwork/include/ssl/private_key.h +++ /dev/null @@ -1,35 +0,0 @@ -unsigned char key_1024[] = { - 0x30, 0x82, 0x02, 0x5d, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xcf, 0xe2, 0x20, 0xf1, 0xd8, 0x18, 0x5f, 0x22, - 0x09, 0xa8, 0x34, 0x00, 0xca, 0x15, 0x39, 0xfc, 0x7b, 0xf3, 0x68, 0xd5, 0xb7, 0xd3, 0xbc, 0xb6, 0xa7, 0xb6, 0xbe, - 0x0c, 0x4f, 0xfa, 0x98, 0x77, 0xe9, 0x3f, 0x2c, 0x33, 0x0b, 0x5f, 0xb4, 0x3b, 0xc3, 0xc1, 0x7f, 0x91, 0x45, 0x46, - 0xd7, 0x22, 0x9e, 0x81, 0x45, 0x80, 0xb5, 0x71, 0x0c, 0xb0, 0xd7, 0x47, 0x48, 0xad, 0xe2, 0x9f, 0x6c, 0x55, 0x3c, - 0x1c, 0xe9, 0x4a, 0x39, 0x78, 0xc6, 0xa2, 0x0a, 0x46, 0xa2, 0xb8, 0x51, 0xaa, 0xa5, 0x88, 0xac, 0x8e, 0x1e, 0x90, - 0x16, 0x4c, 0xac, 0x23, 0x2c, 0xfa, 0x25, 0x62, 0x88, 0xb0, 0xa7, 0x6b, 0x83, 0x6a, 0x68, 0xed, 0x9c, 0xc5, 0xf6, - 0xd0, 0x69, 0x1d, 0x49, 0x04, 0xe1, 0x0e, 0xf8, 0x25, 0xfe, 0xa6, 0x53, 0x5b, 0x00, 0x09, 0x59, 0xaa, 0x2d, 0x71, - 0x28, 0x68, 0x1a, 0x63, 0x0a, 0x93, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x81, 0x80, 0x4c, 0x56, 0x5b, 0x86, 0xb3, - 0xb5, 0xef, 0x69, 0x4e, 0x66, 0x88, 0x02, 0x2a, 0x33, 0x35, 0x41, 0xf4, 0x3a, 0x64, 0x2a, 0xe7, 0x00, 0x47, 0xf2, - 0x43, 0x10, 0x26, 0x25, 0xdb, 0x50, 0xc8, 0xa0, 0x6f, 0xf4, 0x94, 0xc4, 0x81, 0xce, 0xb9, 0x1e, 0xa1, 0x39, 0xf3, - 0x20, 0x63, 0x72, 0x2a, 0x1a, 0x3a, 0x5e, 0x7a, 0x29, 0x53, 0x77, 0x9a, 0x13, 0x6e, 0x5a, 0x6c, 0xe3, 0xfd, 0xae, - 0x51, 0x57, 0x29, 0xb3, 0xb0, 0x01, 0x69, 0x58, 0xd7, 0x34, 0x36, 0xb2, 0xea, 0xc9, 0xb4, 0x03, 0x0f, 0xf2, 0x17, - 0xaf, 0xc1, 0x8c, 0xe1, 0x7e, 0x29, 0xb5, 0x97, 0x80, 0x61, 0xf7, 0x59, 0xe6, 0x53, 0xb0, 0xa2, 0x77, 0x38, 0x57, - 0xd2, 0x5e, 0x82, 0x8a, 0x3b, 0x3f, 0xef, 0x54, 0x60, 0x9f, 0x2e, 0xb5, 0xbe, 0x8e, 0x64, 0xb1, 0x18, 0xdf, 0x1e, - 0x15, 0x35, 0x3f, 0x9a, 0xe9, 0x65, 0xcc, 0xc0, 0x31, 0x02, 0x41, 0x00, 0xf4, 0x0e, 0x50, 0x85, 0x10, 0x96, 0x6b, - 0xa0, 0xd6, 0xeb, 0xcb, 0x72, 0xe9, 0xcf, 0x59, 0x01, 0x8c, 0x85, 0x87, 0xb9, 0xa0, 0x19, 0x1d, 0x55, 0x05, 0xd7, - 0x37, 0x19, 0xb5, 0x99, 0xdc, 0x3a, 0x92, 0x22, 0x8d, 0x1b, 0xe0, 0xb8, 0x88, 0xe5, 0xe5, 0x4a, 0x74, 0x63, 0x28, - 0x22, 0xeb, 0xe2, 0x1f, 0x01, 0x50, 0x57, 0x17, 0xa8, 0x04, 0x68, 0xf4, 0x6a, 0x7d, 0xb6, 0x4a, 0x8c, 0xc2, 0x25, - 0x02, 0x41, 0x00, 0xda, 0x0e, 0x9f, 0x03, 0x65, 0x3c, 0xfa, 0xfa, 0xec, 0xf1, 0xc5, 0x1d, 0xf9, 0x94, 0xc0, 0x86, - 0xf5, 0x76, 0xd7, 0xee, 0x93, 0x87, 0x3d, 0x7e, 0xd9, 0x45, 0x56, 0x7d, 0xcc, 0xe1, 0x55, 0x9d, 0xc2, 0xf7, 0x89, - 0x9f, 0x9f, 0xf1, 0xe3, 0xdb, 0x17, 0xc9, 0xc8, 0x5a, 0x53, 0x15, 0x8a, 0x7a, 0x94, 0x39, 0x4e, 0x29, 0xd2, 0xf9, - 0xb6, 0xe7, 0x1c, 0x15, 0x68, 0x95, 0x40, 0xe3, 0xd0, 0x57, 0x02, 0x41, 0x00, 0xb1, 0x2a, 0x9f, 0x0b, 0x29, 0xb2, - 0x78, 0x69, 0x26, 0xfb, 0xbf, 0x12, 0x29, 0x67, 0x0b, 0x0e, 0xd3, 0xca, 0xaf, 0x6f, 0x72, 0x28, 0x29, 0x21, 0xea, - 0x7e, 0x84, 0x12, 0x56, 0xc1, 0x5d, 0x9c, 0xeb, 0x2e, 0xc7, 0xce, 0xe0, 0x00, 0x35, 0xe8, 0xe5, 0xdd, 0x79, 0xc5, - 0xed, 0x82, 0x04, 0x48, 0x7f, 0x07, 0x7e, 0x21, 0xeb, 0x1b, 0x5e, 0x30, 0x2e, 0x96, 0x0b, 0xb2, 0x44, 0x46, 0x10, - 0x3d, 0x02, 0x40, 0x7d, 0x18, 0x18, 0x37, 0x1d, 0x74, 0x0f, 0x53, 0xb6, 0x6c, 0xb8, 0xb5, 0x8a, 0x81, 0xc0, 0xb5, - 0x6b, 0xca, 0x42, 0xf4, 0x36, 0x24, 0x46, 0xae, 0x27, 0xbc, 0xf4, 0x72, 0x74, 0xff, 0xec, 0x5a, 0xf6, 0x07, 0x86, - 0x27, 0x51, 0xdd, 0xb5, 0xe6, 0xf1, 0xcd, 0xab, 0xa7, 0xcd, 0xb4, 0x34, 0xde, 0x3f, 0x7c, 0x64, 0x8f, 0xef, 0xdd, - 0x9c, 0x05, 0x17, 0x82, 0x5c, 0x9e, 0x0b, 0x3c, 0xe6, 0x3f, 0x02, 0x41, 0x00, 0xcf, 0xb5, 0x87, 0xfa, 0xc3, 0x82, - 0x7b, 0x18, 0x01, 0x8f, 0x88, 0xa4, 0xd4, 0xd9, 0xaa, 0x45, 0x74, 0x83, 0x80, 0x2b, 0xa7, 0x36, 0x2d, 0x91, 0x11, - 0x81, 0x67, 0x44, 0xeb, 0x49, 0xc5, 0x18, 0xbe, 0xff, 0x9a, 0x5b, 0x33, 0x19, 0xf4, 0x40, 0x6e, 0x4d, 0xb9, 0x1b, - 0xc2, 0xda, 0xf8, 0xd3, 0x92, 0x4c, 0x22, 0x6f, 0x25, 0xc6, 0x68, 0x7a, 0x7e, 0x18, 0x99, 0x05, 0x04, 0x91, 0x26, - 0xbf}; -unsigned int key_1024_len = 609; diff --git a/samples/HttpServer_FirmwareUpload/app/application.cpp b/samples/HttpServer_FirmwareUpload/app/application.cpp index 2dbfe83325..586f3251e8 100644 --- a/samples/HttpServer_FirmwareUpload/app/application.cpp +++ b/samples/HttpServer_FirmwareUpload/app/application.cpp @@ -2,8 +2,15 @@ #include #include #include -#include +// If you want, you can define WiFi settings globally in Eclipse Environment Variables +#ifndef WIFI_SSID +#define WIFI_SSID "PleaseEnterSSID" // Put your SSID and password here +#define WIFI_PWD "PleaseEnterPass" +#endif + +namespace +{ HttpServer server; void onFile(HttpRequest& request, HttpResponse& response) @@ -83,6 +90,8 @@ void startWebServer() server.paths.setDefault(onFile); } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); // 115200 by default @@ -91,8 +100,8 @@ void init() spiffs_mount(); // Mount file system, in order to work with files WifiStation.enable(true); - //WifiStation.config(WIFI_SSID, WIFI_PWD); - //WifiStation.enableDHCP(true); + WifiStation.config(WIFI_SSID, WIFI_PWD); + // WifiStation.enableDHCP(true); // Run WEB server on system ready System.onReady(startWebServer); diff --git a/samples/HttpServer_Plugins/app/application.cpp b/samples/HttpServer_Plugins/app/application.cpp index 04af70bb83..cc1689288d 100644 --- a/samples/HttpServer_Plugins/app/application.cpp +++ b/samples/HttpServer_Plugins/app/application.cpp @@ -55,8 +55,8 @@ void startWebServer() * * make sure to replace the IP address with the IP address of your HttpServer */ - server->paths.set("/ip-n-auth", echoContentBody, - new ResourceIpAuth(IpAddress("192.168.13.0"), IpAddress("255.255.255.0")), pluginBasicAuth); + server->paths.set("/ip-n-auth", echoContentBody, new ResourceIpAuth(F("192.168.13.0"), F("255.255.255.0")), + pluginBasicAuth); /* * This content coming to this resource is modified on the fly @@ -70,16 +70,18 @@ void startWebServer() */ server->paths.set("/test", echoContentBody, new ContentDecoder()); - Serial.println(F("\r\n=== WEB SERVER STARTED ===")); - Serial.println(WifiStation.getIP()); - Serial.println(F("==============================\r\n")); + Serial << endl + << _F("=== WEB SERVER STARTED ===") << endl + << WifiStation.getIP() << endl + << _F("==============================") << endl + << endl; } // Will be called when WiFi station becomes fully operational void gotIP(IpAddress ip, IpAddress netmask, IpAddress gateway) { startWebServer(); - debug_i("free heap = %u", system_get_free_heap_size()); + Serial << _F("Free heap = ") << system_get_free_heap_size() << endl; } } // namespace diff --git a/samples/HttpServer_WebSockets/Kconfig b/samples/HttpServer_WebSockets/Kconfig index 8744832f6b..ef96b02ac4 100644 --- a/samples/HttpServer_WebSockets/Kconfig +++ b/samples/HttpServer_WebSockets/Kconfig @@ -4,8 +4,8 @@ # mainmenu "Sample Configuration" - menu "Command Hanler" + menu "Command Handler" config ENABLE_CMD_HANDLER bool "Enable command handler functionality" default y - endmenu \ No newline at end of file + endmenu diff --git a/samples/HttpServer_WebSockets/app/CUserData.cpp b/samples/HttpServer_WebSockets/app/CUserData.cpp index 801ea01470..ea949da3be 100644 --- a/samples/HttpServer_WebSockets/app/CUserData.cpp +++ b/samples/HttpServer_WebSockets/app/CUserData.cpp @@ -1,7 +1,5 @@ #include "CUserData.h" -//Simplified container modelling a user session - void CUserData::addSession(WebsocketConnection& connection) { activeWebSockets.addElement(&connection); @@ -10,34 +8,24 @@ void CUserData::addSession(WebsocketConnection& connection) void CUserData::removeSession(WebsocketConnection& connection) { - for(unsigned i = 0; i < activeWebSockets.count(); i++) { - if(connection == *(activeWebSockets[i])) { - activeWebSockets[i]->setUserData(nullptr); - activeWebSockets.remove(i); - Serial.println(F("Removed user session")); - return; - } + if(activeWebSockets.removeElement(&connection)) { + connection.setUserData(nullptr); + Serial.println(F("Removed user session")); } } void CUserData::printMessage(WebsocketConnection& connection, const String& msg) { - unsigned i = 0; - for(; i < activeWebSockets.count(); i++) { - if(connection == *(activeWebSockets[i])) { - break; - } - } - - if(i < activeWebSockets.count()) { - Serial << _F("Received msg on connection ") << i << ": " << msg; + int i = activeWebSockets.indexOf(&connection); + if(i >= 0) { + Serial << _F("Received msg on connection ") << i << ": " << msg << endl; } } void CUserData::logOut() { - for(unsigned i = 0; i < activeWebSockets.count(); i++) { - activeWebSockets[i]->setUserData(nullptr); + for(auto skt : activeWebSockets) { + skt->setUserData(nullptr); } activeWebSockets.removeAllElements(); diff --git a/samples/HttpServer_WebSockets/app/application.cpp b/samples/HttpServer_WebSockets/app/application.cpp index 193966e636..2d0a059c4c 100644 --- a/samples/HttpServer_WebSockets/app/application.cpp +++ b/samples/HttpServer_WebSockets/app/application.cpp @@ -2,7 +2,7 @@ #include #include "CUserData.h" -#if ENABLE_CMD_HANDLER +#ifdef ENABLE_CMD_HANDLER #include CommandProcessing::Handler commandHandler; #endif @@ -13,15 +13,17 @@ CommandProcessing::Handler commandHandler; #define WIFI_PWD "PleaseEnterPass" #endif +namespace +{ HttpServer server; -unsigned totalActiveSockets = 0; +unsigned totalActiveSockets; -CUserData userGeorge("George", "I like SMING"); +CUserData userGeorge; void onIndex(HttpRequest& request, HttpResponse& response) { auto tmpl = new TemplateFileStream(F("index.html")); - auto& vars = tmpl->variables(); + //auto& vars = tmpl->variables(); //vars["counter"] = String(counter); response.sendNamedStream(tmpl); // this template object will be deleted automatically } @@ -38,6 +40,14 @@ void onFile(HttpRequest& request, HttpResponse& response) } } +void shutdownServer() +{ + // Don't shutdown immediately, wait a bit to allow messages to propagate + auto timer = new AutoDeleteTimer; + timer->initializeMs<1000>([&]() { server.shutdown(); }); + timer->startOnce(); +} + void wsConnected(WebsocketConnection& socket) { totalActiveSockets++; @@ -58,37 +68,29 @@ void wsMessageReceived(WebsocketConnection& socket, const String& message) if(message == _F("shutdown")) { String message(F("The server is shutting down...")); socket.broadcast(message); - - // Don't shutdown immediately, wait a bit to allow messages to propagate - auto timer = new SimpleTimer; - timer->initializeMs<1000>( - [](void* timer) { - delete static_cast(timer); - server.shutdown(); - }, - timer); - timer->startOnce(); + shutdownServer(); return; } String response = F("Echo: ") + message; socket.sendString(response); - //Normally you would use dynamic cast but just be careful not to convert to wrong object type! - auto user = reinterpret_cast(socket.getUserData()); + // Normally you would use dynamic cast but just be careful not to convert to wrong object type! + auto user = static_cast(socket.getUserData()); if(user != nullptr) { user->printMessage(socket, message); } } -#if ENABLE_CMD_HANDLER +#ifdef ENABLE_CMD_HANDLER void wsCommandReceived(WebsocketConnection& socket, const String& message) { + debug_i("%s(%s)", __FUNCTION__, message.c_str()); String response = commandHandler.processNow(message.c_str(), message.length()); socket.sendString(response); - //Normally you would use dynamic cast but just be careful not to convert to wrong object type! - auto user = reinterpret_cast(socket.getUserData()); + // Normally you would use dynamic cast but just be careful not to convert to wrong object type! + auto user = static_cast(socket.getUserData()); if(user != nullptr) { user->printMessage(socket, message); } @@ -96,15 +98,7 @@ void wsCommandReceived(WebsocketConnection& socket, const String& message) void processShutdownCommand(String commandLine, ReadWriteStream& commandOutput) { - // Don't shutdown immediately, wait a bit to allow messages to propagate - auto timer = new SimpleTimer; - timer->initializeMs<1000>( - [](void* timer) { - delete static_cast(timer); - server.shutdown(); - }, - timer); - timer->startOnce(); + shutdownServer(); } #endif @@ -117,8 +111,8 @@ void wsDisconnected(WebsocketConnection& socket) { totalActiveSockets--; - //Normally you would use dynamic cast but just be careful not to convert to wrong object type! - auto user = reinterpret_cast(socket.getUserData()); + // Normally you would use dynamic cast but just be careful not to convert to wrong object type! + auto user = static_cast(socket.getUserData()); if(user != nullptr) { user->removeSession(socket); } @@ -138,7 +132,7 @@ void startWebServer() auto wsResource = new WebsocketResource(); wsResource->setConnectionHandler(wsConnected); wsResource->setMessageHandler(wsMessageReceived); -#if ENABLE_CMD_HANDLER +#ifdef ENABLE_CMD_HANDLER wsResource->setMessageHandler(wsCommandReceived); #endif @@ -159,21 +153,25 @@ void gotIP(IpAddress ip, IpAddress netmask, IpAddress gateway) startWebServer(); } +} // namespace + void init() { spiffs_mount(); // Mount file system, in order to work with files -#if ENABLE_CMD_HANDLER +#ifdef ENABLE_CMD_HANDLER commandHandler.registerSystemCommands(); commandHandler.registerCommand( - CommandProcessing::Command("shutdown", "Shutdown Server Command", "Application", processShutdownCommand)); + {CMDP_STRINGS("shutdown", "Shutdown Server Command", "Application"), processShutdownCommand}); #endif + userGeorge = CUserData{F("George"), F("I like SMING")}; + Serial.begin(SERIAL_BAUD_RATE); // 115200 by default Serial.systemDebugOutput(true); // Enable debug output to serial WifiStation.enable(true); - WifiStation.config(WIFI_SSID, WIFI_PWD); + WifiStation.config(F(WIFI_SSID), F(WIFI_PWD)); WifiAccessPoint.enable(false); // Run our method when station was connected to AP diff --git a/samples/HttpServer_WebSockets/component.mk b/samples/HttpServer_WebSockets/component.mk index 25bbd74f26..4c7fcfebf6 100644 --- a/samples/HttpServer_WebSockets/component.mk +++ b/samples/HttpServer_WebSockets/component.mk @@ -3,8 +3,7 @@ HWCONFIG := spiffs-2m COMPONENT_VARS += ENABLE_CMD_HANDLER ENABLE_CMD_HANDLER ?= 1 -ifeq ($(ENABLE_CMD_HANDLER), 1) - COMPONENT_DEPENDS += CommandProcessing +ifeq ($(ENABLE_CMD_HANDLER),1) +COMPONENT_DEPENDS += CommandProcessing +APP_CFLAGS += -DENABLE_CMD_HANDLER=1 endif - -APP_CFLAGS += -DENABLE_CMD_HANDLER=$(ENABLE_CMD_HANDLER) \ No newline at end of file diff --git a/samples/HttpServer_WebSockets/include/CUserData.h b/samples/HttpServer_WebSockets/include/CUserData.h index 74e5d7024a..bf93d68c2e 100644 --- a/samples/HttpServer_WebSockets/include/CUserData.h +++ b/samples/HttpServer_WebSockets/include/CUserData.h @@ -1,13 +1,16 @@ -#ifndef C_USER_DATA_H_SAMPLE -#define C_USER_DATA_H_SAMPLE +#pragma once #include -//Simplified container modelling a user session +// Simplified container modelling a user session class CUserData { public: - CUserData(const char* uName, const char* uData) : userName(uName), userData(uData) + CUserData() + { + } + + CUserData(const String& uName, const String& uData) : userName(uName), userData(uData) { } @@ -26,5 +29,3 @@ class CUserData String userData; Vector activeWebSockets; }; - -#endif /*C_USER_DATA_H_SAMPLE*/ diff --git a/samples/Humidity_AM2321/app/application.cpp b/samples/Humidity_AM2321/app/application.cpp index 0890214c5e..19fb17275c 100644 --- a/samples/Humidity_AM2321/app/application.cpp +++ b/samples/Humidity_AM2321/app/application.cpp @@ -1,10 +1,11 @@ #include #include "Libraries/AM2321/AM2321.h" +namespace +{ AM2321 am2321; -Timer procTimer; -bool state = true; +SimpleTimer procTimer; // You can change I2C pins here: const int SCL = 5; @@ -15,6 +16,8 @@ void read() Serial << am2321.read() << ',' << am2321.temperature / 10.0 << ',' << am2321.humidity / 10.0 << endl; } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); // 115200 by default @@ -32,5 +35,5 @@ void init() am2321.begin(); // REQUIRED. Call it after choosing I2C pins. Serial.println(am2321.uid()); - procTimer.initializeMs(3000, read).start(); + procTimer.initializeMs<3000>(read).start(); } diff --git a/samples/Humidity_BME280/app/application.cpp b/samples/Humidity_BME280/app/application.cpp index 395d5a62a0..0f8b38eb41 100644 --- a/samples/Humidity_BME280/app/application.cpp +++ b/samples/Humidity_BME280/app/application.cpp @@ -24,8 +24,10 @@ #define SEALEVELPRESSURE_HPA (1013.25) +namespace +{ Adafruit_BME280 bme; -Timer procTimer; +SimpleTimer procTimer; // Will use default pins for selected architecture. You can override values here // #define SDA 4 @@ -40,6 +42,8 @@ void printValues() Serial.println(); } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); // 115200 by default diff --git a/samples/Humidity_DHT22/app/application.cpp b/samples/Humidity_DHT22/app/application.cpp index 4f5f8e09ba..8849ad545c 100644 --- a/samples/Humidity_DHT22/app/application.cpp +++ b/samples/Humidity_DHT22/app/application.cpp @@ -4,24 +4,10 @@ //#define WORK_PIN 14 // GPIO14 #define WORK_PIN 2 -DHTesp dht; - -Timer readTemperatureProcTimer; -void onTimer_readTemperatures(); - -void init() +namespace { - Serial.begin(SERIAL_BAUD_RATE); // 115200 by default - Serial.systemDebugOutput(true); // Allow debug output to serial - - dht.setup(WORK_PIN, DHTesp::DHT22); - readTemperatureProcTimer.initializeMs(5 * 1000, onTimer_readTemperatures).start(); // every so often. - - Serial.println(_F("\r\n" - "DHT improved lib")); - Serial << _F("TickCount=") << RTC.getRtcNanoseconds() / 1000000 - << _F("; Need to wait 1 second for the sensor to boot up") << endl; -} +DHTesp dht; +SimpleTimer readTemperatureProcTimer; void onTimer_readTemperatures() { @@ -107,10 +93,25 @@ void onTimer_readTemperatures() Serial.print(_F("Cold And Dry")); break; default: - Serial.print(_F("Unknown:")); - Serial.print(cf); + Serial << _F("Unknown:") << cf; break; } Serial.println(')'); } + +} // namespace + +void init() +{ + Serial.begin(SERIAL_BAUD_RATE); // 115200 by default + Serial.systemDebugOutput(true); // Allow debug output to serial + + dht.setup(WORK_PIN, DHTesp::DHT22); + readTemperatureProcTimer.initializeMs<5 * 1000>(onTimer_readTemperatures).start(); // every so often. + + Serial << endl + << _F("DHT improved lib") << endl + << _F("TickCount=") << RTC.getRtcNanoseconds() / 1000000 + << _F("; Need to wait 1 second for the sensor to boot up") << endl; +} diff --git a/samples/Humidity_SI7021/app/application.cpp b/samples/Humidity_SI7021/app/application.cpp index 8861e78543..fe189dfdd4 100644 --- a/samples/Humidity_SI7021/app/application.cpp +++ b/samples/Humidity_SI7021/app/application.cpp @@ -2,13 +2,15 @@ #include #include -SI7021 hydrometer; -Timer procTimer_ht; -Timer procTimer_olt; - #define I2C_SCL 5 // SCL #define I2C_SDA 4 // SCA +namespace +{ +SI7021 hydrometer; +SimpleTimer procTimer_ht; +SimpleTimer procTimer_olt; + //LN10 - 2.30258509299404568402 double getDewPoint(unsigned int humidity, int temperature) { @@ -21,7 +23,9 @@ void si_read_ht() { if(!hydrometer.begin()) { Serial.println(_F("Could not connect to SI7021.")); + return; } + Serial.println(_F("Start reading Humidity and Temperature")); si7021_env env_data = hydrometer.getHumidityAndTemperature(); @@ -39,7 +43,9 @@ void si_read_olt() { if(!hydrometer.begin()) { Serial.println(_F("Could not connect to SI7021.")); + return; } + Serial.println(_F("Start reading Temperature")); si7021_olt olt_data = hydrometer.getTemperatureOlt(); @@ -51,13 +57,17 @@ void si_read_olt() } } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); // 115200 by default Serial.systemDebugOutput(true); // Allow debug output to serial - Serial.print(_F("Start I2c")); + + Serial.println(_F("Start I2c")); Wire.pins(I2C_SDA, I2C_SCL); // SDA, SCL Wire.begin(); - procTimer_ht.initializeMs(10000, si_read_ht).start(); - procTimer_olt.initializeMs(15000, si_read_olt).start(); + + procTimer_ht.initializeMs<10000>(si_read_ht).start(); + procTimer_olt.initializeMs<15000>(si_read_olt).start(); } diff --git a/samples/IR_lib/app/application.cpp b/samples/IR_lib/app/application.cpp index fa97eb7c7d..1f8ba9c3f5 100644 --- a/samples/IR_lib/app/application.cpp +++ b/samples/IR_lib/app/application.cpp @@ -10,13 +10,14 @@ #define IR_RECV_PIN 12 // GPIO12 #define IR_SEND_PIN 5 // GPIO5 -Timer irTimer; +namespace +{ +SimpleTimer irTimer; IRrecv irrecv(IR_RECV_PIN); IRsend irsend(IR_SEND_PIN); void receiveIR() { - irTimer.stop(); decode_results dresults; dresults.decode_type = UNUSED; if(irrecv.decode(&dresults)) { @@ -28,14 +29,19 @@ void receiveIR() Serial.println("Send IR Code"); irsend.send(dresults.decode_type, dresults.value, dresults.bits); } - irTimer.start(); + irTimer.startOnce(); } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); // 115200 by default + Serial.println("Setting up..."); + irrecv.enableIRIn(); // Start the receiver - irTimer.initializeMs(200, receiveIR).start(); + irTimer.initializeMs<200>(receiveIR).startOnce(); + Serial.println("Ready..."); } diff --git a/samples/LED_WS2812/app/application.cpp b/samples/LED_WS2812/app/application.cpp index 7e39358bad..bff8a7e489 100644 --- a/samples/LED_WS2812/app/application.cpp +++ b/samples/LED_WS2812/app/application.cpp @@ -2,18 +2,26 @@ #define LED_PIN 2 // GPIO2 -void init() +namespace { - while(true) { - char buffer1[] = "\x40\x00\x00\x00\x40\x00\x00\x00\x40"; - ws2812_writergb(LED_PIN, buffer1, sizeof(buffer1)); - os_delay_us(500000); - - //We need to feed WDT. - WDT.alive(); +SimpleTimer procTimer; +bool state; +void update() +{ + if(state) { char buffer2[] = "\x00\x40\x40\x40\x00\x40\x40\x40\x00"; ws2812_writergb(LED_PIN, buffer2, sizeof(buffer2)); - os_delay_us(500000); + } else { + char buffer1[] = "\x40\x00\x00\x00\x40\x00\x00\x00\x40"; + ws2812_writergb(LED_PIN, buffer1, sizeof(buffer1)); } + state = !state; +} + +} // namespace + +void init() +{ + procTimer.initializeMs<500>(update).start(); } diff --git a/samples/LED_YeelightBulb/app/application.cpp b/samples/LED_YeelightBulb/app/application.cpp index 734e681cfa..384d0e1d12 100644 --- a/samples/LED_YeelightBulb/app/application.cpp +++ b/samples/LED_YeelightBulb/app/application.cpp @@ -7,11 +7,13 @@ #define WIFI_PWD "PleaseEnterPass" #endif +namespace +{ // Enter your bulb IP here: YeelightBulb bulb(IpAddress("192.168.1.100")); -Timer procTimer; -bool state = false; +SimpleTimer procTimer; +bool state; void blink() { @@ -27,13 +29,15 @@ void blink() // Will be called when WiFi station was connected to AP void gotIP(IpAddress ip, IpAddress netmask, IpAddress gateway) { - debugf("I'm CONNECTED"); + Serial << _F("I'm CONNECTED, IP ") << ip << endl; // Connection to Yeelight Bulb will be established on any first action: bulb.updateState(); // Read actual bulb state - procTimer.initializeMs(5000, blink).start(); + procTimer.initializeMs<5000>(blink).start(); } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); // 115200 by default diff --git a/samples/Light_BH1750/app/application.cpp b/samples/Light_BH1750/app/application.cpp index d55733ceb3..790e8de670 100644 --- a/samples/Light_BH1750/app/application.cpp +++ b/samples/Light_BH1750/app/application.cpp @@ -1,6 +1,8 @@ #include #include +namespace +{ /* Set the Address pin state to change I2C address: BH1750FVI_ADDRESS_LOW "0x23" - usually by default @@ -8,7 +10,7 @@ BH1750FVI_ADDRESS_HIGH "0x5C" */ BH1750FVI LightSensor(BH1750FVI_ADDRESS_LOW); -Timer procTimer; +SimpleTimer procTimer; void readLight() { @@ -19,15 +21,19 @@ void readLight() Serial.println(" lux"); } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); // 115200 by default Serial.systemDebugOutput(false); // Disable debug output to serial - if(LightSensor.begin() == 0) - Serial.println(_F("LightSensor initialized")); - else + if(LightSensor.begin() != 0) { Serial.println(_F("LightSensor not available. May be wrong I2C address?")); + return; + } + + Serial.println(_F("LightSensor initialized")); /* Set the Working Mode for this sensor @@ -36,5 +42,5 @@ void init() LightSensor.setMode(BH1750_Continuous_H_resolution_Mode); // Start reading loop - procTimer.initializeMs(300, readLight).start(); + procTimer.initializeMs<300>(readLight).start(); } diff --git a/samples/LiquidCrystal_44780/app/application.cpp b/samples/LiquidCrystal_44780/app/application.cpp index 7bf4477424..5462634d21 100644 --- a/samples/LiquidCrystal_44780/app/application.cpp +++ b/samples/LiquidCrystal_44780/app/application.cpp @@ -9,8 +9,54 @@ // For more information visit useful wiki page: http://arduino-info.wikispaces.com/LCD-Blue-I2C #define I2C_LCD_ADDR 0x27 + LiquidCrystal_I2C lcd(I2C_LCD_ADDR, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); +SimpleTimer flashTimer; + +//-------- Write characters on the display ------------------ +void writeDisplay() +{ + debug_d("%s", __FUNCTION__); + + // NOTE: Cursor Position: (CHAR, LINE) start at 0 + lcd.setCursor(0, 0); + lcd.print(_F("SMING: Let's do")); + lcd.setCursor(0, 1); + lcd.print(_F("smart things!")); +} + +// ------- Quick 3 blinks of backlight ------------- +void flashBacklight() +{ + static unsigned state; + + if(state == 6) { + debug_d("%s DONE", __FUNCTION__); + lcd.backlight(); // finish with backlight on + writeDisplay(); + return; + } + + if(state == 0) { + debug_d("%s INIT", __FUNCTION__); + flashTimer.setCallback(flashBacklight); + } + + if(state & 0x01) { + debug_d("%s OFF", __FUNCTION__); + lcd.noBacklight(); + flashTimer.setIntervalMs<250>(); + } else { + debug_d("%s ON", __FUNCTION__); + lcd.backlight(); + flashTimer.setIntervalMs<150>(); + } + + ++state; + flashTimer.startOnce(); +} + void init() { Serial.begin(SERIAL_BAUD_RATE); // 115200 by default @@ -20,19 +66,5 @@ void init() lcd.begin(16, 2); // initialize the lcd for 16 chars 2 lines, turn on backlight - // ------- Quick 3 blinks of backlight ------------- - for(int i = 0; i < 3; i++) { - lcd.backlight(); - delay(150); - lcd.noBacklight(); - delay(250); - } - lcd.backlight(); // finish with backlight on - - //-------- Write characters on the display ------------------ - // NOTE: Cursor Position: (CHAR, LINE) start at 0 - lcd.setCursor(0, 0); - lcd.print(_F("SMING: Let's do")); - lcd.setCursor(0, 1); - lcd.print(_F("smart things!")); + flashBacklight(); } diff --git a/samples/LiveDebug/README.rst b/samples/LiveDebug/README.rst index 202edf6ed0..4125fa9ad7 100644 --- a/samples/LiveDebug/README.rst +++ b/samples/LiveDebug/README.rst @@ -13,7 +13,7 @@ simply build and flash the project as usual:: make clean make flash -You should be presented with the GDB command prompt. Enter ‘c’ to +You should be presented with the GDB command prompt. Enter 'c' to continue running the application: .. code-block:: text @@ -26,7 +26,7 @@ The ``(attached)`` prompt is displayed by the LiveDebug application. Type ``help`` to get a list of available commands. Note that if you run this application via serial terminal -(``make terminal``) you’ll get the ``(Detached)`` prompt instead. +(``make terminal``) you'll get the ``(Detached)`` prompt instead. 2. Debugging under eclipse @@ -124,9 +124,9 @@ has run into an exception, use the provided script:: make gdb -Note that software breakpoints (‘br’) only work on code that is in RAM. +Note that software breakpoints ('br') only work on code that is in RAM. During development you can use the GDB_IRAM_ATTR attribute in your function declarations. Code in flash can only have a hardware breakpoint -(‘hbr’). +('hbr'). Read the GDB stub :component-esp8266:`Notes ` for more information. diff --git a/samples/LiveDebug/app/application.cpp b/samples/LiveDebug/app/application.cpp index 6b7a5bd780..108ff73fa0 100644 --- a/samples/LiveDebug/app/application.cpp +++ b/samples/LiveDebug/app/application.cpp @@ -8,6 +8,8 @@ #define LED_PIN 2 // Note: LED is attached to UART1 TX output +namespace +{ // Max length of debug command const unsigned MAX_COMMAND_LENGTH = 64; @@ -49,18 +51,15 @@ Timer procTimer; #define CALLBACK_ATTR GDB_IRAM_ATTR #endif -// See blink() -bool ledState = true; - // A simple log file stored on the host -static GdbFileStream logFile; +GdbFileStream logFile; #define LOG_FILENAME "testlog.txt" // Handles messages from SDK -static OsMessageInterceptor osMessageInterceptor; +OsMessageInterceptor osMessageInterceptor; // Supports `consoleOff` command to prevent re-enabling when debugger is attached -bool consoleOffRequested = false; +bool consoleOffRequested; // IFS::Gdb::FileSystem gdbfs; @@ -75,8 +74,10 @@ void readConsole(); */ void CALLBACK_ATTR blink() { - digitalWrite(LED_PIN, ledState); + static bool ledState; + ledState = !ledState; + digitalWrite(LED_PIN, ledState); } void showPrompt() @@ -96,9 +97,7 @@ void showPrompt() void onDataReceived(Stream& source, char arrivedChar, unsigned short availableCharsCount) { - static unsigned commandLength; - const unsigned MAX_COMMAND_LENGTH = 16; - static char commandBuffer[MAX_COMMAND_LENGTH + 1]; + static LineBuffer commandBuffer; // Error detection unsigned status = Serial.getStatus(); @@ -118,38 +117,25 @@ void onDataReceived(Stream& source, char arrivedChar, unsigned short availableCh } // Discard what is likely to be garbage Serial.clear(SERIAL_RX_ONLY); - commandLength = 0; + commandBuffer.clear(); showPrompt(); return; } - int c; - while((c = Serial.read()) >= 0) { - switch(c) { - case '\b': // delete (backspace) - case 0x7f: // xterm ctrl-? - if(commandLength > 0) { - --commandLength; - Serial.print(_F("\b \b")); - } - break; - case '\r': - case '\n': - if(commandLength > 0) { - Serial.println(); - String cmd(commandBuffer, commandLength); - commandLength = 0; - Serial.clear(SERIAL_RX_ONLY); - handleCommand(cmd); - } - showPrompt(); - break; - default: - if(c >= 0x20 && c <= 0x7f && commandLength < MAX_COMMAND_LENGTH) { - commandBuffer[commandLength++] = c; - Serial.print(char(c)); - } + switch(commandBuffer.process(source, Serial)) { + case LineBufferBase::Action::clear: + showPrompt(); + break; + case LineBufferBase::Action::submit: { + if(commandBuffer) { + handleCommand(String(commandBuffer)); + commandBuffer.clear(); } + showPrompt(); + break; + } + default: + break; } } @@ -231,6 +217,7 @@ void asyncReadCallback(const GdbSyscallInfo& info) Serial << _F("readFileAsync: total = ") << transfer.total << _F(", elapsed = ") << elapsed << _F(" ms, av. ") << bps << _F(" bytes/sec") << endl; readConsole(); + break; } default:; @@ -413,7 +400,7 @@ COMMAND_HANDLER(read0) "At GDB prompt, enter `set $pc = $pc + 3` to skip offending instruction,\r\n" "then enter `c` to continue")); Serial.flush(); - uint8_t value = *(uint8_t*)0; + uint8_t value = *(volatile uint8_t*)0; Serial << _F("Value at address 0 = 0x") << String(value, HEX, 2) << endl; return true; } @@ -424,7 +411,7 @@ COMMAND_HANDLER(write0) "At GDB prompt, enter `set $pc = $pc + 3` to skip offending instruction,\r\n" "then enter `c` to continue")); Serial.flush(); - *(uint8_t*)0 = 0; + *(volatile uint8_t*)0 = 0; Serial.println(_F("...still running!")); return true; } @@ -434,7 +421,7 @@ COMMAND_HANDLER(write0) * @param msg * @retval bool true if we want to report this */ -static bool __noinline parseOsMessage(OsMessage& msg) +bool __noinline parseOsMessage(OsMessage& msg) { m_printf(_F("[OS] %s\r\n"), msg.getBuffer()); if(msg.startsWith(_F("E:M "))) { @@ -452,7 +439,7 @@ static bool __noinline parseOsMessage(OsMessage& msg) * @brief Called when the OS outputs a debug message using os_printf, etc. * @param msg The message */ -static void onOsMessage(OsMessage& msg) +void onOsMessage(OsMessage& msg) { // Note: We do the check in a separate function to avoid messing up the stack pointer if(parseOsMessage(msg)) { @@ -638,6 +625,14 @@ void readConsole() })); } +void printTimerDetails() +{ + Serial << procTimer << ", maxTicks = " << procTimer.maxTicks() + << ", maxTime = " << procTimer.micros().ticksToTime(procTimer.maxTicks()).value() << endl; +} + +} // namespace + extern "C" void gdb_on_attach(bool attached) { debug_i("GdbAttach(%d)", attached); @@ -662,12 +657,6 @@ extern "C" void gdb_on_attach(bool attached) } } -static void printTimerDetails() -{ - Serial << procTimer << ", maxTicks = " << procTimer.maxTicks() - << ", maxTime = " << procTimer.micros().ticksToTime(procTimer.maxTicks()).value() << endl; -} - void GDB_IRAM_ATTR init() { Serial.begin(SERIAL_BAUD_RATE); diff --git a/samples/MeteoControl/app/application.cpp b/samples/MeteoControl/app/application.cpp index b320285b4d..9509a4a92a 100644 --- a/samples/MeteoControl/app/application.cpp +++ b/samples/MeteoControl/app/application.cpp @@ -10,6 +10,11 @@ #include "special_chars.h" #include "webserver.h" +// Sensors string values +String StrT, StrRH, StrTime; + +namespace +{ DHTesp dht; // For more information visit useful wiki page: http://arduino-info.wikispaces.com/LCD-Blue-I2C @@ -17,53 +22,9 @@ DHTesp dht; #define I2C_LCD_ADDR 0x27 LiquidCrystal_I2C lcd(I2C_LCD_ADDR, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); -Timer procTimer; -Timer displayTimer; +SimpleTimer procTimer; +SimpleTimer displayTimer; bool state = true; -// Sensors string values -String StrT, StrRH, StrTime; - -void process(); -void connectOk(const String& SSID, MacAddress bssid, uint8_t channel); -void connectFail(const String& ssid, MacAddress bssid, WifiDisconnectReason reason); -void gotIP(IpAddress ip, IpAddress netmask, IpAddress gateway); - -void init() -{ - spiffs_mount(); // Mount file system, in order to work with files - - Serial.begin(SERIAL_BAUD_RATE); // 115200 by default - Serial.systemDebugOutput(false); // Debug output to serial - - ActiveConfig = loadConfig(); - - // Select control line - pinMode(CONTROL_PIN, OUTPUT); - - // DHT sensor start - dht.setup(DHT_PIN, DHTesp::DHT11); - - lcd.begin(16, 2); - lcd.backlight(); - lcd.createChar(1, icon_termometer); - lcd.createChar(2, icon_water); - lcd.createChar(3, celsius); - lcd.createChar(4, icon_retarrow); - lcd.createChar(5, icon_clock); - lcd.createChar(6, icon_cross); - lcd.createChar(7, icon_check); - - WifiStation.config(ActiveConfig.NetworkSSID, ActiveConfig.NetworkPassword); - WifiStation.enable(true); - WifiAccessPoint.enable(false); - - WifiEvents.onStationConnect(connectOk); - WifiEvents.onStationDisconnect(connectFail); - WifiEvents.onStationGotIP(gotIP); - - procTimer.initializeMs(5000, process).start(); - process(); -} void showValues() { @@ -93,17 +54,19 @@ void process() float t = dht.getTemperature() + ActiveConfig.AddT; float h = dht.getHumidity() + ActiveConfig.AddRH; - if(ActiveConfig.Trigger == eTT_Temperature) + if(ActiveConfig.Trigger == eTT_Temperature) { state = t < ActiveConfig.RangeMin || t > ActiveConfig.RangeMax; - else if(ActiveConfig.Trigger == eTT_Humidity) + } else if(ActiveConfig.Trigger == eTT_Humidity) { state = h < ActiveConfig.RangeMin || h > ActiveConfig.RangeMax; + } digitalWrite(CONTROL_PIN, state); StrT = String(t, 0); StrRH = String(h, 0); - if(!displayTimer.isStarted()) - displayTimer.initializeMs(1000, showValues).start(); + if(!displayTimer.isStarted()) { + displayTimer.initializeMs<1000>(showValues).start(); + } } void connectOk(const String& SSID, MacAddress bssid, uint8_t channel) @@ -115,8 +78,7 @@ void connectOk(const String& SSID, MacAddress bssid, uint8_t channel) void gotIP(IpAddress ip, IpAddress netmask, IpAddress gateway) { lcd.clear(); - lcd.print("\7 "); - lcd.print(ip); + lcd << "\7 " << ip; // Restart main screen output procTimer.restart(); displayTimer.stop(); @@ -124,10 +86,11 @@ void gotIP(IpAddress ip, IpAddress netmask, IpAddress gateway) startWebClock(); // At first run we will download web server content if(!fileExist("index.html") || !fileExist("config.html") || !fileExist("api.html") || - !fileExist("bootstrap.css.gz") || !fileExist("jquery.js.gz")) + !fileExist("bootstrap.css.gz") || !fileExist("jquery.js.gz")) { downloadContentFiles(); - else + } else { startWebServer(); + } } void connectFail(const String& ssid, MacAddress bssid, WifiDisconnectReason reason) @@ -152,26 +115,31 @@ void connectFail(const String& ssid, MacAddress bssid, WifiDisconnectReason reas } ////// WEB Clock ////// -Timer clockRefresher; + +SimpleTimer clockRefresher; HttpClient clockWebClient; -uint32_t lastClockUpdate = 0; +uint32_t lastClockUpdate; DateTime clockValue; const int clockUpdateIntervalMs = 10 * 60 * 1000; // Update web clock every 10 minutes int onClockUpdating(HttpConnection& client, bool successful) { + auto& response = *client.getResponse(); + if(!successful) { - debugf("CLOCK UPDATE FAILED %d (code: %d)", successful, client.getResponse()->code); + Serial << _F("CLOCK UPDATE FAILED, ") << response.code << " " << toString(response.code) << endl; lastClockUpdate = 0; return -1; } // Extract date header from response - clockValue = client.getResponse()->headers.getServerDate(); - if(clockValue.isNull()) - clockValue = client.getResponse()->headers.getLastModifiedDate(); - if(!clockValue.isNull()) + clockValue = response.headers.getServerDate(); + if(clockValue.isNull()) { + clockValue = response.headers.getLastModifiedDate(); + } + if(!clockValue.isNull()) { clockValue.addMilliseconds(ActiveConfig.AddTZ * 1000 * 60 * 60); + } return 0; } @@ -179,27 +147,65 @@ int onClockUpdating(HttpConnection& client, bool successful) void refreshClockTime() { uint32_t nowClock = millis(); - if(nowClock < lastClockUpdate) + if(nowClock < lastClockUpdate) { lastClockUpdate = 0; // Prevent overflow, restart + } if((lastClockUpdate == 0 || nowClock - lastClockUpdate > clockUpdateIntervalMs)) { clockWebClient.downloadString("google.com", onClockUpdating); lastClockUpdate = nowClock; - } else if(!clockValue.isNull()) + } else if(!clockValue.isNull()) { clockValue.addMilliseconds(clockRefresher.getIntervalMs()); + } - if(!clockValue.isNull()) { - StrTime = clockValue.toShortDateString() + " " + clockValue.toShortTimeString(false); - - if((millis() % 2000) > 1000) - StrTime.setCharAt(13, ' '); - else - StrTime.setCharAt(13, ':'); + if(clockValue.isNull()) { + return; } + + StrTime = clockValue.toShortDateString() + " " + clockValue.toShortTimeString(false); + StrTime.setCharAt(13, ((nowClock % 2000) > 1000) ? ' ' : ':'); } +} // namespace + void startWebClock() { lastClockUpdate = 0; - clockRefresher.stop(); - clockRefresher.initializeMs(500, refreshClockTime).start(); + clockRefresher.initializeMs<500>(refreshClockTime).start(); +} + +void init() +{ + Serial.begin(SERIAL_BAUD_RATE); // 115200 by default + Serial.systemDebugOutput(false); // Debug output to serial + + spiffs_mount(); // Mount file system, in order to work with files + + ActiveConfig = loadConfig(); + + // Select control line + pinMode(CONTROL_PIN, OUTPUT); + + // DHT sensor start + dht.setup(DHT_PIN, DHTesp::DHT11); + + lcd.begin(16, 2); + lcd.backlight(); + lcd.createChar(1, icon_termometer); + lcd.createChar(2, icon_water); + lcd.createChar(3, celsius); + lcd.createChar(4, icon_retarrow); + lcd.createChar(5, icon_clock); + lcd.createChar(6, icon_cross); + lcd.createChar(7, icon_check); + + WifiStation.config(ActiveConfig.NetworkSSID, ActiveConfig.NetworkPassword); + WifiStation.enable(true); + WifiAccessPoint.enable(false); + + WifiEvents.onStationConnect(connectOk); + WifiEvents.onStationDisconnect(connectFail); + WifiEvents.onStationGotIP(gotIP); + + procTimer.initializeMs<5000>(process).start(); + process(); } diff --git a/samples/MeteoControl/app/configuration.cpp b/samples/MeteoControl/app/configuration.cpp index 603130b664..fb844d0977 100644 --- a/samples/MeteoControl/app/configuration.cpp +++ b/samples/MeteoControl/app/configuration.cpp @@ -1,7 +1,5 @@ #include "configuration.h" -#include - MeteoConfig ActiveConfig; MeteoConfig loadConfig() @@ -23,8 +21,8 @@ MeteoConfig loadConfig() cfg.RangeMin = trigger["min"]; cfg.RangeMax = trigger["max"]; } else { - cfg.NetworkSSID = WIFI_SSID; - cfg.NetworkPassword = WIFI_PWD; + cfg.NetworkSSID = F(WIFI_SSID); + cfg.NetworkPassword = F(WIFI_PWD); } return cfg; } diff --git a/samples/MeteoControl/app/webserver.cpp b/samples/MeteoControl/app/webserver.cpp index bc1cc12adb..fff647f7bc 100644 --- a/samples/MeteoControl/app/webserver.cpp +++ b/samples/MeteoControl/app/webserver.cpp @@ -1,11 +1,15 @@ #include - #include "configuration.h" +#include "webserver.h" -bool serverStarted = false; -HttpServer server; extern String StrT, StrRH; // Sensors string values +namespace +{ +HttpServer server; +HttpClient downloadClient; +bool serverStarted; + void onIndex(HttpRequest& request, HttpResponse& response) { TemplateFileStream* tmpl = new TemplateFileStream("index.html"); @@ -92,23 +96,44 @@ void onApiSensors(HttpRequest& request, HttpResponse& response) void onApiOutput(HttpRequest& request, HttpResponse& response) { int val = request.getQueryParameter("control", "-1").toInt(); - if(val == 0 || val == 1) + if(val == 0 || val == 1) { digitalWrite(CONTROL_PIN, val == 1); - else + } else { val = -1; + } JsonObjectStream* stream = new JsonObjectStream(); JsonObject json = stream->getRoot(); - json["status"] = val != -1; - if(val == -1) + json["status"] = val >= 0; + if(val < 0) json["error"] = "Wrong control parameter value, please use: ?control=0|1"; response.sendDataStream(stream, MIME_JSON); } +} // namespace + +void downloadContentFiles() +{ + debugf("DownloadContentFiles"); + + downloadClient.downloadFile(F("http://simple.anakod.ru/templates/MeteoControl/MeteoControl.html"), "index.html"); + downloadClient.downloadFile(F("http://simple.anakod.ru/templates/MeteoControl/MeteoConfig.html"), "config.html"); + downloadClient.downloadFile(F("http://simple.anakod.ru/templates/MeteoControl/MeteoAPI.html"), "api.html"); + downloadClient.downloadFile(F("http://simple.anakod.ru/templates/bootstrap.css.gz")); + downloadClient.downloadFile(F("http://simple.anakod.ru/templates/jquery.js.gz"), + [](HttpConnection& connection, bool success) -> int { + if(success) { + startWebServer(); + } + return 0; + }); +} + void startWebServer() { - if(serverStarted) + if(serverStarted) { return; + } server.listen(80); server.paths.set("/", onIndex); @@ -124,24 +149,3 @@ void startWebServer() if(WifiAccessPoint.isEnabled()) debugf("AP: %s", WifiAccessPoint.getIP().toString().c_str()); } - -/// FileSystem Initialization /// - -HttpClient downloadClient; -int dowfid = 0; -void downloadContentFiles() -{ - debugf("DownloadContentFiles"); - - downloadClient.downloadFile("http://simple.anakod.ru/templates/MeteoControl/MeteoControl.html", "index.html"); - downloadClient.downloadFile("http://simple.anakod.ru/templates/MeteoControl/MeteoConfig.html", "config.html"); - downloadClient.downloadFile("http://simple.anakod.ru/templates/MeteoControl/MeteoAPI.html", "api.html"); - downloadClient.downloadFile("http://simple.anakod.ru/templates/bootstrap.css.gz"); - downloadClient.downloadFile("http://simple.anakod.ru/templates/jquery.js.gz", - (RequestCompletedDelegate)([](HttpConnection& connection, bool success) -> int { - if(success) { - startWebServer(); - } - return 0; - })); -} diff --git a/samples/MeteoControl/include/configuration.h b/samples/MeteoControl/include/configuration.h index d39a298f39..24b490c888 100644 --- a/samples/MeteoControl/include/configuration.h +++ b/samples/MeteoControl/include/configuration.h @@ -1,5 +1,4 @@ -#ifndef INCLUDE_CONFIGURATION_H_ -#define INCLUDE_CONFIGURATION_H_ +#pragma once #include #include @@ -20,7 +19,11 @@ #define METEO_CONFIG_FILE ".meteo.conf" // leading point for security reasons :) -enum TriggerType { eTT_None = 0, eTT_Temperature, eTT_Humidity }; +enum TriggerType { + eTT_None = 0, + eTT_Temperature, + eTT_Humidity, +}; struct MeteoConfig { MeteoConfig() @@ -50,5 +53,3 @@ void saveConfig(MeteoConfig& cfg); extern void startWebClock(); extern MeteoConfig ActiveConfig; - -#endif /* INCLUDE_CONFIGURATION_H_ */ diff --git a/samples/MeteoControl/include/webserver.h b/samples/MeteoControl/include/webserver.h index 9ce09aa046..54f6987fc9 100644 --- a/samples/MeteoControl/include/webserver.h +++ b/samples/MeteoControl/include/webserver.h @@ -1,7 +1,4 @@ -#ifndef INCLUDE_WEBSERVER_H_ -#define INCLUDE_WEBSERVER_H_ +#pragma once void startWebServer(); void downloadContentFiles(); - -#endif /* INCLUDE_WEBSERVER_H_ */ diff --git a/samples/MeteoControl_mqtt/app/application.cpp b/samples/MeteoControl_mqtt/app/application.cpp index 9fb95ca902..5851177202 100644 --- a/samples/MeteoControl_mqtt/app/application.cpp +++ b/samples/MeteoControl_mqtt/app/application.cpp @@ -1,13 +1,14 @@ #include #include - #include "configuration.h" // application configuration -#include "bmp180.cpp" // bmp180 configuration -#include "si7021.cpp" // htu21d configuration +extern void BMPinit(); +extern void SIinit(); -Timer publishTimer; +MqttClient mqtt; +namespace +{ // Publish our message void publishMessage() // uncomment timer in connectOk() if need publishMessage() loop { @@ -26,7 +27,15 @@ int onMessageReceived(MqttClient& client, mqtt_message_t* message) return 0; } -// Run MQTT client +void gotIP(IpAddress ip, IpAddress netmask, IpAddress gateway) +{ + Serial << _F("Connected: ") << ip << endl; + startMqttClient(); + publishMessage(); // run once publishMessage +} + +} // namespace + void startMqttClient() { Url url(URI_SCHEME_MQTT, F(LOG), F(PASS), F(MQTT_SERVER), MQTT_PORT); @@ -35,13 +44,6 @@ void startMqttClient() mqtt.subscribe(SUB_TOPIC); } -void gotIP(IpAddress ip, IpAddress netmask, IpAddress gateway) -{ - Serial << _F("Connected: ") << ip << endl; - startMqttClient(); - publishMessage(); // run once publishMessage -} - void init() { Serial.begin(SERIAL_BAUD_RATE); // 115200 by default diff --git a/samples/MeteoControl_mqtt/app/bmp180.cpp b/samples/MeteoControl_mqtt/app/bmp180.cpp index de51ac26c7..024b8c1696 100644 --- a/samples/MeteoControl_mqtt/app/bmp180.cpp +++ b/samples/MeteoControl_mqtt/app/bmp180.cpp @@ -1,6 +1,3 @@ -#ifndef INCLUDE_BMP180_H_ -#define INCLUDE_BMP180_H_ - #include #include @@ -9,9 +6,10 @@ // GPIO0 SCL // GPIO2 SDA +namespace +{ BMP180 barometer; - -Timer publishBMPTimer; +SimpleTimer publishBMPTimer; void publishBMP() { @@ -22,27 +20,29 @@ void publishBMP() Serial.println(_F("Start reading BMP180 sensor")); if(!barometer.EnsureConnected()) { Serial.println(_F("Could not connect to BMP180")); - } else { - // Retrieve the current pressure in Pascals - long currentPressure = barometer.GetPressure(); - // convert pressure to mmHg - float BMPPress = currentPressure / 133.322; - - // Print out the Pressure - Serial << _F("Pressure: ") << BMPPress << _F(" mmHg") << endl; - mqtt.publish(BMP_P, String(BMPPress)); - - // Retrieve the current temperature in degrees celsius - float BMPTemp = barometer.GetTemperature(); - - // Print out the Temperature - Serial << _F("Temperature: ") << BMPTemp << " °C" << endl; - mqtt.publish(BMP_T, String(BMPTemp)); - Serial.println(_F("BMP180 sensor read and transmitted to server\r\n" - "********************************************")); + return; } + // Retrieve the current pressure in Pascals + long currentPressure = barometer.GetPressure(); + // convert pressure to mmHg + float BMPPress = currentPressure / 133.322; + + // Print out the Pressure + Serial << _F("Pressure: ") << BMPPress << _F(" mmHg") << endl; + mqtt.publish(BMP_P, String(BMPPress)); + + // Retrieve the current temperature in degrees celsius + float BMPTemp = barometer.GetTemperature(); + + // Print out the Temperature + Serial << _F("Temperature: ") << BMPTemp << " °C" << endl; + mqtt.publish(BMP_T, String(BMPTemp)); + Serial.println(_F("BMP180 sensor read and transmitted to server\r\n" + "********************************************")); } +} // namespace + void BMPinit() { // When we have connected, we reset the device to ensure a clean start. @@ -52,7 +52,5 @@ void BMPinit() barometer.Initialize(); barometer.PrintCalibrationData(); - publishBMPTimer.initializeMs(TIMER * 3000, publishBMP).start(); // start publish BMP180 sensor data + publishBMPTimer.initializeMs(publishBMP).start(); // start publish BMP180 sensor data } - -#endif /* INCLUDE_BMP180_H_ */ diff --git a/samples/MeteoControl_mqtt/app/si7021.cpp b/samples/MeteoControl_mqtt/app/si7021.cpp index 8fb2c61fe6..7eb1000f20 100644 --- a/samples/MeteoControl_mqtt/app/si7021.cpp +++ b/samples/MeteoControl_mqtt/app/si7021.cpp @@ -1,14 +1,12 @@ -#ifndef INCLUDE_SI7021_H_ -#define INCLUDE_SI7021_H_ - #include #include #include "configuration.h" +namespace +{ SI7021 hydrometer; - -Timer publishSITimer; +SimpleTimer publishSITimer; void publishSI() { @@ -21,28 +19,30 @@ void publishSI() if(!hydrometer.begin()) { Serial.println(_F("Could not connect to SI7021")); - } else { - si7021_env data = hydrometer.getHumidityAndTemperature(); - if(data.error_crc == 1) { - Serial.println(_F("\tCRC ERROR")); - } else { - float SIhum = data.humidityPercent; - // Print out the humidity - Serial << _F("Humidity: ") << SIhum << '%' << endl; - mqtt.publish(SI_H, String(SIhum)); - float SITemp = data.temperature; - // Print out the Temperature - Serial << _F("Temperature: ") << SITemp / 100 << " °C" << endl; - mqtt.publish(SI_T, String(SITemp / 100)); - Serial.println(_F("SI sensor read and transmitted to server\r\n" - "*********************************************")); - } + return; + } + + si7021_env data = hydrometer.getHumidityAndTemperature(); + if(data.error_crc == 1) { + Serial.println(_F("\tCRC ERROR")); + return; } + + float SIhum = data.humidityPercent; + // Print out the humidity + Serial << _F("Humidity: ") << SIhum << '%' << endl; + mqtt.publish(SI_H, String(SIhum)); + float SITemp = data.temperature; + // Print out the Temperature + Serial << _F("Temperature: ") << SITemp / 100 << " °C" << endl; + mqtt.publish(SI_T, String(SITemp / 100)); + Serial.println(_F("SI sensor read and transmitted to server\r\n" + "*********************************************")); } +} // namespace + void SIinit() { - publishSITimer.initializeMs(TIMER * 1000, publishSI).start(); // start publish SI sensor data + publishSITimer.initializeMs(publishSI).start(); // start publish SI sensor data } - -#endif /* INCLUDE_SI7021_H_ */ diff --git a/samples/MeteoControl_mqtt/include/configuration.h b/samples/MeteoControl_mqtt/include/configuration.h index ba02ccdb83..a1d3cbf9ea 100644 --- a/samples/MeteoControl_mqtt/include/configuration.h +++ b/samples/MeteoControl_mqtt/include/configuration.h @@ -1,7 +1,6 @@ -#ifndef INCLUDE_CONFIGURATION_H_ -#define INCLUDE_CONFIGURATION_H_ +#pragma once -#include +#include //////////////////////////// Wi-Fi config /////////////////////////////////////// #ifndef WIFI_SSID @@ -31,13 +30,14 @@ #define SI_H "testing/status/SI7021/Humidity" #define VER_TOPIC "testing/firmware/version" -int TIMER = 20; // every N* seconds send to mqtt server +constexpr int TIMER = 20; // every N* seconds send to mqtt server -// Forward declarations -void startMqttClient(); - -MqttClient mqtt; +enum TriggerType { + eTT_None = 0, + eTT_Temperature, + eTT_Humidity, +}; -enum TriggerType { eTT_None = 0, eTT_Temperature, eTT_Humidity }; +void startMqttClient(); -#endif /* INCLUDE_CONFIGURATION_H_ */ +extern MqttClient mqtt; diff --git a/samples/MqttClient_Hello/app/application.cpp b/samples/MqttClient_Hello/app/application.cpp index d2f8772610..b27b3a7302 100644 --- a/samples/MqttClient_Hello/app/application.cpp +++ b/samples/MqttClient_Hello/app/application.cpp @@ -7,25 +7,22 @@ #define WIFI_PWD "PleaseEnterPass" #endif -// For testing purposes, try a few different URL formats -#define MQTT_URL1 "mqtt://test.mosquitto.org:1883" -#define MQTT_URL2 "mqtts://test.mosquitto.org:8883" // (Need ENABLE_SSL) -#define MQTT_URL3 "mqtt://frank:fiddle@192.168.100.107:1883" - +namespace +{ #ifdef ENABLE_SSL #include #include -#define MQTT_URL MQTT_URL2 +DEFINE_FSTR(MQTT_URL, "mqtts://test.mosquitto.org:8883") #else -#define MQTT_URL MQTT_URL1 +DEFINE_FSTR(MQTT_URL, "mqtt://test.mosquitto.org:1883") +// DEFINE_FSTR(MQTT_URL, "mqtt://frank:fiddle@192.168.100.107:1883") #endif // Forward declarations void startMqttClient(); MqttClient mqtt; - -Timer procTimer; +SimpleTimer procTimer; // Check for MQTT Disconnection void checkMQTTDisconnect(TcpClient& client, bool flag) @@ -37,7 +34,7 @@ void checkMQTTDisconnect(TcpClient& client, bool flag) } // Restart connection attempt after few seconds - procTimer.initializeMs(2 * 1000, startMqttClient).start(); // every 2 seconds + procTimer.initializeMs<2 * 1000>(startMqttClient).start(); // every 2 seconds } int onMessageDelivered(MqttClient& client, mqtt_message_t* message) @@ -88,7 +85,7 @@ void startMqttClient() // Start publishing message now publishMessage(); // and schedule a timer to send messages every 5 seconds - procTimer.initializeMs(5 * 1000, publishMessage).start(); + procTimer.initializeMs<5 * 1000>(publishMessage).start(); return 0; }); @@ -118,6 +115,8 @@ void onConnected(IpAddress ip, IpAddress netmask, IpAddress gateway) startMqttClient(); } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); // 115200 by default diff --git a/samples/MqttClient_Hello/include/ssl/cert.h b/samples/MqttClient_Hello/include/ssl/cert.h index 61ca8a654e..656efaadbd 100644 --- a/samples/MqttClient_Hello/include/ssl/cert.h +++ b/samples/MqttClient_Hello/include/ssl/cert.h @@ -1,4 +1,4 @@ -unsigned char default_certificate[] = { +unsigned char default_certificate[] PROGMEM = { 0x30, 0x82, 0x01, 0xd7, 0x30, 0x82, 0x01, 0x40, 0x02, 0x09, 0x00, 0xab, 0x08, 0x18, 0xa7, 0x03, 0x07, 0x27, 0xfd, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x34, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x29, 0x61, 0x78, 0x54, 0x4c, 0x53, 0x20, 0x50, 0x72, 0x6f, 0x6a, diff --git a/samples/MqttClient_Hello/include/ssl/private_key.h b/samples/MqttClient_Hello/include/ssl/private_key.h index 31de50cb53..e4d72a0bfc 100644 --- a/samples/MqttClient_Hello/include/ssl/private_key.h +++ b/samples/MqttClient_Hello/include/ssl/private_key.h @@ -1,4 +1,4 @@ -unsigned char default_private_key[] = { +unsigned char default_private_key[] PROGMEM = { 0x30, 0x82, 0x02, 0x5d, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xcd, 0xfd, 0x89, 0x48, 0xbe, 0x36, 0xb9, 0x95, 0x76, 0xd4, 0x13, 0x30, 0x0e, 0xbf, 0xb2, 0xed, 0x67, 0x0a, 0xc0, 0x16, 0x3f, 0x51, 0x09, 0x9d, 0x29, 0x2f, 0xb2, 0x6d, 0x3f, 0x3e, 0x6c, 0x2f, 0x90, 0x80, 0xa1, 0x71, 0xdf, 0xbe, 0x38, 0xc5, 0xcb, 0xa9, 0x9a, 0x40, 0x14, 0x90, diff --git a/samples/Network_Ping/app/application.cpp b/samples/Network_Ping/app/application.cpp index 1c7521fb95..360291aeee 100644 --- a/samples/Network_Ping/app/application.cpp +++ b/samples/Network_Ping/app/application.cpp @@ -18,9 +18,9 @@ constexpr uint8_t MAX_FAILED_ATTEMTPS = 5; constexpr uint8_t PING_INTERVAL_SECONDS = 10; constexpr uint8_t RESTART_DELAY_SECONDS = 2; -Timer procTimer; +SimpleTimer procTimer; -void ping(uint32 ip); +void ping(uint32_t ip); void pingTask() { @@ -45,7 +45,7 @@ void onSent(void* arg, void* pdata) } debug_d("Scheduling another ping in %d seconds", PING_INTERVAL_SECONDS); - procTimer.initializeMs(PING_INTERVAL_SECONDS * 1000, pingTask).startOnce(); + procTimer.initializeMs(pingTask).startOnce(); } void onReceived(void* arg, void* pdata) @@ -79,7 +79,7 @@ void ping(uint32_t ip) void connectOk(IpAddress ip, IpAddress mask, IpAddress gateway) { debug_d("Scheduling initial ping in 1 second."); - procTimer.initializeMs(1000, pingTask).startOnce(); + procTimer.initializeMs<1000>(pingTask).startOnce(); } } // namespace diff --git a/samples/Nextion_Button/app/application.cpp b/samples/Nextion_Button/app/application.cpp index 6bddd18ef9..75662f56cd 100644 --- a/samples/Nextion_Button/app/application.cpp +++ b/samples/Nextion_Button/app/application.cpp @@ -1,9 +1,6 @@ #include #include -#include -#include - #define GPIO_LED 2 // See this example in action: https://youtu.be/lHk6fqDBHyI @@ -22,22 +19,22 @@ // Note: I always unplugged the ESP8266 from USB (connecting with computer) // while fiddling with the connections between ESP8266 and Nextion display. -NexButton b0 = NexButton(0, 1, "b0"); -NexText t0 = NexText(0, 2, "g0"); - +namespace +{ +NexButton b0(0, 1, "b0"); +NexText t0(0, 2, "g0"); NexTouch* nex_listen_list[] = {&b0, NULL}; - -Timer timerNextion; +SimpleTimer timerNextion; void loopNextion() { nexLoop(nex_listen_list); } -bool ledState = true; - void b0PopCallback(void* ptr) { + static bool ledState = true; + digitalWrite(GPIO_LED, ledState); // state == false => on // state == true => off @@ -49,10 +46,12 @@ void b0PopCallback(void* ptr) ledState = !ledState; } +} // namespace + void init() { pinMode(GPIO_LED, OUTPUT); nexInit(); b0.attachPop(b0PopCallback, &b0); - timerNextion.initializeMs(100, loopNextion).start(); + timerNextion.initializeMs<100>(loopNextion).start(); } diff --git a/samples/PortExpander_MCP23017/app/application.cpp b/samples/PortExpander_MCP23017/app/application.cpp index 8b00bc081e..0e8953d236 100644 --- a/samples/PortExpander_MCP23017/app/application.cpp +++ b/samples/PortExpander_MCP23017/app/application.cpp @@ -1,19 +1,24 @@ #include #include +namespace +{ MCP23017 mcp; -volatile bool awakenByInterrupt = false; +volatile bool awakenByInterrupt; byte mcpPinA = 0; byte interruptPin = 15; -void interruptCallback() +void interruptDelegate() { awakenByInterrupt = true; - Serial.println("Interrupt Called"); - while(!(mcp.digitalRead(mcpPinA))) - ; + Serial.println(_F("Interrupt Called")); + while(!mcp.digitalRead(mcpPinA)) { + // + } } +} // namespace + void init() { Serial.begin(COM_SPEED_SERIAL); @@ -36,5 +41,5 @@ void init() mcp.pinMode(mcpPinA, INPUT); mcp.pullUp(mcpPinA, HIGH); mcp.setupInterruptPin(mcpPinA, FALLING); - attachInterrupt(interruptPin, InterruptDelegate(interruptCallback), FALLING); + attachInterrupt(interruptPin, InterruptDelegate(interruptDelegate), FALLING); } diff --git a/samples/PortExpander_MCP23S17/app/application.cpp b/samples/PortExpander_MCP23S17/app/application.cpp index 4095b02ea8..9126294024 100644 --- a/samples/PortExpander_MCP23S17/app/application.cpp +++ b/samples/PortExpander_MCP23S17/app/application.cpp @@ -1,21 +1,30 @@ #include -#include -#include #include +namespace +{ // // Instantiate an object called "inputchip" on an MCP23S17 device at address 1 = 0b00000001 and CS pin = GPIO16 MCP inputchip(1, 16); // Instantiate an object called "outputchip" on an MCP23S17 device at address 0 = 0b00000010 and CS pin = GPIO16 MCP outputchip(0, 16); -void loop(); +SimpleTimer procTimer; + +void loop() +{ + int value; // declare an integer to hold the value temporarily. + value = inputchip.digitalRead(); // read the input chip in word-mode, storing the result in "value" + outputchip.digitalWrite(value); // write the output chip in word-mode, using our variable "value" as the argument + // outputchip.digitalWrite(inputchip.digitalRead()); // this one line replaces the three above, and is more efficient +} -Timer procTimer; +} // namespace void init() { Serial.begin(SERIAL_BAUD_RATE); // 115200 by default Serial.systemDebugOutput(false); // Allow debug output to serial + Serial.println(_F("<-= Sming start =->")); // Set higher CPU freq & disable wifi sleep @@ -35,13 +44,5 @@ void init() inputchip.inputInvert(0x0000); // Use word-write mode to invert the inputs so that logic 0 is read as HIGH outputchip.pinMode(0x0000); // Use word-write mode to Set all of the pins on outputchip to be outputs - procTimer.initializeMs(200, loop).start(); -} - -void loop() -{ - int value; // declare an integer to hold the value temporarily. - value = inputchip.digitalRead(); // read the input chip in word-mode, storing the result in "value" - outputchip.digitalWrite(value); // write the output chip in word-mode, using our variable "value" as the argument - // outputchip.digitalWrite(inputchip.digitalRead()); // this one line replaces the three above, and is more efficient + procTimer.initializeMs<200>(loop).start(); } diff --git a/samples/Pressure_BMP180/app/application.cpp b/samples/Pressure_BMP180/app/application.cpp index db9d44a384..b097b74ec0 100644 --- a/samples/Pressure_BMP180/app/application.cpp +++ b/samples/Pressure_BMP180/app/application.cpp @@ -2,6 +2,7 @@ #include BMP180 barometer; + void init() { Serial.begin(SERIAL_BAUD_RATE); // 115200 by default diff --git a/samples/Radio_RCSwitch/app/application.cpp b/samples/Radio_RCSwitch/app/application.cpp index 7ce74fc87c..0a2e997680 100644 --- a/samples/Radio_RCSwitch/app/application.cpp +++ b/samples/Radio_RCSwitch/app/application.cpp @@ -3,10 +3,11 @@ #define LED_PIN 2 // GPIO2 -Timer sendTimer; -Timer receiveTimer; - -RCSwitch mySwitch = RCSwitch(); +namespace +{ +SimpleTimer sendTimer; +SimpleTimer receiveTimer; +RCSwitch mySwitch; void sendRF() { @@ -16,18 +17,22 @@ void sendRF() void receiveRF() { - if(mySwitch.available()) { - if(mySwitch.getReceivedValue() == 0) { - Serial.print(_F("Unknown encoding")); - } else { - Serial << _F("Received ") << mySwitch.getReceivedValue() << " / " << mySwitch.getReceivedBitlength() - << " bit, Protocol: " << mySwitch.getReceivedProtocol() << endl; - } - - mySwitch.resetAvailable(); + if(mySwitch.available() == 0) { + return; + } + + if(mySwitch.getReceivedValue() == 0) { + Serial.println(_F("Unknown encoding")); + } else { + Serial << _F("Received ") << mySwitch.getReceivedValue() << " / " << mySwitch.getReceivedBitlength() + << " bit, Protocol: " << mySwitch.getReceivedProtocol() << endl; } + + mySwitch.resetAvailable(); } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); // 115200 by default @@ -41,6 +46,6 @@ void init() // Optional set protocol (default is 1, will work for most outlets) // mySwitch.setProtocol(2); - sendTimer.initializeMs(1000, sendRF).start(); - receiveTimer.initializeMs(20, receiveRF).start(); + sendTimer.initializeMs<1000>(sendRF).start(); + receiveTimer.initializeMs<20>(receiveRF).start(); } diff --git a/samples/Radio_nRF24L01/app/application.cpp b/samples/Radio_nRF24L01/app/application.cpp index 167154e8eb..246e768bff 100644 --- a/samples/Radio_nRF24L01/app/application.cpp +++ b/samples/Radio_nRF24L01/app/application.cpp @@ -5,6 +5,8 @@ // Use this server with standard RF24 client example "pingpair" // https://github.com/maniacbug/RF24/tree/master/examples/pingpair +namespace +{ /* **** NRF24L01 pins connection: **** * VCC 3.3v @@ -27,7 +29,7 @@ RF24 radio(RF24_CE_PIN, RF24_CSN_PIN); // Radio pipe addresses for the 2 nodes to communicate. const uint64_t pipes[2] = {0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL}; -Timer procTimer; +SimpleTimer procTimer; void loopListen() { @@ -65,6 +67,8 @@ void loopListen() } } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); // 115200 by default @@ -107,6 +111,6 @@ void init() radio.printDetails(); Serial.println(_F("Initialization completed.")); - procTimer.initializeMs(10, loopListen).start(); + procTimer.initializeMs<10>(loopListen).start(); Serial.println(_F("Listening...")); } diff --git a/samples/Radio_si4432/README.rst b/samples/Radio_si4432/README.rst index 17c81592bc..b54a5926d7 100644 --- a/samples/Radio_si4432/README.rst +++ b/samples/Radio_si4432/README.rst @@ -4,5 +4,5 @@ SI443 Radio Example application for radio module Si4432 aka RF22 driver. Link: http://www.electrodragon.com/w/SI4432_433M-Wireless_Transceiver_Module_%281.5KM_Range,_Shield-Protected%29 -.. :image:: test_hardware.jpg +.. image:: test_hardware.jpg :height: 192px diff --git a/samples/Radio_si4432/app/application.cpp b/samples/Radio_si4432/app/application.cpp index 7a947f63eb..32cb28d277 100644 --- a/samples/Radio_si4432/app/application.cpp +++ b/samples/Radio_si4432/app/application.cpp @@ -18,27 +18,29 @@ Link: http://www.electrodragon.com/w/SI4432_433M-Wireless_Transceiver_Module_%28 #define PIN_RADIO_CK 15 /* Serial Clock */ #define PIN_RADIO_SS 13 /* Slave Select */ -Timer procTimer; -Si4432* radio = nullptr; -SPISoft* pRadioSPI = nullptr; +namespace +{ +SimpleTimer procTimer; +SPISoft radioSPI(PIN_RADIO_DO, PIN_RADIO_DI, PIN_RADIO_CK, PIN_RADIO_SS); +Si4432 radio(&radioSPI); #define PING_PERIOD_MS 2000 #define PING_WAIT_PONG_MS 100 -unsigned long lastPingTime; + +PeriodicFastMs pingTimer; void loopListen() { - const byte* ack = (const byte*)"OK"; //{ 0x01, 0x3, 0x11, 0x13 }; - const byte* ping = (const byte*)"PING"; + const char* ack = "OK"; //{ 0x01, 0x3, 0x11, 0x13 }; + const char* ping = "PING"; byte payLoad[64] = {0}; byte len = 0; //1. Ping from time to time, and wait for incoming response - if(millis() - lastPingTime > PING_PERIOD_MS) { - lastPingTime = millis(); - + if(pingTimer.expired()) { Serial.print(_F("Ping -> ")); - if(!radio->sendPacket(strlen((const char*)ping), ping, true, PING_WAIT_PONG_MS, &len, payLoad)) { + if(!radio.sendPacket(strlen(ping), reinterpret_cast(ping), true, PING_WAIT_PONG_MS, &len, + payLoad)) { Serial.println(" ERR!"); } else { Serial.println(_F(" SENT!")); @@ -49,62 +51,55 @@ void loopListen() } //2. Listen for any other incoming packet - bool pkg = radio->isPacketReceived(); + bool pkg = radio.isPacketReceived(); if(pkg) { - radio->getPacketReceived(&len, payLoad); + radio.getPacketReceived(&len, payLoad); Serial << _F("ASYNC RX (") << len << "): "; Serial.write(payLoad, len); Serial.println(); Serial.print(_F("Response -> ")); - if(!radio->sendPacket(strlen((const char*)ack), ack)) { + if(!radio.sendPacket(strlen(ack), reinterpret_cast(ack))) { Serial.println(_F("ERR!")); } else { Serial.println(_F("SENT!")); } - radio->startListening(); // restart the listening. + radio.startListening(); // restart the listening. } } +} // namespace + void init() { +#ifdef ARCH_HOST + setDigitalHooks(nullptr); +#endif + Serial.begin(SERIAL_BAUD_RATE); // 115200 by default Serial.systemDebugOutput(true); //Allow debug output to serial - Serial.println(_F("\nRadio si4432 example - !!! see code for HW setup !!! \n")); - - pRadioSPI = new SPISoft(PIN_RADIO_DO, PIN_RADIO_DI, PIN_RADIO_CK, PIN_RADIO_SS); - - if(pRadioSPI != nullptr) { - radio = new Si4432(pRadioSPI); - } - - if(radio == nullptr) { - Serial.println(_F("Error: Not enough heap.")); - return; - } - - delay(100); + Serial.println(_F("\r\nRadio si4432 example - !!! see code for HW setup !!!\r\n")); - //initialise radio with default settings - radio->init(); + // initialise radio with default settings + radio.init(); - //explicitly set baudrate and channel - radio->setBaudRateFast(eBaud_38k4); - radio->setChannel(0); + // explicitly set baudrate and channel + radio.setBaudRateFast(eBaud_38k4); + radio.setChannel(0); - //dump the register configuration to console - radio->readAll(); + // dump the register configuration to console + radio.readAll(); - //start listening for incoming packets + // start listening for incoming packets Serial.println("Listening..."); - radio->startListening(); + radio.startListening(); - lastPingTime = millis(); + pingTimer.reset(PING_PERIOD_MS); - //start listen loop - procTimer.initializeMs(10, loopListen).start(); + // start listen loop + procTimer.initializeMs<10>(loopListen).start(); } diff --git a/samples/SDCard/app/application.cpp b/samples/SDCard/app/application.cpp index 7a777efb60..a7979af387 100644 --- a/samples/SDCard/app/application.cpp +++ b/samples/SDCard/app/application.cpp @@ -26,6 +26,8 @@ Descr: SDCard/FAT file usage and write benchmark. /* Sets the max frequency of SPI (init is done at a lower speed than the main communication) */ #define SPI_FREQ_LIMIT 2000000 +namespace +{ void writeToFile(const String& filename, uint32_t totalBytes, uint32_t bytesPerRound) { char* buf = new char[totalBytes]; @@ -108,7 +110,7 @@ void stat_file(char* fname) break; default: - Serial.printf(_F("Error(%d)\r\n"), fr); + Serial << _F("Error ") << fr << endl; } } @@ -162,11 +164,11 @@ void readWriteTest() f_printf(&file, _F(" has %d letters\r\n"), actual); if(actual != 5) { - Serial.printf(_F("Only written %u bytes\r\n"), actual); + Serial << _F("Only written ") << actual << _F(" bytes") << endl; } f_close(&file); } else { - Serial.printf(_F("fopen FAIL: %u\r\n"), (unsigned int)fRes); + Serial << _F("fopen FAIL: ") << fRes << endl; } } @@ -185,11 +187,11 @@ void readTest() f_read(&file, buffer, sizeof(buffer), &actual); buffer[actual] = 0; - Serial.printf(_F("Read: %s\r\n"), buffer); + Serial << _F("Read: ") << buffer << endl; f_close(&file); } else { - Serial.printf(_F("fopen FAIL: %u\r\n"), fRes); + Serial << _F("fopen FAIL: ") << fRes << endl; } } @@ -200,16 +202,24 @@ bool speedTest(unsigned num) uint32_t bytesPerRound; }; - static Test tests[] PROGMEM{ - {1024, 1}, {1024, 64}, {1024, 128}, {1024, 512}, {1024, 1024}, - {4096, 1024}, {8192, 512}, {8192, 1024}, {8192, 8192}, + static const Test tests[] PROGMEM{ + {1024, 1}, // + {1024, 64}, // + {1024, 128}, // + {1024, 512}, // + {1024, 1024}, // + {4096, 1024}, // + {8192, 512}, // + {8192, 1024}, // + {8192, 8192}, // + }; if(num >= ARRAY_SIZE(tests)) { return false; } - Serial.printf(_F("4.%u: Write speed benchmark\r\n"), num + 1); + Serial << "4." << num + 1 << _F(": Write speed benchmark") << endl; auto& test = tests[num]; String filename; @@ -263,6 +273,8 @@ void runTest(uint32_t state = 0) System.queueCallback(runTest, state + 1); } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); // 115200 by default diff --git a/samples/ScreenLCD_5110/app/application.cpp b/samples/ScreenLCD_5110/app/application.cpp index 2fffa50e1d..945dea1448 100644 --- a/samples/ScreenLCD_5110/app/application.cpp +++ b/samples/ScreenLCD_5110/app/application.cpp @@ -1,32 +1,48 @@ #include #include +namespace +{ // GPIO13/D7 - Serial clock out (SCLK) // GPIO12/D6 - Serial data out (DIN) // GPIO14/D5 - Data/Command select (D/C) // GPIO5/D1 - LCD chip select (CS) // GPIO4/D2 - LCD reset (RST) -Adafruit_PCD8544 display = Adafruit_PCD8544(13, 12, 14, 5, 4); +Adafruit_PCD8544 display(13, 12, 14, 5, 4); +SimpleTimer timer; void displayTest() { display.begin(); display.setContrast(10); display.display(); // show splashscreen - delay(2000); - display.clearDisplay(); // no changes will be visible until display() is called - display.setRotation(4); // rotate 90 degrees counter clockwise, can also use values of 2 and 3 to go further. - display.setTextSize(1); - display.setTextColor(BLACK); - display.setCursor(0, 0); - display.println("Sming"); - display.setTextSize(2); - display.println("Example"); - display.display(); + debug_d("Show splash..."); + + timer.initializeMs<2000>([]() { + debug_d("Update screen."); + display.clearDisplay(); // no changes will be visible until display() is called + display.setRotation(4); // rotate 90 degrees counter clockwise, can also use values of 2 and 3 to go further. + display.setTextSize(1); + display.setTextColor(BLACK); + display.setCursor(0, 0); + display.println("Sming"); + display.setTextSize(2); + display.println("Example"); + display.display(); + }); + timer.startOnce(); } +} // namespace + void init() { +#ifdef ARCH_HOST + setDigitalHooks(nullptr); +#endif + Serial.begin(SERIAL_BAUD_RATE); + Serial.systemDebugOutput(true); + displayTest(); } diff --git a/samples/ScreenOLED_SSD1306/app/application.cpp b/samples/ScreenOLED_SSD1306/app/application.cpp index d0b8d3b5f6..df67dadd1b 100644 --- a/samples/ScreenOLED_SSD1306/app/application.cpp +++ b/samples/ScreenOLED_SSD1306/app/application.cpp @@ -18,6 +18,8 @@ #define SH1106_128_64 // larger one */ +namespace +{ // For spi oled module // Adafruit_SSD1306 display(0, 16, 2); @@ -25,7 +27,7 @@ // Default I2C pins 0 (SCL) and 2 (SDA). Pin 4 - optional reset Adafruit_SSD1306 display(-1); // reset Pin required but later ignored if set to False -Timer DemoTimer; +SimpleTimer demoTimer; void Demo2() { @@ -45,7 +47,6 @@ void Demo2() display.setTextSize(3); display.print("IoT"); display.display(); - DemoTimer.stop(); // Finish demo } void Demo1() @@ -56,10 +57,13 @@ void Demo1() // draw a circle, 10 pixel radius display.fillCircle(display.width() / 2, display.height() / 2, 10, WHITE); display.display(); - DemoTimer.stop(); - DemoTimer.initializeMs(2000, Demo2).start(); + + demoTimer.setCallback(Demo2); + demoTimer.startOnce(); } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); // 115200 by default @@ -70,5 +74,6 @@ void init() // bool:reset set to TRUE or FALSE depending on your display display.begin(SSD1306_SWITCHCAPVCC, 0x3c, false); display.display(); - DemoTimer.initializeMs(2000, Demo1).start(); + + demoTimer.initializeMs<2000>(Demo1).startOnce(); } diff --git a/samples/ScreenTFT_ILI9163C/app/application.cpp b/samples/ScreenTFT_ILI9163C/app/application.cpp index 8994109c9c..3d1611a989 100644 --- a/samples/ScreenTFT_ILI9163C/app/application.cpp +++ b/samples/ScreenTFT_ILI9163C/app/application.cpp @@ -1,6 +1,8 @@ #include #include +namespace +{ /* * LED (BACKLIGHT) 3.3v * SCK (SCLK) GPIO14 @@ -12,33 +14,41 @@ * VCC (VCC) 3.3v */ TFT_ILI9163C tft(2, 0); +SimpleTimer timer; -void init() +void demo() { - Serial.begin(SERIAL_BAUD_RATE); // 115200 by default - Serial.systemDebugOutput(true); // Allow debug output to serial - Serial.println(_F("Display start")); tft.begin(); tft.setRotation(2); // try yourself tft.fillScreen(); tft.fillRect(10, 20, 100, 120, YELLOW); - delay(1000); - // text display tests - tft.fillScreen(); - tft.setTextSize(1); - tft.setTextColor(GREEN); - tft.setCursor(0, 0); - tft.println(_F("Sming Framework")); - tft.setTextColor(BLACK, WHITE); // 'inverted' text - tft.setCursor(104, 7); - tft.println("v1.0"); - tft.setTextColor(WHITE); - tft.println(_F("Let's do smart things")); - tft.setTextSize(3); - tft.setTextColor(BLUE); - tft.print("IoT"); + timer.initializeMs<1000>([]() { + // text display tests + tft.fillScreen(); + tft.setTextSize(1); + tft.setTextColor(GREEN); + tft.setCursor(0, 0); + tft.println(_F("Sming Framework")); + tft.setTextColor(BLACK, WHITE); // 'inverted' text + tft.setCursor(104, 7); + tft.println("v1.0"); + tft.setTextColor(WHITE); + tft.println(_F("Let's do smart things")); + tft.setTextSize(3); + tft.setTextColor(BLUE); + tft.print("IoT"); + }); + timer.startOnce(); +} + +} // namespace + +void init() +{ + Serial.begin(SERIAL_BAUD_RATE); // 115200 by default + Serial.systemDebugOutput(true); // Allow debug output to serial - delay(2000); + demo(); } diff --git a/samples/ScreenTFT_ILI9340-ILI9341/README.rst b/samples/ScreenTFT_ILI9340-ILI9341/README.rst index 48e3cbb0a2..16bccbc3b6 100644 --- a/samples/ScreenTFT_ILI9340-ILI9341/README.rst +++ b/samples/ScreenTFT_ILI9340-ILI9341/README.rst @@ -2,4 +2,4 @@ ILI9340 and ILI9341 TFT Screens =============================== Demonstration of how to interface with displays such as the -`Adafruit 2.8” Touch Shield V2 (SPI) `__. +`Adafruit 2.8" Touch Shield V2 (SPI) `__. diff --git a/samples/ScreenTFT_ILI9340-ILI9341/app/application.cpp b/samples/ScreenTFT_ILI9340-ILI9341/app/application.cpp index 2b0ec9b1d3..5aba476570 100644 --- a/samples/ScreenTFT_ILI9340-ILI9341/app/application.cpp +++ b/samples/ScreenTFT_ILI9340-ILI9341/app/application.cpp @@ -8,36 +8,41 @@ #define WIFI_PWD "PleaseEnterPass" #endif +namespace +{ // See library for pinout Adafruit_ILI9341 tft; -Timer guiTimer; - -int r = 0; - -int ara = 4, yerara = 15; -int u1 = 100; -int u2 = 320 - (u1 + ara); -int s1 = 0; -int s2 = (u1 + ara); -int p1 = 50; - -int g = 28; -int y = 90; -int satir = 6; - -String lists[] = {"a", "b", "c", "d", "e", "f"}; +SimpleTimer guiTimer; void basicBMP() { + debug_d("%s", __FUNCTION__); + tft.fillScreen(ILI9341_BLACK); // Clear display tft.setRotation(tft.getRotation() + 1); // Inc rotation 90 degrees - for(uint8_t i = 0; i < 4; i++) // Draw 4 parrots - bmpDraw(tft, "sming.bmp", tft.width() / 4 * i, tft.height() / 4 * i); + for(uint8_t i = 0; i < 4; i++) { // Draw 4 parrots + bmpDraw(tft, "sming.bmp", i * tft.width() / 4, i * tft.height() / 4); + } } void basicGui() { + debug_d("%s", __FUNCTION__); + + static int r; + + const int ara = 4; + const int yerara = 15; + const int u1 = 100; + const int u2 = 320 - (u1 + ara); + const int s1 = 0; + const int s2 = (u1 + ara); + + const int g = 28; + + int p1 = 50; + tft.setTextSize(1); tft.setRotation(1); @@ -48,12 +53,13 @@ void basicGui() tft.println("Sming"); tft.setTextSize(2); tft.fillRect((u1 * 2) + ara, 0, 318 - (u1 * 2), 48, ILI9341_RED); - for(int a = 0; a < satir; a++) { + for(auto a : {'a', 'b', 'c', 'd', 'e', 'f'}) { + debug_d("%c: %u", a, r); tft.setTextColor(ILI9341_GREEN); tft.fillRect(s1, p1, u1, g, ILI9341_DARKCYAN); tft.setCursor(s1 + yerara, p1 + 6); tft.setTextColor(ILI9341_WHITE); - tft.println(lists[a]); + tft.println(a); tft.fillRect(s2, p1, u2, g, ILI9341_DARKCYAN); tft.setCursor(s2 + yerara, p1 + 6); tft.println(r); @@ -61,24 +67,16 @@ void basicGui() } p1 = 50; r++; - guiTimer.initializeMs<1000>(basicBMP).start(false); -} -void init() -{ - Serial.begin(SERIAL_BAUD_RATE); // 115200 by default - Serial.systemDebugOutput(true); // Allow debug output to serial - -#ifndef DISABLE_WIFI - //WifiStation.config(WIFI_SSID, WIFI_PWD); - WifiStation.enable(false); - WifiAccessPoint.enable(false); -#endif + if(r >= 5) { + guiTimer.setCallback(basicBMP); + } - spiffs_mount(); - Serial.println(_F("FileSystem mounted.")); + guiTimer.startOnce(); +} - // delay(2000); +void demo() +{ Serial.println(_F("Display start")); // text display tests @@ -99,8 +97,33 @@ void init() tft.println(_F("ili9340-40C-41 ")); tft.setCursor(60, 125); tft.println(_F("M.Bozkurt")); - delay(2000); - tft.fillScreen(0); - guiTimer.initializeMs<1000>(basicGui).start(false); - //runTest(); + + guiTimer.initializeMs<2000>([]() { + tft.fillScreen(0); + guiTimer.initializeMs<1000>(basicGui).startOnce(); + }); + guiTimer.startOnce(); +} + +} // namespace + +void init() +{ +#ifdef ARCH_HOST + setDigitalHooks(nullptr); +#endif + + Serial.begin(SERIAL_BAUD_RATE); // 115200 by default + Serial.systemDebugOutput(true); // Allow debug output to serial + +#ifndef DISABLE_WIFI + //WifiStation.config(WIFI_SSID, WIFI_PWD); + WifiStation.enable(false); + WifiAccessPoint.enable(false); +#endif + + spiffs_mount(); + Serial.println(_F("FileSystem mounted.")); + + demo(); } diff --git a/samples/ScreenTFT_ST7735/app/application.cpp b/samples/ScreenTFT_ST7735/app/application.cpp index b4a2ed3701..b4a3b7bbe7 100644 --- a/samples/ScreenTFT_ST7735/app/application.cpp +++ b/samples/ScreenTFT_ST7735/app/application.cpp @@ -18,14 +18,12 @@ #define TFT_DC 0 #define TFT_CS 2 -//Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST); -Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); - -Timer DemoScreenTimer; -float p = 3.1415926; -uint32_t startTime; +namespace +{ +//Adafruit_ST7735 tft(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST); +Adafruit_ST7735 tft(TFT_CS, TFT_DC, TFT_RST); -void testdrawtext(const char text[], uint16_t color) +void testdrawtext(const String& text, uint16_t color) { tft.setCursor(0, 0); tft.setTextColor(color); @@ -61,7 +59,7 @@ void tftPrintTest2() tft.println("Hello Sming!"); tft.setTextSize(1); tft.setTextColor(ST7735_GREEN); - tft.print(p, 6); + tft.print(PI, 6); tft.println(" Want pi?"); tft.println(" "); tft.print(8675309, HEX); // print 8,675,309 out in HEX! @@ -226,122 +224,155 @@ void mediabuttons() void screen13() { - startTime = millis(); - debugf("screen13: bmpDraw rotaton %d ms", millis() - startTime); tft.fillScreen(ST7735_BLACK); // Clear display tft.setRotation(tft.getRotation() + 1); // Inc rotation 90 degrees - for(uint8_t i = 0; i < 4; i++) // Draw 4 parrots + for(uint8_t i = 0; i < 4; i++) { // Draw 4 parrots bmpDraw(tft, "sming.bmp", tft.width() / 4 * i, tft.height() / 4 * i); + } } void screen12() { - startTime = millis(); bmpDraw(tft, "sming.bmp", 0, 0); - debugf("screen12: bmpDraw %d ms", millis() - startTime); - // DemoScreenTimer.initializeMs(2000, screen13).start(false); } void screen11() { - startTime = millis(); mediabuttons(); - debugf("screen11: mediabuttons %d ms", millis() - startTime); - DemoScreenTimer.initializeMs(1000, screen12).start(false); } void screen10() { - startTime = millis(); testtriangles(); - debugf("screen10: testtriangles %d ms", millis() - startTime); - DemoScreenTimer.initializeMs(1000, screen11).start(false); } void screen9() { - startTime = millis(); testroundrects(); - debugf("screen9: testroundrects %d ms", millis() - startTime); - DemoScreenTimer.initializeMs(1000, screen10).start(false); } void screen8() { - startTime = millis(); tft.fillScreen(ST7735_BLACK); testfillcircles(10, ST7735_BLUE); testdrawcircles(10, ST7735_WHITE); - debugf("screen8: testfillcircles %d ms", millis() - startTime); - DemoScreenTimer.initializeMs(1000, screen9).start(false); } void screen7() { - startTime = millis(); testfillrects(ST7735_YELLOW, ST7735_MAGENTA); - debugf("screen7: testfillrects %d ms", millis() - startTime); - DemoScreenTimer.initializeMs(1000, screen8).start(false); } void screen6() { - startTime = millis(); testdrawrects(ST7735_GREEN); - debugf("screen6: testdrawrects %d ms", millis() - startTime); - DemoScreenTimer.initializeMs(1000, screen7).start(false); } void screen5() { - startTime = millis(); // optimized lines testfastlines(ST7735_RED, ST7735_BLUE); - debugf("screen5: testfastlines %d ms", millis() - startTime); - DemoScreenTimer.initializeMs(1000, screen6).start(false); } void screen4() { - startTime = millis(); // line draw test testlines(ST7735_YELLOW); - debugf("screen4: testlines %d ms", millis() - startTime); - DemoScreenTimer.initializeMs(1000, screen5).start(false); } void screen3() { - startTime = millis(); tftPrintTest2(); - debugf("screen3: tftPrintTest2 %d ms", millis() - startTime); - DemoScreenTimer.initializeMs(1000, screen4).start(false); } void screen2() { - startTime = millis(); tftPrintTest1(); - debugf("screen2: tftPrintTest1 %d ms", millis() - startTime); - DemoScreenTimer.initializeMs(1000, screen3).start(false); } void screen1() { - startTime = millis(); // large block of text tft.fillScreen(ST7735_BLACK); - testdrawtext("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh " - "tincidunt feugiat. Maecenas enim massa, fringilla sed malesuada et, malesuada sit amet turpis. Sed " - "porttitor neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet ultrices massa eu " - "hendrerit. Ut sed nisi lorem. In vestibulum purus a tortor imperdiet posuere. ", - ST7735_WHITE); - debugf("screen1: testdrawtext %d ms", millis() - startTime); - DemoScreenTimer.initializeMs(1000, screen2).start(false); + DEFINE_FSTR_LOCAL( + largeTextBlock, + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh " + "tincidunt feugiat. Maecenas enim massa, fringilla sed malesuada et, malesuada sit amet turpis. Sed " + "porttitor neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet ultrices massa eu " + "hendrerit. Ut sed nisi lorem. In vestibulum purus a tortor imperdiet posuere. ") + testdrawtext(largeTextBlock, ST7735_WHITE); } +void initialise() +{ + // Use this initializer if you're using a 1.8" TFT + // tft.initR(INITR_BLACKTAB); // initialize a ST7735S chip, black tab + + // Use this initializer (uncomment) if you're using a 1.44" TFT + tft.initR(INITR_144GREENTAB); // initialize a ST7735S chip, black tab + + tft.fillScreen(ST7735_BLACK); +} + +#define SCREEN_FUNCTION_MAP(XX) \ + XX(initialise, "Initialise") \ + XX(screen1, "testdrawtext") \ + XX(screen2, "tftPrintTest1") \ + XX(screen3, "tftPrintTest2") \ + XX(screen4, "testlines") \ + XX(screen5, "testfastlines") \ + XX(screen6, "testdrawrects") \ + XX(screen7, "testfillrects") \ + XX(screen8, "testfillcircles") \ + XX(screen9, "testroundrects") \ + XX(screen10, "testtriangles") \ + XX(screen11, "mediabuttons") \ + XX(screen12, "bmpDraw") \ + XX(screen13, "bmpDraw rotation") + +#define XX(function, title) DEFINE_FSTR(function##_title, #function ": " title) +SCREEN_FUNCTION_MAP(XX) +#undef XX + +struct DemoScreen { + InterruptCallback function; + const FlashString& title; +}; + +const DemoScreen screenList[] PROGMEM{ +#define XX(name, title) {name, name##_title}, + SCREEN_FUNCTION_MAP(XX) +#undef XX +}; + +SimpleTimer demoScreenTimer; +auto screen = std::begin(screenList); + +void nextScreen() +{ + OneShotFastMs elapseTimer; + screen->function(); + auto elapsed = elapseTimer.elapsedTime(); + + Serial << screen->title << " in " << elapsed << "ms" << endl; + + ++screen; + if(screen != std::end(screenList)) { + demoScreenTimer.startOnce(); + return; + } + + Serial.println(_F("All screens displayed")); +} + +} // namespace + void init() { +#ifdef ARCH_HOST + setDigitalHooks(nullptr); +#endif + spiffs_mount(); // Mount file system, in order to work with files Serial.begin(SERIAL_BAUD_RATE); // 115200 by default @@ -353,19 +384,7 @@ void init() WifiAccessPoint.enable(false); #endif - debugf("Display start"); - startTime = millis(); - - // Use this initializer if you're using a 1.8" TFT - // tft.initR(INITR_BLACKTAB); // initialize a ST7735S chip, black tab - - // Use this initializer (uncomment) if you're using a 1.44" TFT - tft.initR(INITR_144GREENTAB); // initialize a ST7735S chip, black tab - - tft.fillScreen(ST7735_BLACK); - startTime = millis() - startTime; - - debugf("Initialized in %d ms\n", startTime); - - DemoScreenTimer.initializeMs(500, screen1).start(false); + Serial.println(_F("Initialise display")); + demoScreenTimer.initializeMs<500>(nextScreen); + nextScreen(); } diff --git a/samples/ScreenTFT_ST7735/component.mk b/samples/ScreenTFT_ST7735/component.mk index 17c7646fff..41fb0dc894 100644 --- a/samples/ScreenTFT_ST7735/component.mk +++ b/samples/ScreenTFT_ST7735/component.mk @@ -1,4 +1,3 @@ -COMPONENT_SOC := esp* HWCONFIG := spiffs-2m ARDUINO_LIBRARIES := Adafruit_ST7735 DISABLE_NETWORK := 1 diff --git a/samples/SmtpClient/README.rst b/samples/SmtpClient/README.rst index c52261ee73..09020d6659 100644 --- a/samples/SmtpClient/README.rst +++ b/samples/SmtpClient/README.rst @@ -13,16 +13,17 @@ When an IOT device detects a malfunction, it is good to be able to notify the user. We can do that either by sending them an email or via a service like MQTT. -This sample shows how to send an email via SMTP directly from the -ESP8266. +This sample shows how to send an email via SMTP directly from the embedded device. smtp2go conveniently provides a free account. Create an account here: https://www.smtp2go.com/setupguide/arduino/ . -It needs some configuration: \* the name of the SMTP server, eg -“mail.smtp2go.com” \* a username and password \* the name and email of -the person from whom the email will be sent \* the name and email of the -person to send the email to +It needs some configuration: + +- the name of the SMTP server, eg "mail.smtp2go.com" +- a username and password +- the name and email of the person from whom the email will be sent +- the name and email of the person to send the email to Edit the sample to replace these values and the SSID etc. diff --git a/samples/SmtpClient/app/application.cpp b/samples/SmtpClient/app/application.cpp index 9890635d3a..411150add1 100644 --- a/samples/SmtpClient/app/application.cpp +++ b/samples/SmtpClient/app/application.cpp @@ -7,12 +7,14 @@ #define WIFI_PWD "PleaseEnterPass" #endif +namespace +{ // Make sure to change those to your desired values -#define MAIL_FROM "admin@sming.com" -#define MAIL_TO "slav@attachix.com" -#define SMTP_USERNAME nullptr -#define SMTP_PASSWORD nullptr -#define SMTP_HOST "attachix.com" +DEFINE_FSTR(MAIL_FROM, "admin@sming.com") +DEFINE_FSTR(MAIL_TO, "slav@attachix.com") +DEFINE_FSTR(SMTP_USERNAME, "") +DEFINE_FSTR(SMTP_PASSWORD, "") +DEFINE_FSTR(SMTP_HOST, "attachix.com") #define SMTP_PORT 0 // Use default port #define SMTP_USE_SSL false @@ -22,7 +24,7 @@ int onServerError(SmtpClient& client, int code, char* status) { debugf("Status: %s", status); - return 0; // return non-zero value to abort the connection + return -1; // return non-zero value to abort the connection } int onMailSent(SmtpClient& client, int code, char* status) @@ -31,11 +33,11 @@ int onMailSent(SmtpClient& client, int code, char* status) MailMessage* mail = client.getCurrentMessage(); // TODO: The status line contains the unique ID that was given to this email - debugf("Mail sent to '%s'. Status: %s", mail->to.c_str(), status); + Serial << _F("Mail sent to '") << mail->to << _F("'. Status: ") << status << endl; // And if there are no more pending emails then you can disconnect from the server if(client.countPending() == 0) { - debugf("No more mails to send. Quitting..."); + Serial.println(_F("No more mails to send. Quitting...")); client.quit(); } @@ -50,7 +52,7 @@ void onConnected(IpAddress ip, IpAddress mask, IpAddress gateway) Url dsn(SMTP_USE_SSL ? URI_SCHEME_SMTP_SECURE : URI_SCHEME_SMTP, SMTP_USERNAME, SMTP_PASSWORD, SMTP_HOST, SMTP_PORT); - debugf("Connecting to SMTP server using: %s", String(dsn).c_str()); + Serial << _F("Connecting to SMTP server using: ") << dsn << endl; client.connect(dsn); @@ -58,8 +60,9 @@ void onConnected(IpAddress ip, IpAddress mask, IpAddress gateway) mail->from = MAIL_FROM; mail->to = MAIL_TO; mail->subject = "Greetings from Sming"; - String body = F("Hello.\r\n.\r\n" - "This is test email from Sming " + String body = F("Hello.\r\n." + "\r\n" + "This is test email from Sming \r\n" "It contains attachment, Ümlauts, кирилица + etc"); // Note: Body can be quite large so use move semantics to avoid additional heap allocation mail->setBody(std::move(body)); @@ -71,11 +74,13 @@ void onConnected(IpAddress ip, IpAddress mask, IpAddress gateway) client.send(mail); } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); Serial.systemDebugOutput(true); - Serial.println("Sming: SmtpClient example!"); + Serial.println(_F("Sming: SmtpClient example!")); spiffs_mount(); diff --git a/samples/SmtpClient/component.mk b/samples/SmtpClient/component.mk index 7f43d35855..4113e94c06 100644 --- a/samples/SmtpClient/component.mk +++ b/samples/SmtpClient/component.mk @@ -1,2 +1,2 @@ HWCONFIG := spiffs-2m -ENABLE_SSL ?= 1 +ENABLE_SSL ?= 1 diff --git a/samples/SmtpClient/include/ssl/cert.h b/samples/SmtpClient/include/ssl/cert.h deleted file mode 100644 index 0f5317732d..0000000000 --- a/samples/SmtpClient/include/ssl/cert.h +++ /dev/null @@ -1,27 +0,0 @@ -unsigned char default_certificate[] = { - 0x30, 0x82, 0x01, 0xd7, 0x30, 0x82, 0x01, 0x40, 0x02, 0x09, 0x00, 0xa6, 0xf3, 0xaa, 0xf6, 0xaf, 0xcd, 0x0b, 0x3a, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x34, 0x31, 0x32, - 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x29, 0x61, 0x78, 0x54, 0x4c, 0x53, 0x20, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x20, 0x44, 0x6f, 0x64, 0x67, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x38, 0x30, - 0x34, 0x32, 0x34, 0x30, 0x39, 0x34, 0x38, 0x32, 0x39, 0x5a, 0x17, 0x0d, 0x33, 0x32, 0x30, 0x31, 0x30, 0x31, 0x30, - 0x39, 0x34, 0x38, 0x32, 0x39, 0x5a, 0x30, 0x2c, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0d, - 0x61, 0x78, 0x54, 0x4c, 0x53, 0x20, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x0c, 0x09, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x30, 0x81, 0x9f, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, - 0x89, 0x02, 0x81, 0x81, 0x00, 0xa0, 0xbd, 0x8d, 0xf6, 0x21, 0x4b, 0x76, 0x92, 0xa8, 0x13, 0xe8, 0x74, 0x90, 0x79, - 0x05, 0x04, 0xfb, 0xf1, 0x4f, 0x4b, 0x02, 0xc2, 0xd9, 0x6f, 0xc1, 0x82, 0xa7, 0xf2, 0x8b, 0x03, 0x15, 0xe3, 0x56, - 0xce, 0x37, 0x4a, 0x2d, 0xcb, 0x80, 0xd1, 0xc0, 0xa0, 0x84, 0x3d, 0x1b, 0xd9, 0xda, 0x5c, 0xbc, 0x7a, 0x2c, 0x35, - 0xda, 0x9e, 0xe7, 0x56, 0x4b, 0xc5, 0x63, 0xa0, 0x6f, 0xa7, 0x39, 0x0c, 0x72, 0x56, 0x43, 0x34, 0xb0, 0x9a, 0x59, - 0xfb, 0x86, 0xa4, 0x3a, 0xdd, 0xfb, 0xf6, 0xfb, 0x3a, 0x26, 0x69, 0xe8, 0x45, 0x03, 0x3b, 0xde, 0xa9, 0x64, 0x97, - 0x8a, 0x95, 0xf1, 0xfc, 0xd5, 0x77, 0x2d, 0x49, 0x4c, 0x72, 0xf5, 0xcf, 0xcc, 0xb8, 0x54, 0x87, 0x40, 0x4a, 0x6f, - 0x0f, 0x40, 0xd1, 0xba, 0xf1, 0x8c, 0x5b, 0xf9, 0x5d, 0x94, 0xa6, 0xd4, 0xe9, 0x98, 0x38, 0x91, 0x77, 0x91, 0x9b, - 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, - 0x00, 0x03, 0x81, 0x81, 0x00, 0x19, 0xe5, 0x9f, 0x6f, 0x26, 0x0a, 0x4b, 0xb4, 0xc2, 0x70, 0x5b, 0x2a, 0x31, 0xe6, - 0x0f, 0x37, 0x30, 0x1c, 0x9b, 0xaf, 0x0a, 0xe6, 0x12, 0xf8, 0xde, 0x37, 0x2b, 0xd3, 0xb0, 0x56, 0x2e, 0xeb, 0x95, - 0xdb, 0xd3, 0x2f, 0x70, 0xd9, 0xa5, 0x4e, 0x01, 0xd4, 0x2a, 0xb1, 0xa1, 0x79, 0x71, 0xb5, 0xe8, 0xf1, 0x0d, 0xb0, - 0x95, 0x98, 0xb5, 0xc8, 0x7d, 0x1d, 0x10, 0x64, 0x54, 0x16, 0x9f, 0x1e, 0x92, 0xc6, 0x26, 0xe6, 0xc5, 0xa7, 0xb0, - 0x1d, 0x3c, 0xd5, 0x92, 0xbf, 0xf3, 0xcf, 0xfe, 0x67, 0x03, 0x9d, 0x57, 0x76, 0x9a, 0xa2, 0x4e, 0x55, 0xad, 0xc2, - 0xcb, 0xbe, 0x7e, 0x83, 0xb1, 0xd8, 0x02, 0x59, 0x49, 0x7b, 0x48, 0x70, 0xec, 0xe1, 0x17, 0x76, 0x8e, 0x00, 0x3e, - 0x28, 0xd6, 0x79, 0x84, 0x65, 0x7e, 0x77, 0x8b, 0x0b, 0x3a, 0x19, 0xbb, 0x25, 0xec, 0x0a, 0xdd, 0x9a, 0xfe, 0x96}; -unsigned int default_certificate_len = 475; diff --git a/samples/SmtpClient/include/ssl/private_key.h b/samples/SmtpClient/include/ssl/private_key.h deleted file mode 100644 index e4a0f9130a..0000000000 --- a/samples/SmtpClient/include/ssl/private_key.h +++ /dev/null @@ -1,34 +0,0 @@ -unsigned char default_private_key[] = { - 0x30, 0x82, 0x02, 0x5c, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xa0, 0xbd, 0x8d, 0xf6, 0x21, 0x4b, 0x76, 0x92, - 0xa8, 0x13, 0xe8, 0x74, 0x90, 0x79, 0x05, 0x04, 0xfb, 0xf1, 0x4f, 0x4b, 0x02, 0xc2, 0xd9, 0x6f, 0xc1, 0x82, 0xa7, - 0xf2, 0x8b, 0x03, 0x15, 0xe3, 0x56, 0xce, 0x37, 0x4a, 0x2d, 0xcb, 0x80, 0xd1, 0xc0, 0xa0, 0x84, 0x3d, 0x1b, 0xd9, - 0xda, 0x5c, 0xbc, 0x7a, 0x2c, 0x35, 0xda, 0x9e, 0xe7, 0x56, 0x4b, 0xc5, 0x63, 0xa0, 0x6f, 0xa7, 0x39, 0x0c, 0x72, - 0x56, 0x43, 0x34, 0xb0, 0x9a, 0x59, 0xfb, 0x86, 0xa4, 0x3a, 0xdd, 0xfb, 0xf6, 0xfb, 0x3a, 0x26, 0x69, 0xe8, 0x45, - 0x03, 0x3b, 0xde, 0xa9, 0x64, 0x97, 0x8a, 0x95, 0xf1, 0xfc, 0xd5, 0x77, 0x2d, 0x49, 0x4c, 0x72, 0xf5, 0xcf, 0xcc, - 0xb8, 0x54, 0x87, 0x40, 0x4a, 0x6f, 0x0f, 0x40, 0xd1, 0xba, 0xf1, 0x8c, 0x5b, 0xf9, 0x5d, 0x94, 0xa6, 0xd4, 0xe9, - 0x98, 0x38, 0x91, 0x77, 0x91, 0x9b, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x81, 0x80, 0x0d, 0x1f, 0xcd, 0x02, 0x86, - 0xaf, 0x69, 0xac, 0x09, 0xcb, 0x2e, 0x54, 0xae, 0x23, 0x23, 0x74, 0xc7, 0xb9, 0x69, 0x36, 0xff, 0xaf, 0xb7, 0x1f, - 0x37, 0xd6, 0x9a, 0x2d, 0xe4, 0x89, 0xc8, 0xf4, 0xb9, 0xf6, 0xb6, 0x6e, 0xf9, 0x14, 0x3f, 0x9d, 0x60, 0xb3, 0xfa, - 0x78, 0x1e, 0xd9, 0x07, 0xca, 0x40, 0x9d, 0x5d, 0x14, 0xbc, 0x97, 0xf2, 0xdd, 0x89, 0xec, 0x40, 0xf9, 0x2d, 0x84, - 0xa2, 0xd4, 0xaf, 0x29, 0x42, 0x13, 0x74, 0xa7, 0x8e, 0xe5, 0xe8, 0xec, 0xbc, 0xde, 0x64, 0xd9, 0xf5, 0x84, 0x9e, - 0x1d, 0x19, 0x4c, 0xf6, 0xdc, 0xb3, 0x7d, 0x66, 0x49, 0xef, 0x45, 0x57, 0x49, 0xed, 0x4d, 0x4a, 0xe3, 0xec, 0xea, - 0x5b, 0xe4, 0xdf, 0x0d, 0x72, 0x3a, 0xd9, 0xbd, 0x9e, 0x37, 0x28, 0x9f, 0x5f, 0xa4, 0x74, 0xdd, 0xdb, 0xeb, 0x65, - 0xfa, 0x42, 0x36, 0x21, 0xd3, 0x3f, 0x47, 0x68, 0xc9, 0x02, 0x41, 0x00, 0xd5, 0xcf, 0xdb, 0xed, 0xa4, 0x73, 0x47, - 0xf9, 0x39, 0x40, 0xaa, 0x7d, 0xc3, 0x18, 0x5d, 0x7b, 0x3b, 0x73, 0x48, 0x5b, 0x64, 0x5f, 0xe9, 0xbb, 0x02, 0x83, - 0xe3, 0xd8, 0xe7, 0x85, 0x70, 0x26, 0x0c, 0x92, 0x57, 0xe9, 0x13, 0xdf, 0xae, 0x5d, 0x67, 0x5b, 0xdf, 0x0c, 0x64, - 0x61, 0x8b, 0x9f, 0x34, 0xc7, 0x85, 0xc5, 0x55, 0x1b, 0xed, 0xd1, 0xd2, 0xfc, 0xbd, 0xb0, 0x1f, 0xd6, 0x31, 0xdf, - 0x02, 0x41, 0x00, 0xc0, 0x74, 0xee, 0x0f, 0x90, 0x6f, 0x0b, 0x9f, 0xa9, 0x5b, 0x70, 0xd7, 0x8d, 0x63, 0x80, 0x95, - 0x2b, 0x77, 0xa2, 0x28, 0x79, 0xfd, 0x49, 0x14, 0x61, 0x3f, 0x5a, 0x09, 0x08, 0xc7, 0x74, 0x47, 0xe2, 0x9b, 0x1e, - 0xe9, 0x9f, 0x61, 0x1f, 0x70, 0xba, 0x89, 0xf6, 0xc5, 0xc5, 0x2c, 0xed, 0x19, 0x40, 0x46, 0x9c, 0x51, 0x3b, 0xda, - 0x9b, 0x20, 0x96, 0x8c, 0xd5, 0x7d, 0xd1, 0x6c, 0xef, 0xc5, 0x02, 0x40, 0x16, 0x28, 0x9c, 0x9a, 0x5c, 0x58, 0xb6, - 0x34, 0xd6, 0x02, 0x25, 0xa9, 0x32, 0xf6, 0xeb, 0x79, 0x42, 0x08, 0x08, 0x8f, 0xb0, 0x2f, 0x60, 0x81, 0xc9, 0x18, - 0xf2, 0x1c, 0x20, 0xa2, 0x6b, 0xa5, 0x05, 0xd8, 0x84, 0xd3, 0xdb, 0x03, 0x6b, 0x86, 0xb2, 0x97, 0x8a, 0xde, 0x35, - 0xe9, 0x06, 0x17, 0x51, 0xd8, 0xfb, 0xbc, 0x1f, 0xbd, 0xed, 0x3f, 0xb9, 0xa6, 0x07, 0xe2, 0xa0, 0xea, 0x09, 0xf1, - 0x02, 0x40, 0x68, 0xec, 0xd7, 0x05, 0x61, 0x47, 0x49, 0x5d, 0x08, 0xa6, 0x33, 0xc5, 0x30, 0xee, 0x78, 0xa1, 0xdb, - 0x0a, 0xe4, 0x3b, 0x91, 0x16, 0x88, 0x0b, 0x36, 0x61, 0xa5, 0xa2, 0x9b, 0x48, 0xb2, 0x9a, 0xa6, 0x6e, 0xcf, 0xd1, - 0xaa, 0xf4, 0xf6, 0x81, 0x2d, 0x12, 0x1e, 0x9a, 0x00, 0x3f, 0xd8, 0x1c, 0x16, 0x30, 0xe8, 0xf4, 0x58, 0xdf, 0x7c, - 0x07, 0xae, 0x4c, 0xa5, 0xf0, 0x6c, 0x87, 0x29, 0xc9, 0x02, 0x41, 0x00, 0x94, 0x5f, 0x43, 0xe0, 0x51, 0x27, 0xe5, - 0xe9, 0x19, 0x0c, 0x22, 0x45, 0xe9, 0xd3, 0x88, 0xde, 0x15, 0x33, 0x30, 0x31, 0x07, 0xd2, 0x7c, 0xd9, 0x5a, 0xeb, - 0xc0, 0x7c, 0x39, 0x5e, 0xa5, 0x5f, 0x98, 0x13, 0xed, 0xc9, 0x92, 0x1b, 0x50, 0xce, 0x01, 0xf7, 0x4f, 0xd1, 0x36, - 0x66, 0xd1, 0x48, 0xf7, 0xcb, 0x9b, 0x2c, 0x80, 0x48, 0xb0, 0xef, 0x1e, 0xf3, 0xc4, 0xca, 0x1d, 0xd5, 0x41, 0x96}; -unsigned int default_private_key_len = 608; diff --git a/samples/SystemClock_NTP/app/NtpClientDemo.cpp b/samples/SystemClock_NTP/app/NtpClientDemo.cpp index 7ed6c6ec1d..b1152337e0 100644 --- a/samples/SystemClock_NTP/app/NtpClientDemo.cpp +++ b/samples/SystemClock_NTP/app/NtpClientDemo.cpp @@ -1,9 +1,75 @@ #include +#include +#include #include +#include +#include -const TimeChangeRule NtpClientDemo::dstStart = {"BST", Last, Sun, Mar, 1, 60}; -const TimeChangeRule NtpClientDemo::stdStart = {"GMT", Last, Sun, Oct, 2, 0}; -Timezone NtpClientDemo::tz(dstStart, stdStart); +namespace MyZone +{ +using namespace TZ; +/* + * For handling local/UTC time conversions + * This is for the UK, amend as required + */ +const Rule dstStart{{"BST"}, Last, Sun, Mar, 1, 60}; +const Rule stdStart{{"GMT"}, Last, Sun, Oct, 2, 0}; + +// Posix rule string +DEFINE_FSTR_LOCAL(tzstr, "GMT0BST,M3.5.0/1,M10.5.0") + +// Sunrise/sunset requires coordinates +SolarRef solarRef = {51.4769, 0.0005}; // Greenwich, London + +} // namespace MyZone + +namespace +{ +// We can initialise timezone in various ways +// Timezone tz = Timezone::fromPosix(MyZone::tzstr); +// Timezone tz(MyZone::dstStart, MyZone::stdStart); +Timezone tz = TZ::Europe::London(); + +/* + * We use the y/m/d from local time for sunrise/sunset calculations, and the solar calculator + * returns the time from midnight in UTC for that day. We therefore need to adjust this + * to account for timezone and daylight savings. + */ +ZonedTime getNextSunriseSet(bool isSunrise) +{ + auto utcNow = SystemClock.now(eTZ_UTC); + DateTime dt(tz.toLocal(utcNow)); + dt.Hour = 0; + dt.Minute = 0; + dt.Second = 0; + SolarCalculator calc(MyZone::solarRef); + int offset_secs = SECS_PER_MIN * calc.sunRiseSet(isSunrise, dt.Year, dt.Month + 1, dt.Day); + + time_t utcNext = dt + offset_secs; + + // If time has already passed, then make it tomorrow + if(utcNext < utcNow) { + utcNext += SECS_PER_DAY; + } + + return tz.makeZoned(utcNext); +} + +void checkTimeZoneOffset(time_t systemTime) +{ + static ZonedTime nextChange{TZ::invalidTime}; + + if(nextChange == TZ::invalidTime) { + nextChange = tz.makeZoned(systemTime); + } else if(systemTime < nextChange) { + return; + } + + SystemClock.setTimeZone(nextChange.getZoneInfo()); + nextChange = tz.getNextChange(systemTime); +} + +} // namespace void NtpClientDemo::ntpResult(NtpClient& client, time_t ntpTime) { @@ -11,9 +77,10 @@ void NtpClientDemo::ntpResult(NtpClient& client, time_t ntpTime) * Update the system clock and calculate the correct time offset, * accounting for time zone and daylight savings. */ - auto localTime = tz.toLocal(ntpTime); SystemClock.setTime(ntpTime, eTZ_UTC); - SystemClock.setTimeZoneOffset(localTime - ntpTime); + + // Now we've set the clock, we can determine the initial active timezone and maintain the offset + SystemClock.onCheckTimeZoneOffset([](time_t systemTime) { checkTimeZoneOffset(systemTime); }); /* * Display the new time @@ -25,33 +92,29 @@ void NtpClientDemo::ntpResult(NtpClient& client, time_t ntpTime) /* * Display times of next sunrise and sunset */ - DateTime sunrise = getNextSunriseSet(true); - DateTime sunset = getNextSunriseSet(false); - Serial << _F("Next sunrise at ") << sunrise.toShortTimeString() << _F(", sunset at ") << sunset.toShortTimeString() - << endl; -} + ZonedTime sunrise = getNextSunriseSet(true); + ZonedTime sunset = getNextSunriseSet(false); + Serial << _F("Next sunrise ") << sunrise.toString() << _F(", sunset ") << sunset.toString() << endl; -/* - * We use the y/m/d from local time for sunrise/sunset calculations, and the solar calculator - * returns the time from midnight in UTC for that day. We therefore need to adjust this - * to account for timezone and daylight savings. - */ -time_t NtpClientDemo::getNextSunriseSet(bool isSunrise) -{ - auto timeNow = SystemClock.now(eTZ_Local); - DateTime dt(timeNow); - dt.Hour = 0; - dt.Minute = 0; - dt.Second = 0; - SolarCalculator calc; - int offset_secs = SECS_PER_MIN * calc.sunRiseSet(isSunrise, dt.Year, dt.Month + 1, dt.Day); + /* + * Display points at which daylight savings changes. + */ + if(!tz.hasDaylightSavings()) { + Serial << _F("Selected timezone has no daylight savings.") << endl; + return; + } - time_t t = tz.toLocal(dt + offset_secs); + DateTime dt(ntpTime); - // If time has already passed, then make it tomorrow - if(t < timeNow) { - t = tz.toLocal(dt + offset_secs + SECS_PER_DAY); - } + Serial << _F("In ") << dt.Year << _F(", daylight savings:") << endl; + ZonedTime dst = tz.getTransition(dt.Year, true); + ZonedTime transition = tz.makeZoned(dst, true); + Serial << _F(" Starts: ") << transition.toString() << " (" << dst.toUtc().toString() << ")" << endl; + + ZonedTime std = tz.getTransition(dt.Year, false); + transition = tz.makeZoned(std, true); + Serial << _F(" Ends: ") << transition.toString() << " (" << std.toUtc().toString() << ")" << endl; - return t; + ZonedTime nextChange = tz.getNextChange(ntpTime); + Serial << _F("Next change to ") << nextChange.tag() << _F(" on ") << nextChange.toUtc().toString() << endl; } diff --git a/samples/SystemClock_NTP/app/application.cpp b/samples/SystemClock_NTP/app/application.cpp index 5129bb6f22..077fa39682 100644 --- a/samples/SystemClock_NTP/app/application.cpp +++ b/samples/SystemClock_NTP/app/application.cpp @@ -7,9 +7,11 @@ #define WIFI_PWD "PleaseEnterPass" #endif -void onNtpReceive(NtpClient& client, time_t timestamp); +namespace +{ +[[maybe_unused]] void onNtpReceive(NtpClient& client, time_t timestamp); -Timer printTimer; +SimpleTimer printTimer; // Option 1 // Use this option if you want to have full control of NtpTime client @@ -62,7 +64,7 @@ void onNtpReceive(NtpClient& client, time_t timestamp) // Will be called when WiFi station timeout was reached void connectFail(const String& ssid, MacAddress bssid, WifiDisconnectReason reason) { - debugf("I'm NOT CONNECTED!"); + Serial.println(_F("I'm NOT CONNECTED!")); } void gotIP(IpAddress ip, IpAddress netmask, IpAddress gateway) @@ -88,6 +90,8 @@ void gotIP(IpAddress ip, IpAddress netmask, IpAddress gateway) } } +} // namespace + // Will be called when WiFi hardware and software initialization was finished // And system initialization was completed diff --git a/samples/SystemClock_NTP/include/NtpClientDemo.h b/samples/SystemClock_NTP/include/NtpClientDemo.h index 9f6dbbfed0..d12c502963 100644 --- a/samples/SystemClock_NTP/include/NtpClientDemo.h +++ b/samples/SystemClock_NTP/include/NtpClientDemo.h @@ -1,26 +1,16 @@ #pragma once -#include -#include +#include class NtpClientDemo { public: - NtpClientDemo() : ntpcp(nullptr, 30, NtpTimeResultDelegate(&NtpClientDemo::ntpResult, this)) + NtpClientDemo() : client(nullptr, 30, NtpTimeResultDelegate(&NtpClientDemo::ntpResult, this)) { } void ntpResult(NtpClient& client, time_t ntpTime); - time_t getNextSunriseSet(bool isSunrise); - private: - NtpClient ntpcp; - /* - * For handling local/UTC time conversions - * This is for the UK, amend as required - */ - static const TimeChangeRule dstStart; - static const TimeChangeRule stdStart; - static Timezone tz; + NtpClient client; }; diff --git a/samples/TcpClient_NarodMon/app/application.cpp b/samples/TcpClient_NarodMon/app/application.cpp index 063bdd03a6..cdc8c21c47 100644 --- a/samples/TcpClient_NarodMon/app/application.cpp +++ b/samples/TcpClient_NarodMon/app/application.cpp @@ -13,7 +13,9 @@ #define WIFI_PWD "PleaseEnterPass" #endif -#define NARODM_HOST "narodmon.ru" +namespace +{ +DEFINE_FSTR(NARODM_HOST, "narodmon.ru") #define NARODM_PORT 8283 // Time between command packets, in seconds @@ -21,7 +23,7 @@ const unsigned SENDDATA_INTERVAL = 6 * 60; // Таймер для периодического вызова отправки данных // Timer for a periodic call to send data -Timer procTimer; +SimpleTimer procTimer; // Переменная для хранения mac-адреса // Variable for storing MAC address @@ -103,33 +105,33 @@ void sendData() // Когда удачно подключились к роутеру void connectOk(const String& SSID, MacAddress bssid, uint8_t channel) { - // debug msg - debugf("I'm CONNECTED to WiFi"); - // Get the MAC address of our ESP // получаем MAC-адрес нашей ESP и помещаем в переменную mac mac = WifiStation.getMacAddress(); - debugf("mac: %s", mac.toString().c_str()); + + Serial << _F("I'm CONNECTED to WiFi, MAC: ") << mac << endl; } void connectFail(const String& ssid, MacAddress bssid, WifiDisconnectReason reason) { // Display a message on failed connection // Если подключение к роутеру не удалось, выводим сообщение - debugf("I'm NOT CONNECTED!"); + Serial.println(_F("I'm NOT CONNECTED!")); } void gotIP(IpAddress ip, IpAddress netmask, IpAddress gateway) { // Call the sendData function by timer, every 6 minutes // вызываем по таймеру функцию sendData - procTimer.initializeMs(SENDDATA_INTERVAL * 1000, sendData).start(); // каждые 6 минут + procTimer.initializeMs(sendData).start(); // каждые 6 минут // Send immediately on startup // ну и заодно сразу после запуска вызываем, чтобы не ждать 6 минут первый раз sendData(); } +} // namespace + void init() { // Configure and enable output in UART for debug diff --git a/samples/Temperature_DS1820/app/application.cpp b/samples/Temperature_DS1820/app/application.cpp index 75d695c349..3c4277df35 100644 --- a/samples/Temperature_DS1820/app/application.cpp +++ b/samples/Temperature_DS1820/app/application.cpp @@ -3,8 +3,10 @@ #define I2C_PIN 4 +namespace +{ DS18S20 ReadTemp; -Timer procTimer; +SimpleTimer procTimer; //********************************************************** // DS18S20 example, reading @@ -22,31 +24,35 @@ Timer procTimer; //*********************************************************** void readData() { - if(!ReadTemp.MeasureStatus()) // the last measurement completed - { - auto sensorCount = ReadTemp.GetSensorsCount(); - if(sensorCount > 0) { - Serial.println(_F("******************************************")); - } - Serial.println(_F(" Reading temperature DEMO")); - // prints for all sensors - for(unsigned a = 0; a < sensorCount; a++) { - Serial << " T" << a + 1 << " = "; - if(ReadTemp.IsValidTemperature(a)) { - Serial << ReadTemp.GetCelsius(a) << _F(" Celsius, (") << ReadTemp.GetFahrenheit(a) << _F(" Fahrenheit)") - << endl; - } else { - Serial.println(_F("Temperature not valid")); - } - - Serial << _F(" ' << endl; - } - Serial.println(_F("******************************************")); - ReadTemp.StartMeasure(); // next measure, result after 1.2 seconds * number of sensors - } else + if(ReadTemp.MeasureStatus()) { Serial.println(_F("No valid Measure so far! wait please")); + return; + } + + // the last measurement completed + auto sensorCount = ReadTemp.GetSensorsCount(); + if(sensorCount > 0) { + Serial.println(_F("******************************************")); + } + Serial.println(_F(" Reading temperature DEMO")); + // prints for all sensors + for(unsigned a = 0; a < sensorCount; a++) { + Serial << " T" << a + 1 << " = "; + if(ReadTemp.IsValidTemperature(a)) { + Serial << ReadTemp.GetCelsius(a) << _F(" Celsius, (") << ReadTemp.GetFahrenheit(a) << _F(" Fahrenheit)") + << endl; + } else { + Serial.println(_F("Temperature not valid")); + } + + Serial << _F(" ' << endl; + } + Serial.println(_F("******************************************")); + ReadTemp.StartMeasure(); // next measure, result after 1.2 seconds * number of sensors } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); diff --git a/samples/UdpServer_Echo/app/application.cpp b/samples/UdpServer_Echo/app/application.cpp index 52cf2503ec..ab90275c8f 100644 --- a/samples/UdpServer_Echo/app/application.cpp +++ b/samples/UdpServer_Echo/app/application.cpp @@ -6,7 +6,9 @@ #define WIFI_PWD "PleaseEnterPass" #endif -void onReceive(UdpConnection& connection, char* data, int size, IpAddress remoteIP, uint16_t remotePort); // Declaration +namespace +{ +void onReceive(UdpConnection& connection, char* data, int size, IpAddress remoteIP, uint16_t remotePort); // UDP server const uint16_t EchoPort = 1234; @@ -20,7 +22,7 @@ void onReceive(UdpConnection& connection, char* data, int size, IpAddress remote Serial << ">\t" << data; // Send echo to remote sender - String text = String("echo: ") + data; + String text = F("echo: ") + data; udp.sendStringTo(remoteIP, remotePort, text); } @@ -34,6 +36,8 @@ void gotIP(IpAddress ip, IpAddress gateway, IpAddress netmask) Serial.println(_F("==========================\r\n")); } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); // 115200 by default diff --git a/samples/UdpServer_mDNS/app/application.cpp b/samples/UdpServer_mDNS/app/application.cpp index 15638491f0..83c60187cb 100644 --- a/samples/UdpServer_mDNS/app/application.cpp +++ b/samples/UdpServer_mDNS/app/application.cpp @@ -11,8 +11,8 @@ // Our device will be reachable via "sming.local" DEFINE_FSTR_LOCAL(hostName, "sming"); -HttpServer server; - +namespace +{ class MyHttpService : public mDNS::Service { public: @@ -28,37 +28,9 @@ class MyHttpService : public mDNS::Service } }; -static mDNS::Responder responder; -static MyHttpService myHttpService; - -void speedTest(mDNS::Question* question) -{ - using namespace mDNS; - - OneShotFastUs timer; - unsigned count{0}; - for(unsigned i = 0; i < 10000; ++i) { - if(question->getName() == fstrServicesLocal) { - ++count; - } - if(question->getName().equalsIgnoreCase("Haggis basher")) { - ++count; - } - } - debug_i("(question == fstrServicesLocal): %u, %s", count, timer.elapsedTime().toString().c_str()); - - timer.start(); - count = 0; - for(unsigned i = 0; i < 10000; ++i) { - if(String(question->getName()).equalsIgnoreCase(fstrServicesLocal)) { - ++count; - } - if(String(question->getName()).equalsIgnoreCase("Haggis basher")) { - ++count; - } - } - debug_i("(question == fstrServicesLocal): %u, %s", count, timer.elapsedTime().toString().c_str()); -} +HttpServer server; +mDNS::Responder responder; +MyHttpService myHttpService; void test() { @@ -71,7 +43,7 @@ void test() auto submit = [&](const String& name, ResourceType type) { Query query; - auto question = query.addQuestion(name, type); + query.addQuestion(name, type); printMessage(Serial, query); responder.onMessage(query); }; @@ -97,8 +69,6 @@ void test() Query query; auto question = query.addQuestion(fstrServicesLocal, ResourceType::PTR); - // speedTest(question); - checkLike(question, _F("_services._dns-sd._udp.local"), true); checkLike(question, _F("_dns-sd._udp.local"), true); checkLike(question, _F("_udp.local"), true); @@ -141,18 +111,6 @@ void onIndex(HttpRequest& request, HttpResponse& response) response.sendFile("index.html"); } -void onFile(HttpRequest& request, HttpResponse& response) -{ - String file = request.uri.getRelativePath(); - - if(file[0] == '.') { - response.code = HTTP_STATUS_FORBIDDEN; - } else { - response.setCache(86400, true); // It's important to use cache for better performance. - response.sendFile(file); - } -} - void startWebServer() { server.listen(80); @@ -180,6 +138,8 @@ void gotIP(IpAddress ip, IpAddress netmask, IpAddress gateway) startmDNS(); // Start mDNS "Advertise" of your hostname "test.local" for this example } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); // 115200 by default diff --git a/samples/Ultrasonic_HCSR04/app/application.cpp b/samples/Ultrasonic_HCSR04/app/application.cpp index 756e9e3c76..bd2ee80f43 100644 --- a/samples/Ultrasonic_HCSR04/app/application.cpp +++ b/samples/Ultrasonic_HCSR04/app/application.cpp @@ -14,8 +14,10 @@ #define TRIG_PIN 2 #define ECHO_PIN 5 -Timer procTimer; -Ultrasonic ultrasonic = Ultrasonic(); +namespace +{ +SimpleTimer procTimer; +Ultrasonic ultrasonic; void measure() { @@ -26,9 +28,11 @@ void measure() Serial.println(dist); } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); ultrasonic.begin(TRIG_PIN, ECHO_PIN); - procTimer.initializeMs(500, measure).start(); + procTimer.initializeMs<500>(measure).start(); } diff --git a/samples/WebcamServer/app/application.cpp b/samples/WebcamServer/app/application.cpp index 84a1320747..4c09491675 100644 --- a/samples/WebcamServer/app/application.cpp +++ b/samples/WebcamServer/app/application.cpp @@ -10,14 +10,16 @@ #define WIFI_PWD "PleaseEnterPass" #endif +namespace +{ HttpServer server; -FakeCamera* camera = nullptr; +FakeCamera* camera; /* * default http handler to check if server is up and running */ -void onIndex(HttpRequest& request, HttpResponse& response) +void onIndex(HttpRequest&, HttpResponse& response) { response.sendFile(_F("index.html")); } @@ -82,6 +84,8 @@ void startWebServer() server.paths.setDefault(onFile); } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); // Enable serial diff --git a/samples/Websocket_Client/README.rst b/samples/Websocket_Client/README.rst index 141fe2fa58..86335d0938 100644 --- a/samples/Websocket_Client/README.rst +++ b/samples/Websocket_Client/README.rst @@ -2,9 +2,17 @@ Websocket Client ================ This is a simple demo of the WebsocketClient class. +It shows connection, closing and reconnection methods of WebsocketClient. -The client tries to connect to *echo.websocket.org*. +The client tries to connect to a websocket echo server. It sents 10 messages then client connection is closed. -It reconnects and sends 25 messages and continues doing same. +This sequence repeats after 20 seconds. -This demo shows connection, closing and reconnection methods of WebsocketClient. +The sample was originally written to communicate with *echo.websocket.org* +but that service no longer exists. +Instead, run ``make wsserver`` to run a local test server. +This has the advantage of showing detailed diagnostic information which may be helpful. + +Build with ``WS_URL`` set to the server address. For example: + + make WS_URL=ws://192.168.1.10:8000 diff --git a/samples/Websocket_Client/app/application.cpp b/samples/Websocket_Client/app/application.cpp index 7b80fb4974..4501ad92b9 100644 --- a/samples/Websocket_Client/app/application.cpp +++ b/samples/Websocket_Client/app/application.cpp @@ -20,12 +20,13 @@ //Uncomment next line to enable websocket binary transfer test //#define WS_BINARY +namespace +{ WebsocketClient wsClient; -Timer msgTimer; -Timer restartTimer; +SimpleTimer msgTimer; // Number of messages to send -const unsigned MESSAGES_TO_SEND = 10; +const unsigned MESSAGES_TO_SEND = 5; // Interval (in seconds) between sending of messages const unsigned MESSAGE_INTERVAL = 1; @@ -33,36 +34,29 @@ const unsigned MESSAGE_INTERVAL = 1; // Time (in seconds) to wait before restarting client and sending another group of messages const unsigned RESTART_PERIOD = 20; -unsigned msg_cnt = 0; +unsigned messageCount; +bool sendBinary; -#ifdef ENABLE_SSL -DEFINE_FSTR_LOCAL(ws_Url, "wss://echo.websocket.org"); -#else -DEFINE_FSTR_LOCAL(ws_Url, "ws://echo.websocket.org"); -#endif /* ENABLE_SSL */ +DEFINE_FSTR_LOCAL(ws_Url, WS_URL); -void wsMessageSent(); +void sendNewMessage(); -void wsConnected(WebsocketConnection& wsConnection) +void wsConnected(WebsocketConnection&) { Serial << _F("Start sending messages every ") << MESSAGE_INTERVAL << _F(" second(s)...") << endl; - msgTimer.initializeMs(MESSAGE_INTERVAL * 1000, wsMessageSent); - msgTimer.start(); + msgTimer.initializeMs(sendNewMessage); + msgTimer.startOnce(); } -void wsMessageReceived(WebsocketConnection& wsConnection, const String& message) +void wsMessageReceived(WebsocketConnection&, const String& message) { Serial << _F("WebSocket message received: ") << message << endl; Serial << _F("Free Heap: ") << system_get_free_heap_size() << endl; } -void wsBinReceived(WebsocketConnection& wsConnection, uint8_t* data, size_t size) +void wsBinReceived(WebsocketConnection&, uint8_t* data, size_t size) { - Serial.println(_F("WebSocket BINARY received")); - for(uint8_t i = 0; i < size; i++) { - Serial << "wsBin[" << i << "] = 0x" << String(data[i], HEX, 2) << endl; - } - + m_printHex(_F("WebSocket BINARY received"), data, size); Serial << _F("Free Heap: ") << system_get_free_heap_size() << endl; } @@ -70,47 +64,50 @@ void restart() { Serial.println(_F("restart...")); - msg_cnt = 0; + messageCount = 0; + sendBinary = false; wsClient.connect(String(ws_Url)); } -void wsDisconnected(WebsocketConnection& wsConnection) +void wsDisconnected(WebsocketConnection&) { Serial << _F("Restarting websocket client after ") << RESTART_PERIOD << _F(" seconds") << endl; - msgTimer.setCallback(restart); - msgTimer.setIntervalMs(RESTART_PERIOD * 1000); + msgTimer.initializeMs(restart); msgTimer.startOnce(); } -void wsMessageSent() +void sendNewMessage() { if(!WifiStation.isConnected()) { // Check if Esp8266 is connected to router return; } - if(msg_cnt > MESSAGES_TO_SEND) { - Serial.println(_F("End Websocket client session")); - msgTimer.stop(); - wsClient.close(); // clean disconnect. + if(messageCount >= MESSAGES_TO_SEND) { + if(sendBinary) { + Serial.println(_F("End Websocket client session")); + wsClient.close(); // clean disconnect. + return; + } - return; + messageCount = 0; + sendBinary = true; } -#ifndef WS_BINARY - String message = F("Hello ") + String(msg_cnt++); - Serial << _F("Sending websocket message: ") << message << endl; - wsClient.sendString(message); -#else - uint8_t buf[] = {0xF0, 0x00, 0xF0}; - buf[1] = msg_cnt++; - Serial.println(_F("Sending websocket binary buffer")); - for(uint8_t i = 0; i < 3; i++) { - Serial << "wsBin[" << i << "] = 0x" << String(buf[i], HEX, 2) << endl; + if(sendBinary) { + uint8_t buf[10]; + os_get_random(buf, sizeof(buf)); + buf[1] = messageCount; + m_printHex(_F("Sending websocket binary"), buf, sizeof(buf)); + wsClient.sendBinary(buf, sizeof(buf)); + } else { + String message = F("Hello ") + String(messageCount); + Serial << _F("Sending websocket message: ") << message << endl; + wsClient.sendString(message); } - wsClient.sendBinary(buf, 3); -#endif + ++messageCount; + msgTimer.startOnce(); } void STAGotIP(IpAddress ip, IpAddress mask, IpAddress gateway) @@ -133,6 +130,8 @@ void STADisconnect(const String& ssid, MacAddress bssid, WifiDisconnectReason re << endl; } +} // namespace + void init() { Serial.begin(COM_SPEED_SERIAL); diff --git a/samples/Websocket_Client/component.mk b/samples/Websocket_Client/component.mk index 27468497da..619b65de9b 100644 --- a/samples/Websocket_Client/component.mk +++ b/samples/Websocket_Client/component.mk @@ -1,2 +1,9 @@ # Uncomment the option below if you want SSL support #ENABLE_SSL=1 + +CONFIG_VARS += WS_URL + +# Use wss: for secure connection +WS_URL ?= ws://127.0.0.1:8000 + +COMPONENT_CXXFLAGS += -DWS_URL=\"$(WS_URL)\" diff --git a/samples/Websocket_Client/include/ssl/cert.h b/samples/Websocket_Client/include/ssl/cert.h deleted file mode 100644 index c16737b162..0000000000 --- a/samples/Websocket_Client/include/ssl/cert.h +++ /dev/null @@ -1,27 +0,0 @@ -unsigned char default_certificate[] = { - 0x30, 0x82, 0x01, 0xd7, 0x30, 0x82, 0x01, 0x40, 0x02, 0x09, 0x00, 0xe1, 0x1b, 0x5e, 0x9f, 0xbd, 0x6a, 0x8f, 0xd9, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x34, 0x31, 0x32, - 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x29, 0x61, 0x78, 0x54, 0x4c, 0x53, 0x20, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x20, 0x44, 0x6f, 0x64, 0x67, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x31, - 0x31, 0x32, 0x38, 0x31, 0x35, 0x32, 0x30, 0x33, 0x39, 0x5a, 0x17, 0x0d, 0x33, 0x30, 0x30, 0x38, 0x30, 0x37, 0x31, - 0x35, 0x32, 0x30, 0x33, 0x39, 0x5a, 0x30, 0x2c, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, - 0x61, 0x78, 0x54, 0x4c, 0x53, 0x20, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x13, 0x09, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x30, 0x81, 0x9f, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, - 0x89, 0x02, 0x81, 0x81, 0x00, 0xda, 0x2c, 0x2b, 0xed, 0x4a, 0x24, 0xa5, 0x02, 0x6a, 0x39, 0x31, 0x4e, 0xf2, 0x0d, - 0x07, 0x6b, 0x4b, 0xc2, 0xa9, 0x95, 0x06, 0xa3, 0x6e, 0xe1, 0x15, 0x7c, 0x12, 0xcc, 0xe4, 0xf7, 0xa7, 0xf8, 0x09, - 0x7f, 0x50, 0xa5, 0x97, 0xf1, 0x6f, 0x8f, 0x80, 0xa3, 0x1e, 0x88, 0x9f, 0x8e, 0xbd, 0x3b, 0x33, 0x5c, 0xfc, 0x2f, - 0xb3, 0x3e, 0x97, 0xf5, 0xbe, 0xe5, 0xe6, 0x23, 0xf1, 0x16, 0xf3, 0xc4, 0xc9, 0xa4, 0xa4, 0xf9, 0xc0, 0x96, 0xdc, - 0x11, 0x4e, 0x8a, 0xf9, 0x83, 0xde, 0xa2, 0x67, 0xe5, 0xa2, 0x07, 0x63, 0x67, 0x08, 0xc3, 0x4f, 0x5f, 0xac, 0xc2, - 0x8e, 0xc0, 0x9a, 0x17, 0x19, 0xc4, 0xa7, 0x82, 0x22, 0xa6, 0x36, 0x34, 0x38, 0x18, 0x0c, 0x1a, 0x86, 0x6c, 0x70, - 0x1d, 0x70, 0x9c, 0x71, 0x12, 0xec, 0xcb, 0x15, 0xda, 0x97, 0xfe, 0xe5, 0x54, 0xf2, 0x98, 0xfa, 0x28, 0x2d, 0x97, - 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, - 0x00, 0x03, 0x81, 0x81, 0x00, 0x2c, 0x35, 0xcb, 0x03, 0x38, 0xa9, 0x25, 0x40, 0x20, 0x9c, 0x4a, 0x7a, 0x15, 0x1a, - 0x4e, 0x1f, 0xec, 0x34, 0xd3, 0x43, 0x76, 0xb8, 0x90, 0xcf, 0x9f, 0x3b, 0x1c, 0x6d, 0x15, 0xfd, 0xd3, 0x21, 0xfe, - 0x1d, 0x07, 0x84, 0x1f, 0x8a, 0x0e, 0xcf, 0x93, 0x19, 0xdc, 0x16, 0xcf, 0x1e, 0xac, 0x9c, 0xf6, 0x37, 0x97, 0xfb, - 0x7d, 0xef, 0x2b, 0xfa, 0x7c, 0x94, 0x59, 0x4b, 0x6c, 0x04, 0xad, 0xe7, 0x99, 0xfa, 0x0a, 0x25, 0x8b, 0xcd, 0x8e, - 0x0e, 0x9f, 0x63, 0x80, 0x71, 0x4f, 0xf5, 0x5e, 0x0f, 0xf4, 0xdb, 0xe2, 0x17, 0x13, 0x48, 0x68, 0x1b, 0xdd, 0x85, - 0xd8, 0xba, 0xe2, 0xbb, 0xfc, 0x07, 0xf0, 0x3a, 0x29, 0xd1, 0x71, 0xf8, 0xe3, 0x69, 0x4f, 0xb6, 0xc2, 0x26, 0xfc, - 0x94, 0x67, 0xfb, 0xbb, 0x7e, 0x30, 0x8a, 0x55, 0x28, 0x09, 0x35, 0xf1, 0x37, 0x62, 0x19, 0x42, 0x0e, 0x98, 0x55}; -unsigned int default_certificate_len = 475; diff --git a/samples/Websocket_Client/include/ssl/private_key.h b/samples/Websocket_Client/include/ssl/private_key.h deleted file mode 100644 index eb0d88821b..0000000000 --- a/samples/Websocket_Client/include/ssl/private_key.h +++ /dev/null @@ -1,35 +0,0 @@ -unsigned char default_private_key[] = { - 0x30, 0x82, 0x02, 0x5e, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xda, 0x2c, 0x2b, 0xed, 0x4a, 0x24, 0xa5, 0x02, - 0x6a, 0x39, 0x31, 0x4e, 0xf2, 0x0d, 0x07, 0x6b, 0x4b, 0xc2, 0xa9, 0x95, 0x06, 0xa3, 0x6e, 0xe1, 0x15, 0x7c, 0x12, - 0xcc, 0xe4, 0xf7, 0xa7, 0xf8, 0x09, 0x7f, 0x50, 0xa5, 0x97, 0xf1, 0x6f, 0x8f, 0x80, 0xa3, 0x1e, 0x88, 0x9f, 0x8e, - 0xbd, 0x3b, 0x33, 0x5c, 0xfc, 0x2f, 0xb3, 0x3e, 0x97, 0xf5, 0xbe, 0xe5, 0xe6, 0x23, 0xf1, 0x16, 0xf3, 0xc4, 0xc9, - 0xa4, 0xa4, 0xf9, 0xc0, 0x96, 0xdc, 0x11, 0x4e, 0x8a, 0xf9, 0x83, 0xde, 0xa2, 0x67, 0xe5, 0xa2, 0x07, 0x63, 0x67, - 0x08, 0xc3, 0x4f, 0x5f, 0xac, 0xc2, 0x8e, 0xc0, 0x9a, 0x17, 0x19, 0xc4, 0xa7, 0x82, 0x22, 0xa6, 0x36, 0x34, 0x38, - 0x18, 0x0c, 0x1a, 0x86, 0x6c, 0x70, 0x1d, 0x70, 0x9c, 0x71, 0x12, 0xec, 0xcb, 0x15, 0xda, 0x97, 0xfe, 0xe5, 0x54, - 0xf2, 0x98, 0xfa, 0x28, 0x2d, 0x97, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x81, 0x81, 0x00, 0xd2, 0xbf, 0xb6, 0x93, - 0x1a, 0x7a, 0xf9, 0x76, 0xb2, 0xbb, 0x9a, 0x99, 0x03, 0x12, 0x78, 0xe7, 0x39, 0xa0, 0xca, 0x05, 0xae, 0x0a, 0xf3, - 0xd1, 0xb3, 0xda, 0x4d, 0xa2, 0xe5, 0x4f, 0x22, 0x4f, 0x64, 0x85, 0x3a, 0x97, 0x2b, 0x86, 0x4a, 0xd8, 0xd9, 0x4f, - 0x38, 0xf0, 0x8b, 0x08, 0xec, 0x5c, 0xa2, 0x8a, 0x21, 0x05, 0xc6, 0xe5, 0x21, 0x0f, 0x7f, 0x1f, 0x3f, 0x47, 0xda, - 0xdc, 0xec, 0x0d, 0x94, 0x90, 0xe4, 0xab, 0x1d, 0x9a, 0x8f, 0x2c, 0x72, 0x4b, 0xd0, 0xba, 0xf9, 0x16, 0xd3, 0x57, - 0x9c, 0xbe, 0x2c, 0x64, 0xbf, 0xbd, 0x4a, 0xdf, 0x31, 0x0e, 0x37, 0x1a, 0x0d, 0xf7, 0x6c, 0x87, 0x9a, 0x36, 0xb6, - 0x39, 0x7b, 0x1c, 0x53, 0x8e, 0xb8, 0xb3, 0x6a, 0xb1, 0x26, 0x16, 0x36, 0xc1, 0xa2, 0xc6, 0x2d, 0x5d, 0x3d, 0x13, - 0xa7, 0x40, 0x80, 0x83, 0x14, 0x2e, 0x86, 0x04, 0x24, 0xf1, 0x02, 0x41, 0x00, 0xed, 0x1e, 0x2f, 0x12, 0x72, 0x6b, - 0xe2, 0xb1, 0xfb, 0x1e, 0xe2, 0x33, 0xbc, 0xd7, 0xf0, 0xdc, 0x54, 0xc5, 0x60, 0xc9, 0x3d, 0x9e, 0x57, 0x7f, 0x52, - 0xed, 0x16, 0x32, 0x7b, 0x47, 0x43, 0x58, 0xb8, 0x09, 0xef, 0xb1, 0x4c, 0xfd, 0xfd, 0x44, 0x66, 0xe0, 0x2c, 0x30, - 0x56, 0x91, 0xd1, 0xe1, 0xed, 0x48, 0xb8, 0xb4, 0xaa, 0x62, 0x02, 0xb0, 0xb2, 0xbf, 0x64, 0x9c, 0xfc, 0x75, 0x04, - 0xd9, 0x02, 0x41, 0x00, 0xeb, 0x8b, 0xc5, 0xed, 0x0d, 0xf4, 0x2f, 0x8d, 0x0e, 0x1e, 0x66, 0xd7, 0xd0, 0x5b, 0xa0, - 0x89, 0x33, 0xce, 0x9f, 0xcf, 0x91, 0x66, 0x22, 0xad, 0x8a, 0x80, 0xd4, 0x6c, 0xc3, 0x4c, 0x8d, 0xd5, 0xe6, 0x5c, - 0x95, 0x0e, 0xe4, 0x15, 0xc8, 0xa6, 0x75, 0x87, 0xea, 0x2d, 0xdc, 0xcd, 0x5d, 0x53, 0x31, 0xa4, 0x1e, 0x57, 0xab, - 0x27, 0x2c, 0x21, 0x46, 0xb0, 0x03, 0xad, 0x22, 0xe9, 0x7f, 0xef, 0x02, 0x41, 0x00, 0xb8, 0xa0, 0x78, 0xfc, 0x7f, - 0x15, 0x5b, 0xf5, 0x43, 0x58, 0x1f, 0xbf, 0x33, 0x3a, 0x5c, 0xb3, 0xe2, 0x59, 0xb1, 0x6b, 0xe0, 0x4b, 0xab, 0x4b, - 0x5b, 0x71, 0x79, 0x88, 0x23, 0x0f, 0x30, 0xf4, 0x22, 0x90, 0xb2, 0x0e, 0xb6, 0xa9, 0x49, 0x8b, 0xfa, 0x22, 0x70, - 0xa5, 0xce, 0xb2, 0x49, 0xdf, 0x05, 0x98, 0x4b, 0x21, 0x79, 0x4d, 0x49, 0x54, 0xf6, 0x49, 0x2a, 0x79, 0x45, 0xe5, - 0x83, 0xb9, 0x02, 0x41, 0x00, 0x88, 0x37, 0x50, 0xc3, 0x02, 0x6a, 0xd0, 0x84, 0xf6, 0x41, 0x46, 0xa0, 0x4f, 0xf2, - 0x6d, 0x28, 0x6b, 0x39, 0x76, 0xda, 0x06, 0xef, 0xd5, 0xe6, 0x1e, 0x4e, 0xda, 0x89, 0xfb, 0x77, 0x6e, 0x1e, 0xe1, - 0x15, 0x71, 0x6e, 0x27, 0x21, 0x21, 0xe4, 0x81, 0xdb, 0x93, 0xe5, 0xe9, 0xe7, 0x29, 0xad, 0x4e, 0xeb, 0xe6, 0x50, - 0x34, 0xbe, 0x76, 0x9a, 0xd7, 0xd2, 0x3a, 0x8e, 0x09, 0xbe, 0x97, 0x29, 0x02, 0x40, 0x4a, 0x3c, 0x78, 0x22, 0x42, - 0x5b, 0xce, 0x60, 0xa0, 0x48, 0x70, 0x16, 0x7c, 0x92, 0xc2, 0xe1, 0xe3, 0x24, 0xed, 0x58, 0xce, 0xea, 0x91, 0x80, - 0x2d, 0x7c, 0x59, 0xcb, 0xb7, 0x47, 0xa7, 0xc5, 0xab, 0xc6, 0xf6, 0x25, 0x35, 0xd9, 0xbc, 0xd2, 0x11, 0x6e, 0xc2, - 0xfc, 0x97, 0xa9, 0x03, 0xba, 0x5c, 0x8e, 0x92, 0xff, 0x2c, 0xab, 0xab, 0x95, 0x02, 0x1a, 0x9a, 0xd3, 0xb0, 0x4c, - 0x79, 0xfd}; -unsigned int default_private_key_len = 610; diff --git a/samples/Websocket_Client/test.py b/samples/Websocket_Client/test.py new file mode 100644 index 0000000000..429b47bcd4 --- /dev/null +++ b/samples/Websocket_Client/test.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python +# +# Test python application to send test message to server +# +# Shows connection detail so we can compare it to Sming code +# + +import argparse +import logging +import asyncio +from websockets.sync.client import connect + +def main(): + parser = argparse.ArgumentParser(description='Simple websocket client test') + parser.add_argument('URL', help='Connection URL', default='ws://192.168.13.10/ws') + + args = parser.parse_args() + + logging.basicConfig( + format="%(asctime)s %(message)s", + level=logging.DEBUG, + ) + print(f'Connecting to {args.URL}...') + with connect(args.URL) as websocket: + websocket.send("Hello world!") + websocket.recv() + websocket.recv() + +if __name__ == "__main__": + main() diff --git a/samples/Wifi_Sniffer/app/application.cpp b/samples/Wifi_Sniffer/app/application.cpp index 37343ca383..d1144fab1a 100644 --- a/samples/Wifi_Sniffer/app/application.cpp +++ b/samples/Wifi_Sniffer/app/application.cpp @@ -3,8 +3,10 @@ #include "Platform/WifiSniffer.h" #include "Data/HexString.h" -static BeaconInfoList knownAPs; ///< List of known APs -static ClientInfoList knownClients; ///< List of known CLIENTs +namespace +{ +BeaconInfoList knownAPs; ///< List of known APs +ClientInfoList knownClients; ///< List of known CLIENTs const unsigned scanTimeoutMs = 2000; ///< End scan on channel if no new devices found within this time @@ -16,7 +18,7 @@ SimpleTimer timer; * Replace these with ?. * Return a String of exactly 32 characters. */ -static String makeSsidString(const uint8_t* ssid, size_t len) +String makeSsidString(const uint8_t* ssid, size_t len) { String s; s.pad(32); @@ -25,7 +27,7 @@ static String makeSsidString(const uint8_t* ssid, size_t len) return s; } -static void printBeacon(const BeaconInfo& beacon) +void printBeacon(const BeaconInfo& beacon) { if(beacon.err != 0) { Serial << _F("BEACON ERR: (") << beacon.err << ')' << endl; @@ -37,58 +39,68 @@ static void printBeacon(const BeaconInfo& beacon) Serial << makeHexString(beacon.ssid, 32) << " " << beacon.ssid_len << endl; } -static void printClient(const ClientInfo& client) +void printClient(const ClientInfo& client) { if(client.err != 0) { Serial << _F("CLIENT ERR: (") << client.err << ')' << endl; - } else { - Serial << _F("DEVICE: ") << client.station << _F(" ==> "); - - int i = knownAPs.indexOf(client.bssid); - if(i < 0) { - Serial << _F("Unknown/Malformed packet, BSSID = ") << client.bssid << endl; - } else { - auto& ap = knownAPs[i]; - String ssid = makeSsidString(ap.ssid, ap.ssid_len); - Serial << '[' << ssid << ']' << " " << client.ap << " " << String(ap.channel).padLeft(3) << " " - << String(client.rssi).padLeft(4) << endl; - } + return; } + + Serial << _F("DEVICE: ") << client.station << _F(" ==> "); + + int i = knownAPs.indexOf(client.bssid); + if(i < 0) { + Serial << _F("Unknown/Malformed packet, BSSID = ") << client.bssid << endl; + return; + } + + auto& ap = knownAPs[i]; + String ssid = makeSsidString(ap.ssid, ap.ssid_len); + Serial << '[' << ssid << ']' << " " << client.ap << " " << String(ap.channel).padLeft(3) << " " + << String(client.rssi).padLeft(4) << endl; } -static void printSummary() +void printSummary() { - Serial.println("\r\n" - "-------------------------------------------------------------------------------------\r\n"); - for(unsigned u = 0; u < knownClients.count(); u++) { - printClient(knownClients[u]); + DEFINE_FSTR_LOCAL(SEPARATOR, + "\r\n" + "-------------------------------------------------------------------------------------\r\n") + + Serial.println(SEPARATOR); + for(auto& client : knownClients) { + printClient(client); } - for(unsigned u = 0; u < knownAPs.count(); u++) { - printBeacon(knownAPs[u]); + for(auto& ap : knownAPs) { + printBeacon(ap); } - Serial.println("\r\n" - "-------------------------------------------------------------------------------------\r\n"); + Serial.println(SEPARATOR); } -static void onBeacon(const BeaconInfo& beacon) +void onBeacon(const BeaconInfo& beacon) { - if(knownAPs.indexOf(beacon.bssid) < 0) { - knownAPs.add(beacon); - printBeacon(beacon); - timer.restart(); + if(knownAPs.indexOf(beacon.bssid) >= 0) { + // Already listed + return; } + + knownAPs.add(beacon); + printBeacon(beacon); + timer.restart(); } -static void onClient(const ClientInfo& client) +void onClient(const ClientInfo& client) { - if(knownClients.indexOf(client.station) < 0) { - knownClients.add(client); - printClient(client); - timer.restart(); + if(knownClients.indexOf(client.station) >= 0) { + // Already listed + return; } + + knownClients.add(client); + printClient(client); + timer.restart(); } -static void scanChannel(void* param) +void scanChannel(void* param) { auto channel = reinterpret_cast(param); if(channel <= 15) { @@ -97,21 +109,22 @@ static void scanChannel(void* param) sniffer.setChannel(channel); timer.initializeMs(scanChannel, reinterpret_cast(channel + 1)); timer.startOnce(); - } else { - // Stop sniffing and display final scan results - sniffer.end(); - printSummary(); + return; } + + // Stop sniffing and display final scan results + sniffer.end(); + printSummary(); } +} // namespace + void init() { Serial.begin(SERIAL_BAUD_RATE); // 115200 by default Serial.systemDebugOutput(true); // Debug output to serial - Serial << _F("\r\n\r\n" - "SDK version:") - << system_get_sdk_version() << endl; + Serial << endl << endl << _F("SDK version:") << system_get_sdk_version() << endl; Serial.println(_F("ESP8266 mini-sniff by Ray Burnette http://www.hackster.io/rayburne/projects")); Serial.println( _F("Type: /---------MAC---------/-----WiFi Access Point SSID-----/ /------MAC------/ Chnl RSSI")); diff --git a/tests/HostTests/README.rst b/tests/HostTests/README.rst new file mode 100644 index 0000000000..e8f0799bc0 --- /dev/null +++ b/tests/HostTests/README.rst @@ -0,0 +1,13 @@ +HostTests +========= + +Modular tests which must build and run on all architectures. + +DateTime +-------- + +Test data in ``include/DateTimeData.h`` is generated using python script ``tools/datetime-test.py``. + +If this file is changed, re-generate by running:: + + tools/datetime-test.py include/DateTimeData.h diff --git a/tests/HostTests/app/application.cpp b/tests/HostTests/app/application.cpp index c64e750aff..12eabb6daa 100644 --- a/tests/HostTests/app/application.cpp +++ b/tests/HostTests/app/application.cpp @@ -68,7 +68,7 @@ void init() } else { WifiStation.enable(true); WifiStation.config(WIFI_SSID, WIFI_PWD); - WifiEvents.onStationGotIP([](IpAddress ip, IpAddress netmask, IpAddress gateway) { beginTests(); }); + WifiEvents.onStationGotIP([](IpAddress, IpAddress, IpAddress) { beginTests(); }); } #endif } diff --git a/tests/HostTests/component.mk b/tests/HostTests/component.mk index 3fd335e767..17a42e1746 100644 --- a/tests/HostTests/component.mk +++ b/tests/HostTests/component.mk @@ -14,12 +14,6 @@ COMPONENT_SRCDIRS := \ modules \ Arch/$(SMING_ARCH) -ifneq ($(DISABLE_NETWORK),1) -COMPONENT_SRCDIRS += \ - modules/Network \ - modules/Network/Arch/$(SMING_ARCH) -endif - ARDUINO_LIBRARIES := \ SmingTest \ ArduinoJson5 \ @@ -30,9 +24,16 @@ ifeq ($(SMING_ARCH),Host) endif COMPONENT_DEPENDS := \ - malloc_count \ + malloc_count + +ifneq ($(DISABLE_NETWORK),1) +COMPONENT_SRCDIRS += \ + modules/Network \ + modules/Network/Arch/$(SMING_ARCH) +COMPONENT_DEPENDS += \ axtls-8266 \ bearssl-esp8266 +endif ifeq ($(UNAME),Windows) # Network tests run on Linux only diff --git a/tests/HostTests/host-tests-1m.hw b/tests/HostTests/host-tests-1m.hw index 3ad4348efc..52d4449b59 100644 --- a/tests/HostTests/host-tests-1m.hw +++ b/tests/HostTests/host-tests-1m.hw @@ -5,12 +5,10 @@ "1m" ], "partitions": { - "fwfs0": { - "address": "0x000c0000", - "size": "128K" + "fwfs_httprequest": { + "address": "0x000c0000" }, "spiffs0": { - "size": "0x10000", "address": "0x000e0000" } } diff --git a/tests/HostTests/host-tests-esp32.hw b/tests/HostTests/host-tests-esp32.hw index d8b9c308fa..f56f5bd7c9 100644 --- a/tests/HostTests/host-tests-esp32.hw +++ b/tests/HostTests/host-tests-esp32.hw @@ -3,7 +3,7 @@ "base_config": "host-tests", "partitions": { "factory": { - "size": "1M" + "size": "1600K" } } } diff --git a/tests/HostTests/host-tests.hw b/tests/HostTests/host-tests.hw index 33131de523..4ef994422c 100644 --- a/tests/HostTests/host-tests.hw +++ b/tests/HostTests/host-tests.hw @@ -1,20 +1,14 @@ { "name": "Host Tests profile", "base_config": "spiffs", - "devices": { - "testDevice": { - "type": "spiram", - "size": "0x40000000" - } - }, "partitions": { "spiffs0": { "size": "0x10000", "filename": "" }, - "fwfs0": { + "fwfs_httprequest": { "address": "0x220000", - "size": "0x40000", + "size": "0x20000", "type": "data", "subtype": "fwfs", "filename": "$(FW_BASE)/fwfs0.bin", @@ -22,32 +16,6 @@ "target": "fwfs-build", "config": "fwfs0.json" } - }, - "external1": { - "device": "testDevice", - "address": 0, - "size": "4M", - "type": "data", - "subtype": "spiffs", - "filename": "$(FW_BASE)/test-spiffs.bin", - "build": { - "target": "spiffsgen", - "files": "resource" - } - }, - "external2": { - "device": "testDevice", - "address": "0x600000", - "size": "240K", - "type": "data", - "subtype": 37 - }, - "external3": { - "device": "testDevice", - "address": "0x800000", - "size": "240M", - "type": "data", - "subtype": "nvs" } } } \ No newline at end of file diff --git a/tests/HostTests/include/DateTimeData.h b/tests/HostTests/include/DateTimeData.h new file mode 100644 index 0000000000..d77707ac5d --- /dev/null +++ b/tests/HostTests/include/DateTimeData.h @@ -0,0 +1,78 @@ + +/* + * DateTime test data + * + * File generated Mon May 27 21:53:09 2024 + * + */ + +// clang-format off + +namespace +{ +struct TestDate { + const FlashString* stringToParse; + const FlashString* expectedString; + int64_t unixTimestamp; + uint16_t milliseconds; +}; + +#define VALID_HTTP_DATE_MAP(XX) \ + XX(DT_1, "Sun, 06 Nov 1994 08:49:37 GMT", "Sun, 06 Nov 1994 08:49:37 GMT", 0x2ebc98a1LL, 0) \ + XX(DT_2, "Sunday, 06 Nov 1994 08:49:37 GMT", "Sun, 06 Nov 1994 08:49:37 GMT", 0x2ebc98a1LL, 0) \ + XX(DT_3, "Sunday, 06-Nov-94 08:49:37 GMT", "Sun, 06 Nov 1994 08:49:37 GMT", 0x2ebc98a1LL, 0) \ + XX(DT_4, "Mon, 07 November 1994 00:00:00", "Mon, 07 Nov 1994 00:00:00 GMT", 0x2ebd6e00LL, 0) \ + XX(DT_5, " 1 JAN\t \r\n \t2000 23:59:59", "Sat, 01 Jan 2000 23:59:59 GMT", 0x386e94ffLL, 0) + +#define VALID_ISO_DATETIME_MAP(XX) \ + XX(DT_6, "2024-01-31", "2024-01-31T00:00:00Z", 0x65b98d80LL, 0) \ + XX(DT_7, "20240131", "2024-01-31T00:00:00Z", 0x65b98d80LL, 0) \ + XX(DT_8, "2024-01", "2024-01-01T00:00:00Z", 0x65920080LL, 0) \ + XX(DT_9, "1901-12-13T20:45:53", "1901-12-13T20:45:53Z", -0x7fffffffLL, 0) \ + XX(DT_10, "1901-12-13T20:45:52", "1901-12-13T20:45:52Z", -0x80000000LL, 0) \ + XX(DT_11, "1970-01-01T00:00:00", "1970-01-01T00:00:00Z", 0x0LL, 0) \ + XX(DT_12, "2038-01-19T03:14:07", "2038-01-19T03:14:07Z", 0x7fffffffLL, 0) \ + XX(DT_13, "1950-01-01", "1950-01-01T00:00:00Z", -0x259e9d80LL, 0) \ + XX(DT_14, "2024-04-08T12:33:17", "2024-04-08T12:33:17Z", 0x6613e40dLL, 0) \ + XX(DT_15, "2024-04-09T12:33:16", "2024-04-09T12:33:16Z", 0x6615358cLL, 0) + +#define VALID_ISO_DATETIME64_MAP(XX) \ + XX(DT_16, "2038-01-19T03:14:08", "2038-01-19T03:14:08Z", 0x80000000LL, 0) \ + XX(DT_17, "2099-12-31T23:59:59", "2099-12-31T23:59:59Z", 0xf48656ffLL, 0) \ + XX(DT_18, "2105-12-31T23:59:59", "2105-12-31T23:59:59Z", 0xffcedd7fLL, 0) \ + XX(DT_19, "2106-02-07T06:28:15", "2106-02-07T06:28:15Z", 0xffffffffLL, 0) \ + XX(DT_20, "2106-02-07T06:28:15", "2106-02-07T06:28:15Z", 0xffffffffLL, 0) \ + XX(DT_21, "2106-02-07T06:28:16", "2106-02-07T06:28:16Z", 0x100000000LL, 0) \ + XX(DT_22, "1901-12-13T20:45:52", "1901-12-13T20:45:52Z", -0x80000000LL, 0) \ + XX(DT_23, "2024-05-22T06:28:15+07:30", "2024-05-21T22:58:15Z", 0x664d2707LL, 0) \ + XX(DT_24, "2024-05-22T06:28:15-23:45", "2024-05-23T06:13:15Z", 0x664ede7bLL, 0) + +#define VALID_ISO_TIME_MAP(XX) \ + XX(DT_25, "T18:47:12.123", "18:47:12.123", 0x10830LL, 123) \ + XX(DT_26, "T18:47:12.123456", "18:47:12.123", 0x10830LL, 123) \ + XX(DT_27, "T12:34:12", "12:34:12", 0xb0c4LL, 0) \ + XX(DT_28, "T23:59:59", "23:59:59", 0x1517fLL, 0) \ + XX(DT_29, "12:34", "12:34:00", 0xb0b8LL, 0) \ + XX(DT_30, "T2359", "23:59:00", 0x15144LL, 0) + + +#define XX(tag, str, str2, ...) \ + DEFINE_FSTR_LOCAL(STR1_##tag, str) \ + DEFINE_FSTR_LOCAL(STR2_##tag, str2) + VALID_HTTP_DATE_MAP(XX) + VALID_ISO_DATETIME_MAP(XX) + VALID_ISO_DATETIME64_MAP(XX) + VALID_ISO_TIME_MAP(XX) + +#undef XX + +#define XX(tag, str, str2, ...) {&STR1_##tag, &STR2_##tag, ##__VA_ARGS__}, +DEFINE_FSTR_ARRAY(VALID_HTTP_DATE, TestDate, VALID_HTTP_DATE_MAP(XX)) +DEFINE_FSTR_ARRAY(VALID_ISO_DATETIME, TestDate, VALID_ISO_DATETIME_MAP(XX)) +DEFINE_FSTR_ARRAY(VALID_ISO_DATETIME64, TestDate, VALID_ISO_DATETIME64_MAP(XX)) +DEFINE_FSTR_ARRAY(VALID_ISO_TIME, TestDate, VALID_ISO_TIME_MAP(XX)) + +#undef XX + +} // namespace + diff --git a/tests/HostTests/include/modules.h b/tests/HostTests/include/modules.h index dd302fb86b..d29f54e112 100644 --- a/tests/HostTests/include/modules.h +++ b/tests/HostTests/include/modules.h @@ -25,7 +25,7 @@ XX(String) \ XX(ArduinoString) \ XX(Wiring) \ - XX(Crypto) \ + XX_NET(Crypto) \ XX(CStringArray) \ XX(Stream) \ XX(TemplateStream) \ diff --git a/tests/HostTests/modules/ArduinoJson6.cpp b/tests/HostTests/modules/ArduinoJson6.cpp index e56d813818..302b5f603c 100644 --- a/tests/HostTests/modules/ArduinoJson6.cpp +++ b/tests/HostTests/modules/ArduinoJson6.cpp @@ -80,7 +80,7 @@ class JsonTest6 : public TestGroup } // Keep a reference copy for when doc gets messed up - StaticJsonDocument<512> sourceDoc = doc; + auto sourceDoc = doc; TEST_CASE("Json::serialize(doc, String), then save to file") { @@ -248,6 +248,12 @@ class JsonTest6 : public TestGroup REQUIRE(root["longtest"] == testnum); } + TEST_CASE("FSTR comparison") + { + doc[FS_number2] = FS_number2; + REQUIRE(doc[FS_number2] == FS_number2); + } + /* * Dangling reference https://github.com/bblanchon/ArduinoJson/issues/1120 * Fixed in ArduinoJson 6.13.0 diff --git a/tests/HostTests/modules/ArduinoString.cpp b/tests/HostTests/modules/ArduinoString.cpp index b38279c943..e8cdcea961 100644 --- a/tests/HostTests/modules/ArduinoString.cpp +++ b/tests/HostTests/modules/ArduinoString.cpp @@ -24,7 +24,7 @@ class ArduinoStringTest : public TestGroup { } - void execute() + void execute() override { TEST_CASE("String::trim", "[core][String]") { @@ -131,9 +131,9 @@ class ArduinoStringTest : public TestGroup REQUIRE(str == "cleanclean"); // non-decimal negative #s should be as if they were unsigned str = String((int)-100, 16); - REQUIRE(str == "ffffff9c"); + REQUIRE_EQ(str, sizeof(long) == 4 ? "ffffff9c" : "ffffffffffffff9c"); str = String((long)-101, 16); - REQUIRE(str == "ffffff9b"); + REQUIRE_EQ(str, sizeof(long) == 4 ? "ffffff9b" : "ffffffffffffff9b"); str = String((int)-100, 10); REQUIRE(str == "-100"); str = String((long)-100, 10); @@ -304,7 +304,9 @@ class ArduinoStringTest : public TestGroup } } - auto repl = [](const String& key, const String& val, String& s, boolean useURLencode) { s.replace(key, val); }; + auto repl = [](const String& key, const String& val, String& s, [[maybe_unused]] boolean useURLencode) { + s.replace(key, val); + }; TEST_CASE("String SSO handles junk in memory", "[core][String]") { diff --git a/tests/HostTests/modules/CStringArray.cpp b/tests/HostTests/modules/CStringArray.cpp index 61c8394099..c149aa59df 100644 --- a/tests/HostTests/modules/CStringArray.cpp +++ b/tests/HostTests/modules/CStringArray.cpp @@ -24,6 +24,7 @@ class CStringArrayTest : public TestGroup "b\0" "c\0" "d\0"); + DEFINE_FSTR_LOCAL(FS_BasicJoined, "a,b,c,d") TEST_CASE("Empty construction") { @@ -231,6 +232,29 @@ class CStringArrayTest : public TestGroup csa.add(F("test\0again")); REQUIRE_EQ(csa.join("}+{"), "a}+{}+{test}+{again"); REQUIRE_EQ(csa.join(nullptr), "atestagain"); + + csa = FS_Basic; + REQUIRE_EQ(csa.join(), FS_BasicJoined); + } + + TEST_CASE("release") + { + String orig; + // Allocate > SSO + while(orig.length() <= String::SSO_CAPACITY) { + orig += FS_Basic; + } + CStringArray csa = orig; + Serial << csa.join() << endl; + auto cstrWant = csa.c_str(); + String s = csa.release(); + REQUIRE(!csa); + REQUIRE(s.c_str() == cstrWant); + + REQUIRE(s == orig); + + csa = std::move(s); + REQUIRE(csa == orig); } } }; diff --git a/tests/HostTests/modules/Clocks.cpp b/tests/HostTests/modules/Clocks.cpp index fe9803b767..c43957bf7b 100644 --- a/tests/HostTests/modules/Clocks.cpp +++ b/tests/HostTests/modules/Clocks.cpp @@ -26,7 +26,11 @@ template class ClockTestTemplate : public TestG { printLimits(); - for(unsigned i = 0; i < 2000; ++i) { + unsigned loopCount{2000}; +#ifdef ARCH_HOST + loopCount = 50; +#endif + while(loopCount--) { auto value = os_random(); check(value); check(value); @@ -37,26 +41,39 @@ template class ClockTestTemplate : public TestG TEST_CASE("vs. system time") { - constexpr uint32_t duration{2000000}; - auto startTime = system_get_time(); + // Determine whether this is an up or down-counter auto startTicks = Clock::ticks(); + os_delay_us(100); + auto endTicks = Clock::ticks(); + bool isDownCounter = (endTicks < startTicks); + debug_w("%s is %s counter", Clock::typeName(), isDownCounter ? "DOWN" : "UP"); + + // Run for a second or two and check timer ticks correspond approximately with system clock + constexpr uint64_t maxDuration = Clock::maxTicks().template as() - 5000ULL; + constexpr uint32_t duration = std::min(uint64_t(2000000ULL), maxDuration); + auto startTime = system_get_time(); + startTicks = Clock::ticks(); uint32_t time; - while((time = system_get_time()) < startTime + duration) { + while((time = system_get_time()) - startTime < duration) { // } - auto endTicks = Clock::ticks(); - // Handle both up and down counters - auto elapsedTicks = (endTicks >= startTicks) ? endTicks - startTicks : startTicks - endTicks; + endTicks = Clock::ticks(); + if(isDownCounter) { + std::swap(startTicks, endTicks); + } + uint32_t elapsedTicks = (endTicks - startTicks) % (Clock::maxTicks() + 1); debug_w("System time elapsed: %u", time - startTime); - debug_w("%s ticks: %u", Clock::typeName(), elapsedTicks); + debug_w("Ticks: %u (%u - %u)", elapsedTicks, startTicks, endTicks); debug_w("Ratio: x %f", float(elapsedTicks) / (time - startTime)); uint32_t us = Micros::ticksToTime(elapsedTicks); debug_w("Apparent time: %u", us); +#ifndef ARCH_HOST // Up-timers may report 0 if inactive if(endTicks != 0 || startTicks != 0) { REQUIRE(abs(int(us - duration)) < 500); // Allow some latitude } +#endif } } @@ -116,12 +133,8 @@ template class ClockTestTemplate : public TestG NanoTime::TimeSource src; auto time = src.maxClockTime(); - Serial.print(" "); - Serial.print(src.maxTicks()); - Serial.print(" ticks = "); - Serial.print(time.toString()); - Serial.print(" = "); - Serial.println(time.value()); + Serial << " " << src.maxTicks().ticks() << _F(" ticks = ") << time.toString() << " = " << time.value() + << endl; }; template void printMaxCalcTicks() @@ -129,12 +142,7 @@ template class ClockTestTemplate : public TestG NanoTime::TimeSource src; auto time = src.maxCalcTicks().template as(); - Serial.print(" "); - Serial.print(src.maxCalcTicks()); - Serial.print(" ticks = "); - Serial.print(time.toString()); - Serial.print(" = "); - Serial.println(time.value()); + Serial << " " << src.maxCalcTicks() << _F(" ticks = ") << time.toString() << " = " << time.value() << endl; }; template void printMaxTime() @@ -143,30 +151,24 @@ template class ClockTestTemplate : public TestG auto time = source.maxCalcTime(); auto ticks = source.timeToTicks(time); - Serial.print(" "); - Serial.print(time.toString()); - Serial.print(" = "); - Serial.print(time.value()); - Serial.print(" = "); - Serial.print(ticks); - Serial.println(" ticks"); + Serial << " " << time.toString() << " = " << time.value() << " = " << ticks << " ticks" << endl; }; void printLimits() { - m_puts("Limits:\r\n"); + Serial.println(_F("Limits:")); - m_puts(" clock ticks:\r\n"); + Serial.println(_F(" clock ticks:")); printMaxTicks(); printMaxTicks(); printMaxTicks(); - m_puts(" ticks -> time:\r\n"); + Serial.println(_F(" ticks -> time:")); printMaxCalcTicks(); printMaxCalcTicks(); printMaxCalcTicks(); - m_puts(" time -> ticks:\r\n"); + Serial.println(_F(" time -> ticks:")); printMaxTime(); printMaxTime(); printMaxTime(); @@ -184,22 +186,8 @@ template class ClockTestTemplate : public TestG String result_tag = get_tag(!valueIsTime); auto diff = calc - ref; - Serial.print(" "); - Serial.print(value_tag); - Serial.print(": "); - Serial.print(value); - Serial.print(" ("); - Serial.print(unitToString(timeunit)); - Serial.print("), ref "); - Serial.print(result_tag); - Serial.print(": "); - Serial.print(ref); - Serial.print(", calc "); - Serial.print(result_tag); - Serial.print(": "); - Serial.print(calc); - Serial.print(", diff: "); - Serial.println(diff); + Serial << " " << value_tag << ": " << value << " (" << unitToString(timeunit) << _F("), ref ") << result_tag + << ": " << ref << _F(", calc ") << result_tag << ": " << calc << _F(", diff: ") << diff << endl; } void compare() @@ -250,10 +238,16 @@ template class Timer1ClockTestTemplate : public ClockTestTemplate, uint32_t> { public: + static void IRAM_ATTR callback(void*) + { + } + void execute() override { // Configure the hardware to match selected clock divider Timer1Api timer; + timer.setCallback(callback, nullptr); + timer.setInterval(timer.maxTicks()); timer.arm(false); ClockTestTemplate, uint32_t>::execute(); @@ -323,24 +317,15 @@ class BenchmarkPolledTimer : public TestGroup void execute() override { - Serial.print("How many loop iterations can we achieve in "); - Serial.print(TIMEOUT_MS); - Serial.println(" ms ?"); + Serial << _F("How many loop iterations can we achieve in ") << TIMEOUT_MS << _F(" ms ?") << endl; auto print = [](const char* type, uint32_t loopCount) { - Serial.print("Using "); - Serial.print(type); - Serial.print(", managed "); - Serial.print(loopCount); - Serial.print(" iterations, average loop time = "); using namespace NanoTime; constexpr auto nsTotal = convert(); auto nsPerLoop = time(Nanoseconds, muldiv(nsTotal, uint32_t(1), loopCount)); - Serial.print(nsPerLoop.toString()); - Serial.print(" ("); auto cycles = CpuCycleClockNormal::template timeToTicks(uint32_t(nsPerLoop)); - Serial.print(cycles.toString()); - Serial.println(" CPU cycles)"); + Serial << _F("Using ") << type << _F(", managed ") << loopCount << _F(" iterations, average loop time = ") + << nsPerLoop.toString() << " (" << cycles.toString() << _F(" CPU cycles)") << endl; }; print("millis()", millis_loop()); @@ -396,10 +381,10 @@ struct Timer1TestSource : public Timer1Clock { if(clkdiv == TIMER_CLKDIV_16) { // debug_i("prediv = %u, frequency = %u, mul = %u, div = %u", prediv, frequency, mul, div); return (time / prediv) * mul + (time % prediv) * div; - } else { - using R = std::ratio; - return muldiv(time); } + + using R = std::ratio; + return muldiv(time); } TimeType timeToTicks_test2(const TimeType& time) @@ -444,21 +429,11 @@ template void testTimer1() TimeType refticks = round(double(time) * TimeSource::TicksPerUnit::num / TimeSource::TicksPerUnit::den); - // uint64_t refticks = timer1.timeToTicksRef(time); - auto check = [time, refticks](const char* tag, TimeType ticks) { int64_t diff = int64_t(ticks) - int64_t(refticks); if(abs(diff) > 2) { - Serial.print("time = "); - Serial.print(time); - Serial.print(", refticks = "); - Serial.print(refticks); - Serial.print(", "); - Serial.print(tag); - Serial.print(" = "); - Serial.print(ticks); - Serial.print(", diff = "); - Serial.println(diff); + Serial << _F("time = ") << time << _F(", refticks = ") << refticks << ", " << tag << " = " << ticks + << _F(", diff = ") << diff << endl; } }; diff --git a/tests/HostTests/modules/DateTime.cpp b/tests/HostTests/modules/DateTime.cpp index e34c3b0af1..53f4a193de 100644 --- a/tests/HostTests/modules/DateTime.cpp +++ b/tests/HostTests/modules/DateTime.cpp @@ -1,6 +1,8 @@ #include - #include +#include + +#include "DateTimeData.h" class DateTimeTest : public TestGroup { @@ -11,46 +13,216 @@ class DateTimeTest : public TestGroup void execute() override { - DEFINE_FSTR_LOCAL(testDateString, "Sun, 06 Nov 1994 08:49:37 GMT"); - constexpr time_t testDate = 784111777; - DateTime dt; + Serial << _F("time_t is ") << sizeof(time_t) * 8 << _F(" bits") << endl; TEST_CASE("fromHttpDate()") { - REQUIRE(dt.fromHttpDate(testDateString) == true); + checkHttpDates(VALID_HTTP_DATE); + } + + TEST_CASE("fromISO8601 (32-bit)") + { + checkIsoTimes(VALID_ISO_DATETIME, false); } - TEST_CASE("toUnixTime()") + TEST_CASE("fromISO8601 (time only)") { - debug_i("parseHttpDate(\"%s\") produced \"%s\"", String(testDateString).c_str(), - dt.toFullDateTimeString().c_str()); - time_t unixTime = dt.toUnixTime(); - REQUIRE(unixTime == testDate); + checkIsoTimes(VALID_ISO_TIME, true); } - dt = testDate; - debug_d("\"%s\"", dt.toFullDateTimeString().c_str()); + if(sizeof(time_t) == 8) { + TEST_CASE("fromISO8601 (64-bit)") + { + checkIsoTimes(VALID_ISO_DATETIME64, false); + } + } + + TEST_CASE("fromISO8601 with offset") + { + auto check = [&](const String& strWithOffset, const String& strUtc, time_t time, int offsetMins) { + DateTime dt; + // Without zone, offset is applied to time + CHECK(dt.fromISO8601(strWithOffset)); + REQUIRE_EQ(dt.toUnixTime(), time); + REQUIRE_EQ(dt.toISO8601(), strUtc); + // With zone, get local time plus offset + DateTime::ZoneInfo zoneInfo; + CHECK(dt.fromISO8601(strWithOffset, &zoneInfo)); + REQUIRE_EQ(dt.toUnixTime(), time + (offsetMins * 60)); + REQUIRE_EQ(zoneInfo.offsetMins, offsetMins); + REQUIRE_EQ(dt.toISO8601(&zoneInfo), strWithOffset); + }; + + check(F("2024-05-22T06:28:15+12:45"), F("2024-05-21T17:43:15Z"), 1716313395, 12 * 60 + 45); + check(F("2024-05-22T06:28:15-23:45"), F("2024-05-23T06:13:15Z"), 1716444795, -(23 * 60 + 45)); + } TEST_CASE("setTime") { - checkSetTime(59, 59, 23, 14, 2, 2019); - checkSetTime(13, 1, 1, 1, 1, 1970); + checkSetTime(VALID_HTTP_DATE); + checkSetTime(VALID_ISO_DATETIME); + if(sizeof(time_t) == 8) { + checkSetTime(VALID_ISO_DATETIME64); + } + } + + TEST_CASE("setTime speed check") + { + OneShotFastUs timer; + unsigned count = checkSetTime(VALID_HTTP_DATE); + count += checkSetTime(VALID_ISO_DATETIME); + auto elapsed = timer.elapsedTime(); + Serial << "Checked " << count << " dates in " << elapsed.toString(); + if(count != 0) { + Serial << ", " << elapsed / count << " per date"; + } + Serial << endl; + } + + TEST_CASE("getMonthDays") + { + for(auto year : {1980, 1981}) { + unsigned yearDays{0}; + for(unsigned month = dtJanuary; month <= dtDecember; ++month) { + auto days = DateTime::getMonthDays(month, year); + yearDays += days; + Serial << DateTime::getIsoMonthName(month) << ' ' << year << " : " << days << endl; + } + REQUIRE_EQ(yearDays, DateTime::getDaysInYear(year)); + } + } + + TEST_CASE("getDayName") + { + for(unsigned day = dtSunday; day <= dtSaturday; ++day) { + Serial << day << ": " << DateTime::getIsoDayName(day) << ", " << DateTime::getLocaleDayName(day) + << endl; + } + } + + TEST_CASE("getMonthName") + { + for(unsigned month = dtJanuary; month <= dtDecember; ++month) { + Serial << month << ": " << DateTime::getIsoMonthName(month) << ", " + << DateTime::getLocaleMonthName(month) << endl; + } + } + + TEST_CASE("time() sync") + { + auto curTime = SystemClock.now(eTZ_UTC); + DateTime dt; + dt.fromISO8601(F("2024-01-01T13:57Z")); + time_t newTime = dt; + Serial << _F("curTime ") << curTime << _F(", newTime ") << newTime << _F(" ...") << endl; + SystemClock.setTime(newTime, eTZ_UTC); + auto timer = new AutoDeleteTimer; + const auto delay = 2000; + timer->initializeMs([newTime, this]() { + auto sysClockTime = SystemClock.now(eTZ_UTC); + auto ctime = ::time(nullptr); + auto diff = sysClockTime - ctime; + auto timeDelay = sysClockTime - newTime; + Serial << _F("sysClockTime ") << sysClockTime << _F(", delay ") << timeDelay << endl; + Serial << _F("time() ") << ctime << _F(", diff ") << diff << endl; + REQUIRE(abs(1000 * timeDelay - delay) <= 1000); +#ifndef ARCH_HOST + // Can't check time() on host + REQUIRE(abs(diff) < 2); +#endif + complete(); + }); + timer->startOnce(); + pending(); + } + } + + void checkHttpDates(const FSTR::Array& dates) + { + for(auto date : dates) { + DateTime dt; + String s(*date.stringToParse); + Serial << s << endl; + REQUIRE(dt.fromHttpDate(s)); + REQUIRE_EQ(date.unixTimestamp, dt.toUnixTime()); + + dt.setTime(date.unixTimestamp); + REQUIRE_EQ(date.unixTimestamp, dt.toUnixTime()); + + REQUIRE_EQ(String(*date.expectedString), dt.toHTTPDate()); + Serial.println(); + } + } + + void checkIsoTimes(const FSTR::Array& dates, bool timeOnly) + { + for(auto date : dates) { + DateTime dt; + String s(*date.stringToParse); + Serial << s << ", " << String(time_t(date.unixTimestamp), HEX) << endl; + REQUIRE(dt.fromISO8601(s)); + Serial << dt.toISO8601() << endl; + REQUIRE_EQ(date.unixTimestamp, dt.toUnixTime()); + REQUIRE_EQ(date.milliseconds, dt.Milliseconds); + + if(timeOnly) { + REQUIRE_EQ(String(*date.expectedString), dt.format("%T")); + } else { + REQUIRE_EQ(String(*date.expectedString), dt.toISO8601()); + } + + dt.setTime(date.unixTimestamp); + REQUIRE_EQ(date.unixTimestamp, dt.toUnixTime()); + + Serial.println(); } } - void checkSetTime(uint8_t sec, uint8_t min, uint8_t hour, uint8_t day, uint8_t month, uint16_t year) + // Return number of dates checked + unsigned checkSetTime(const FSTR::Array& dates, bool silent = false) { - DateTime dt; - dt.setTime(sec, min, hour, day, month, year); - debug_i("Checking '%s'", dt.toFullDateTimeString().c_str()); - time_t unixTime = dt.toUnixTime(); - dt.setTime(unixTime); - REQUIRE(dt.Second == sec); - REQUIRE(dt.Minute == min); - REQUIRE(dt.Hour == hour); - REQUIRE(dt.Day == day); - REQUIRE(dt.Month == month); - REQUIRE(dt.Year == year); + unsigned checkCount{0}; + + for(auto date : dates) { + const DateTime refDate(date.unixTimestamp); + + if(!silent) { + Serial << "RefDate " << refDate.toFullDateTimeString() << endl; + } + + auto check = [&](int secOffset, int minOffset, int hourOffset, int dayOffset) { + ++checkCount; + const int sec = secOffset + refDate.Second; + const int min = minOffset + refDate.Minute; + const int hour = hourOffset + refDate.Hour; + const int day = dayOffset + refDate.Day; + DateTime dt = DateTime ::toUnixTime(sec, min, hour, day, refDate.Month, refDate.Year); + time_t refTime = DateTime::toUnixTime(0, 0, 0, 1, refDate.Month, refDate.Year); + refTime += sec; + refTime += int64_t(min) * 60; + refTime += int64_t(hour) * 60 * 60; + refTime += int64_t(day - 1) * 24 * 60 * 60; + time_t calcTime = dt.toUnixTime(); + if(calcTime == refTime) { + return; + } + + char buf[100]; + m_snprintf(buf, sizeof(buf), " (%ds, %dm %dh, %dd)", secOffset, minOffset, hourOffset, dayOffset); + Serial << _F("Check ") << DateTime(refTime).toFullDateTimeString() << buf << endl; + Serial << _F("Got ") << dt.toFullDateTimeString() << ", diff " << refTime - calcTime << endl; + REQUIRE_EQ(refTime, calcTime); + }; + + for(int offset = -10000; offset < 10000; offset += 555) { + check(offset, 0, 0, 0); + check(0, offset, 0, 0); + check(0, 0, offset, 0); + check(0, 0, 0, offset); + } + }; + + return checkCount; } }; diff --git a/tests/HostTests/modules/Files.cpp b/tests/HostTests/modules/Files.cpp index 05eef51a4b..7f5ad4d131 100644 --- a/tests/HostTests/modules/Files.cpp +++ b/tests/HostTests/modules/Files.cpp @@ -16,46 +16,48 @@ class FilesTest : public TestGroup DEFINE_FSTR_LOCAL(testFileName, "test.txt"); int res, pos, size; - FileHandle file{-1}; - TEST_CASE("Initial position and size") { - res = fileSetContent(testFileName, testContent); - debug_i("fileSetContent() returned %d", res); - REQUIRE(size_t(res) == testContent.length()); - file = fileOpen(testFileName, File::ReadWrite); - size = fileSeek(file, 0, SeekOrigin::End); - pos = fileSeek(file, 100, SeekOrigin::Start); - debug_i("pos = %d, size = %d", pos, size); - REQUIRE(pos == 100); - REQUIRE(size_t(size) == testContent.length()); - } - - TEST_CASE("Reduce file sizes") - { - res = fileTruncate(file, 555); - pos = fileTell(file); - size = fileSeek(file, 0, SeekOrigin::End); - debug_i("res = %d, pos = %d, size = %d", res, pos, size); - REQUIRE(res == 0); - REQUIRE(pos == 100); - REQUIRE(size == 555); - } - - TEST_CASE("Increase file size") - { - res = fileTruncate(file, 12345); - size = fileSeek(file, 0, SeekOrigin::End); - debug_i("res = %d, size = %d", res, size); - REQUIRE(res < 0); - REQUIRE(size == 555); - } - - TEST_CASE("Close file") - { - fileClose(file); - REQUIRE(fileTell(file) < 0); - file = -1; + FileHandle file{-1}; + + TEST_CASE("Initial position and size") + { + res = fileSetContent(testFileName, testContent); + debug_i("fileSetContent() returned %d", res); + REQUIRE(size_t(res) == testContent.length()); + file = fileOpen(testFileName, File::ReadWrite); + size = fileSeek(file, 0, SeekOrigin::End); + pos = fileSeek(file, 100, SeekOrigin::Start); + debug_i("pos = %d, size = %d", pos, size); + REQUIRE(pos == 100); + REQUIRE(size_t(size) == testContent.length()); + } + + TEST_CASE("Reduce file sizes") + { + res = fileTruncate(file, 555); + pos = fileTell(file); + size = fileSeek(file, 0, SeekOrigin::End); + debug_i("res = %d, pos = %d, size = %d", res, pos, size); + REQUIRE(res == 0); + REQUIRE(pos == 100); + REQUIRE(size == 555); + } + + TEST_CASE("Increase file size") + { + res = fileTruncate(file, 12345); + size = fileSeek(file, 0, SeekOrigin::End); + debug_i("res = %d, size = %d", res, size); + REQUIRE(res < 0); + REQUIRE(size == 555); + } + + TEST_CASE("Close file") + { + fileClose(file); + REQUIRE(fileTell(file) < 0); + } } TEST_CASE("fileGetSize") @@ -88,6 +90,7 @@ class FilesTest : public TestGroup { fileSetContent(testFileName, testContent); FileStream fs(testFileName); + Serial << testFileName << " ID: " << fs.id() << endl; res = fs.truncate(100); pos = fs.getPos(); size = fs.getSize(); diff --git a/tests/HostTests/modules/Libc.cpp b/tests/HostTests/modules/Libc.cpp index 73f0183068..c5c1d55e61 100644 --- a/tests/HostTests/modules/Libc.cpp +++ b/tests/HostTests/modules/Libc.cpp @@ -3,9 +3,8 @@ static int num_instances; struct A { - A() + A() : order(++num_instances) { - order = ++num_instances; } int order; diff --git a/tests/HostTests/modules/Network/Arch/Host/Hosted.cpp b/tests/HostTests/modules/Network/Arch/Host/Hosted.cpp index fa01c930e9..473845b175 100644 --- a/tests/HostTests/modules/Network/Arch/Host/Hosted.cpp +++ b/tests/HostTests/modules/Network/Arch/Host/Hosted.cpp @@ -8,6 +8,8 @@ #include #include +namespace +{ using namespace simpleRPC; static uint32_t plusCommand(uint8_t a, uint16_t b) @@ -40,48 +42,72 @@ class TheWire TheWire theWire; -class HostedTest : public TestGroup +class TestParseHandler : public ParserCallbacks { public: using RemoteCommands = HashMap; - HostedTest() : TestGroup(_F("Hosted")) + RemoteCommands commands; + uint8_t methodPosition = 0; + String parsedCommand; + + void startMethods() override { + methodPosition = 0; + commands.clear(); } - void execute() override + void startMethod() override + { + parsedCommand = ""; + } + + void methodSignature(char) override + { + } + + void methodName(char ch) override + { + parsedCommand += ch; + } + + void endMethod() override + { + commands[parsedCommand] = methodPosition++; + } + + void endMethods() override + { + } +}; + +class HostedTest : public TestGroup +{ +public: + HostedTest() : TestGroup("Hosted") { - char packet[] = { - 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x50, 0x43, 0x00, 0x03, 0x00, 0x00, 0x3c, 0x49, 0x00, 0x3a, 0x20, - 0x48, 0x20, 0x42, 0x3b, 0x70, 0x69, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x3a, 0x20, 0x53, 0x65, 0x74, 0x73, 0x20, - 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x20, 0x70, 0x69, - 0x6e, 0x2e, 0x20, 0x40, 0x70, 0x69, 0x6e, 0x3a, 0x20, 0x50, 0x69, 0x6e, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, - 0x72, 0x2c, 0x20, 0x40, 0x6d, 0x6f, 0x64, 0x65, 0x3a, 0x20, 0x4d, 0x6f, 0x64, 0x65, 0x20, 0x74, 0x79, 0x70, - 0x65, 0x2e, 0x00, 0x42, 0x3a, 0x20, 0x48, 0x3b, 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x52, 0x65, 0x61, - 0x64, 0x3a, 0x20, 0x52, 0x65, 0x61, 0x64, 0x20, 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x20, 0x70, 0x69, - 0x6e, 0x2e, 0x20, 0x40, 0x70, 0x69, 0x6e, 0x3a, 0x20, 0x50, 0x69, 0x6e, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, - 0x72, 0x2e, 0x20, 0x40, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3a, 0x20, 0x50, 0x69, 0x6e, 0x20, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x2e, 0x00, 0x3a, 0x20, 0x48, 0x20, 0x42, 0x3b, 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, - 0x57, 0x72, 0x69, 0x74, 0x65, 0x3a, 0x20, 0x57, 0x72, 0x69, 0x74, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, - 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x20, 0x70, 0x69, 0x6e, 0x2e, 0x20, 0x40, 0x70, 0x69, 0x6e, 0x3a, - 0x20, 0x50, 0x69, 0x6e, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x2e, 0x20, 0x40, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x20, 0x50, 0x69, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x00, 0x00}; - - ParserSettings settings; - settings.startMethods = ParserSettings::SimpleMethod(&HostedTest::startMethods, this); - settings.startMethod = ParserSettings::SimpleMethod(&HostedTest::startMethod, this); - settings.methodName = ParserSettings::CharMethod(&HostedTest::methodName, this); - settings.endMethod = ParserSettings::SimpleMethod(&HostedTest::endMethod, this); - settings.endMethods = ParserSettings::SimpleMethod(&HostedTest::endMethods, this); - settings.state = ParserState::ready; + } + void execute() override + { TEST_CASE("simpleRPC::parse()") { - REQUIRE(parse(settings, packet, sizeof(packet)) == ParserResult::finished); - REQUIRE(commands.count() == 3); - REQUIRE(commands["digitalWrite"] == 2); - REQUIRE(commands["pinMode"] != 2); - REQUIRE(commands["pinMode"] == 0); + char packet[]{"simpleRPC\0" // protocol identifier + "\3\0\0" // version + "listen(4031); server->setTimeOut(USHRT_MAX); // disable connection timeout server->setKeepAlive(USHRT_MAX); // disable connection timeout @@ -108,10 +134,10 @@ class HostedTest : public TestGroup plusCommand, "plusCommand> Sum two numbers. @a: number one. @b: number two.", /* class methods */ // uint8_t TwoWire::begin(uint8_t sda, uint8_t scl) - pack(&theWire, (uint8_t(TheWire::*)(uint8_t,uint8_t))&TheWire::begin), "TheWire::begin> Starts two-wire communication. @sda: Data pin. @scl: Clock pin.", + makeTuple(&theWire, static_cast(&TheWire::begin)), "TheWire::begin> Starts two-wire communication. @sda: Data pin. @scl: Clock pin.", // void TheWire::begin() - pack(&theWire, (void(TheWire::*)())&TheWire::begin), "TheWire::begin> Starts two-wire communication.", - pack(&theWire, (uint8_t(TheWire::*)())&TheWire::getCalled), "TheWire::getCalled> Gets times called. @return: Result." + makeTuple(&theWire, static_cast(&TheWire::begin)), "TheWire::begin> Starts two-wire communication.", + makeTuple(&theWire, &TheWire::getCalled), "TheWire::getCalled> Gets times called. @return: Result." ); // clang-format on @@ -120,6 +146,7 @@ class HostedTest : public TestGroup // RPC Client + TcpClient client{false}; client.connect(WifiStation.getIP(), 4031); Hosted::Transport::TcpClientStream stream(client, 1024); @@ -128,8 +155,8 @@ class HostedTest : public TestGroup TEST_CASE("Client::getRemoteCommands()") { REQUIRE(hostedClient.getRemoteCommands() == true); - REQUIRE(hostedClient.getFunctionId("plusCommand") == 2); - REQUIRE(hostedClient.getFunctionId("uint8_t TheWire::begin(uint8_t, uint8_t)") == 3); + REQUIRE_EQ(hostedClient.getFunctionId("plusCommand"), 2); + REQUIRE_EQ(hostedClient.getFunctionId("uint8_t TheWire::begin(uint8_t, uint8_t)"), 3); } TEST_CASE("Client::send and wait()") @@ -137,7 +164,7 @@ class HostedTest : public TestGroup ElapseTimer timer; REQUIRE(hostedClient.send("plusCommand", uint8_t(3), uint16_t(2)) == true); - REQUIRE(hostedClient.wait() == 5); + REQUIRE_EQ(hostedClient.wait(), 5); debug_i("PlusCommand Roundtrip Time: %s", timer.elapsedTime().toString().c_str()); } @@ -145,48 +172,18 @@ class HostedTest : public TestGroup TEST_CASE("Client::send and check class method") { REQUIRE(hostedClient.send("uint8_t TheWire::begin(uint8_t, uint8_t)", uint8_t(3), uint8_t(3)) == true); - REQUIRE(hostedClient.wait() == 6); + REQUIRE_EQ(hostedClient.wait(), 6); REQUIRE(hostedClient.send("uint8_t TheWire::getCalled()") == true); - REQUIRE(hostedClient.wait() == 6); + REQUIRE_EQ(hostedClient.wait(), 6); } - } - -private: - RemoteCommands commands; - uint8_t methodPosition = 0; - String parsedCommand; - - TcpServer* server{nullptr}; - TcpClient client{false}; - Hosted::Transport::TcpClientStream* stream{nullptr}; - - void startMethods() - { - methodPosition = 0; - commands.clear(); - } - - void startMethod() - { - parsedCommand = ""; - } - void methodName(char ch) - { - parsedCommand += ch; - } - - void endMethod() - { - commands[parsedCommand] = methodPosition++; - } - - void endMethods() - { + server->shutdown(); } }; +} // namespace + void REGISTER_TEST(Hosted) { registerGroup(); diff --git a/tests/HostTests/modules/Network/Arch/Host/HttpRequest.cpp b/tests/HostTests/modules/Network/Arch/Host/HttpRequest.cpp index 5782443abb..7c0191b333 100644 --- a/tests/HostTests/modules/Network/Arch/Host/HttpRequest.cpp +++ b/tests/HostTests/modules/Network/Arch/Host/HttpRequest.cpp @@ -31,9 +31,8 @@ TestFile testFiles[]{ class HttpRequestTest : public TestGroup { public: - HttpRequestTest() : TestGroup(_F("HTTP")) + HttpRequestTest() : TestGroup(_F("HTTP")), server(new HttpServer) { - server = new HttpServer; } void execute() override @@ -43,10 +42,7 @@ class HttpRequestTest : public TestGroup return; } - auto fs = IFS::createFirmwareFilesystem(*Storage::findPartition(Storage::Partition::SubType::Data::fwfs)); - CHECK(fs != nullptr); - CHECK(fs->mount() == FS_OK); - fileSetFileSystem(fs); + REQUIRE(fwfs_mount(Storage::findPartition("fwfs_httprequest"))); server->listen(80); server->paths.setDefault([](HttpRequest& request, HttpResponse& response) { @@ -74,7 +70,7 @@ class HttpRequestTest : public TestGroup url.Path = String('/') + file.name; auto req = new HttpRequest(url); - req->onRequestComplete([this, file](HttpConnection& connection, bool success) -> int { + req->onRequestComplete([this, file](HttpConnection& connection, bool) -> int { auto response = connection.getResponse(); debug_i("Client received '%s'", connection.getRequest()->uri.toString().c_str()); Serial.print(response->toString()); diff --git a/tests/HostTests/modules/Network/Arch/Host/TcpClient.cpp b/tests/HostTests/modules/Network/Arch/Host/TcpClient.cpp index 0a9a9383ef..32369c64b5 100644 --- a/tests/HostTests/modules/Network/Arch/Host/TcpClient.cpp +++ b/tests/HostTests/modules/Network/Arch/Host/TcpClient.cpp @@ -24,11 +24,11 @@ class TcpClientTest : public TestGroup // Tcp Server server = new TcpServer( - [this](TcpClient& client, char* data, int size) -> bool { + [this](TcpClient&, char* data, int size) -> bool { // on data return receivedData.concat(data, size); }, - [this, inputData](TcpClient& client, bool successful) { + [this, inputData](TcpClient&, bool successful) { // on client close if(finished) { return; @@ -43,7 +43,7 @@ class TcpClientTest : public TestGroup server->setKeepAlive(USHRT_MAX); // disable connection timeout // Tcp Client - bool connected = client.connect(WifiStation.getIP(), port); + [[maybe_unused]] bool connected = client.connect(WifiStation.getIP(), port); debug_d("Connected: %d", connected); TEST_CASE("TcpClient::send stream") diff --git a/tests/HostTests/modules/Crypto.cpp b/tests/HostTests/modules/Network/Crypto.cpp similarity index 100% rename from tests/HostTests/modules/Crypto.cpp rename to tests/HostTests/modules/Network/Crypto.cpp diff --git a/tests/HostTests/modules/Crypto/AxHash.h b/tests/HostTests/modules/Network/Crypto/AxHash.h similarity index 98% rename from tests/HostTests/modules/Crypto/AxHash.h rename to tests/HostTests/modules/Network/Crypto/AxHash.h index 0b577a592e..00b4cf35eb 100644 --- a/tests/HostTests/modules/Crypto/AxHash.h +++ b/tests/HostTests/modules/Network/Crypto/AxHash.h @@ -13,9 +13,7 @@ #include #include -namespace Crypto -{ -namespace Ax +namespace Crypto::Ax { #define AX_HASH_ENGINE(class_, name_, hashsize_, statesize_, blocksize_) \ class class_##Engine \ @@ -58,6 +56,4 @@ using Sha256 = HashContext; using Sha384 = HashContext; using Sha512 = HashContext; -} // namespace Ax - -} // namespace Crypto +} // namespace Crypto::Ax diff --git a/tests/HostTests/modules/Crypto/BrHash.h b/tests/HostTests/modules/Network/Crypto/BrHash.h similarity index 98% rename from tests/HostTests/modules/Crypto/BrHash.h rename to tests/HostTests/modules/Network/Crypto/BrHash.h index ac5ecce4f7..072cb79541 100644 --- a/tests/HostTests/modules/Crypto/BrHash.h +++ b/tests/HostTests/modules/Network/Crypto/BrHash.h @@ -13,9 +13,7 @@ #include #include -namespace Crypto -{ -namespace Br +namespace Crypto::Br { #define BR_HASH_ENGINE(class_, name_, hashsize_, statesize_, blocksize_) \ class class_##Engine \ @@ -70,6 +68,4 @@ using Sha256 = HashContext; using Sha384 = HashContext; using Sha512 = HashContext; -} // namespace Br - -} // namespace Crypto +} // namespace Crypto::Br diff --git a/tests/HostTests/modules/Crypto/EspHash.h b/tests/HostTests/modules/Network/Crypto/EspHash.h similarity index 100% rename from tests/HostTests/modules/Crypto/EspHash.h rename to tests/HostTests/modules/Network/Crypto/EspHash.h diff --git a/tests/HostTests/modules/Network/Http.cpp b/tests/HostTests/modules/Network/Http.cpp index ff4e329620..cab7ce0e4a 100644 --- a/tests/HostTests/modules/Network/Http.cpp +++ b/tests/HostTests/modules/Network/Http.cpp @@ -45,12 +45,12 @@ class HttpTest : public TestGroup } } - static void printHeaders(const HttpHeaders& headers) + static void printHeaders([[maybe_unused]] const HttpHeaders& headers) { #if DEBUG_VERBOSE_LEVEL == DBG Serial << _F(" count: ") << headers.count() << endl; - for(unsigned i = 0; i < headers.count(); ++i) { - String s = headers[i]; + for(auto hdr : headers) { + String s = hdr; m_printHex(" ", s.c_str(), s.length(), 0, 32); } #endif diff --git a/tests/HostTests/modules/Network/Url.cpp b/tests/HostTests/modules/Network/Url.cpp index 812de0fb83..b13a6cd319 100644 --- a/tests/HostTests/modules/Network/Url.cpp +++ b/tests/HostTests/modules/Network/Url.cpp @@ -119,7 +119,12 @@ class UrlTest : public TestGroup uri.Query["key"] = "7XXUJWCWYTMXKN3L"; int sensorValue = 347; uri.Query["field1"] = String(sensorValue); - REQUIRE(uri.toString() == FS_url); + REQUIRE_EQ(uri.toString(), FS_url); + REQUIRE(!uri.Scheme); + REQUIRE_EQ(uri.Port, 0); + REQUIRE_EQ(uri.getPort(), 80); + uri.Scheme = "HTTP"; + REQUIRE_EQ(uri.toString(), FS_url); } } diff --git a/tests/HostTests/modules/Serial.cpp b/tests/HostTests/modules/Serial.cpp index 069e98e22a..544f1f6bf2 100644 --- a/tests/HostTests/modules/Serial.cpp +++ b/tests/HostTests/modules/Serial.cpp @@ -41,7 +41,7 @@ class SerialTest : public TestGroup String compareBuffer; String readBuffer; for(unsigned i = 0; i < 10; ++i) { - m_printf("txfree = %u\n", txbuf.getFreeSpace()); + Serial << _F("txfree = ") << txbuf.getFreeSpace() << endl; for(char c = 'a'; c <= 'z'; ++c) { if(txbuf.getFreeSpace() < 10) { readBuffer += read(); diff --git a/tests/HostTests/modules/Storage.cpp b/tests/HostTests/modules/Storage.cpp index 4c47578f91..e138f5cd39 100644 --- a/tests/HostTests/modules/Storage.cpp +++ b/tests/HostTests/modules/Storage.cpp @@ -33,12 +33,12 @@ class TestDevice : public Storage::Device return true; } - bool write(storage_size_t address, const void* src, size_t size) override + bool write(storage_size_t, const void*, size_t) override { return false; } - bool erase_range(storage_size_t address, storage_size_t size) override + bool erase_range(storage_size_t, storage_size_t) override { return false; } diff --git a/tests/HostTests/modules/Stream.cpp b/tests/HostTests/modules/Stream.cpp index d360be6d1d..9821b8b79c 100644 --- a/tests/HostTests/modules/Stream.cpp +++ b/tests/HostTests/modules/Stream.cpp @@ -11,12 +11,14 @@ #include #endif +#ifndef DISABLE_NETWORK DEFINE_FSTR_LOCAL(template1, "Stream containing {var1}, {var2} and {var3}. {} {{}} {{12345") DEFINE_FSTR_LOCAL(template1_1, "Stream containing value #1, value #2 and {var3}. {} {{}} {{12345") DEFINE_FSTR_LOCAL(template1_2, "Stream containing value #1, value #2 and [value #3]. {} {{}} {{12345") DEFINE_FSTR_LOCAL(template2, "This text should {disable}not {var1} really {var2:hello} again {enable}be missing.") DEFINE_FSTR_LOCAL(template2_1, "This text should be missing.") +#endif class StreamTest : public TestGroup { @@ -108,7 +110,7 @@ class StreamTest : public TestGroup TEST_CASE("MultipartStream / MultiStream") { unsigned itemIndex{0}; - constexpr const FlashString* items[]{ + const FlashString* items[]{ &template1, &template1_1, &template1_2, &template2, &template2_1, }; MultipartStream multi([&]() -> MultipartStream::BodyPart { @@ -171,8 +173,8 @@ class StreamTest : public TestGroup { // STL may perform one-time memory allocation for mutexes, etc. - std::shared_ptr data(new char[18]); - SharedMemoryStream(data, 18); + std::shared_ptr data(new char[18]); + SharedMemoryStream stream(data, 18); } auto memStart = MallocCount::getCurrent(); @@ -180,21 +182,21 @@ class StreamTest : public TestGroup TEST_CASE("SharedMemoryStream") { - char* message = new char[18]; - memcpy(message, "Wonderful data...", 18); - std::shared_ptr data(message, [&message](const char* p) { delete[] p; }); + const char* message = "Wonderful data..."; + const size_t msglen = strlen(message); + std::shared_ptr data(new char[msglen]); + memcpy(data.get(), message, msglen); debug_d("RefCount: %d", data.use_count()); - Vector*> list; + Vector*> list; for(unsigned i = 0; i < 4; i++) { - list.addElement(new SharedMemoryStream(data, strlen(message))); + list.addElement(new SharedMemoryStream(data, msglen)); } - for(unsigned i = 0; i < list.count(); i++) { + for(auto element : list) { constexpr size_t bufferSize{5}; char buffer[bufferSize]{}; - auto element = list[i]; String output; while(!element->isFinished()) { diff --git a/tests/HostTests/modules/String.cpp b/tests/HostTests/modules/String.cpp index ab0e0d87fa..6593529e0a 100644 --- a/tests/HostTests/modules/String.cpp +++ b/tests/HostTests/modules/String.cpp @@ -15,10 +15,11 @@ class StringTest : public TestGroup nonTemplateTest(); testString(); + testMove(); testMakeHexString(); } - template void templateTest(T x) + template void templateTest(T) { #ifndef ARCH_HOST auto pstr = PSTR("This PSTR should get moved out of RAM, filtered by __pstr__ in symbol name."); @@ -154,17 +155,62 @@ class StringTest : public TestGroup } } + void testMove() + { + DEFINE_FSTR_LOCAL(shortText, "Not long") + DEFINE_FSTR_LOCAL(longText, "Greater than SSO buffer length") + + TEST_CASE("Move into unassigned string") + { + // Normal move + String s1 = longText; + String s2 = std::move(s1); + REQUIRE(!s1); + REQUIRE(s2.length() == longText.length()); + } + + TEST_CASE("Move between allocated strings of same length") + { + String s1 = longText; + auto cstrWant = s1.c_str(); + String s2 = std::move(s1); + REQUIRE(s2.c_str() == cstrWant); + } + + TEST_CASE("Move to allocated string of shorter length") + { + String s1 = longText; + String s2 = shortText; + auto cstrWant = s1.c_str(); + s2 = std::move(s1); + REQUIRE(s2.c_str() == cstrWant); + } + + TEST_CASE("Move to allocated string of longer length") + { + String s1 = longText; + String s2; + auto cstrWant = s1.c_str(); + s1 = ""; // Buffer remains allocated + s2 = std::move(s1); + REQUIRE(s2.c_str() == cstrWant); + } + } + void testMakeHexString() { - uint8 hwaddr[] = {0xaa, 0xbb, 0xcc, 0xdd, 0x12, 0x55, 0x00}; - REQUIRE(makeHexString(nullptr, 6) == String::empty); - REQUIRE(makeHexString(hwaddr, 0) == String::empty); - REQUIRE(makeHexString(hwaddr, 6) == F("aabbccdd1255")); - REQUIRE(makeHexString(hwaddr, 6, ':') == F("aa:bb:cc:dd:12:55")); - REQUIRE(makeHexString(hwaddr, 7) == F("aabbccdd125500")); - REQUIRE(makeHexString(hwaddr, 7, ':') == F("aa:bb:cc:dd:12:55:00")); - REQUIRE(makeHexString(hwaddr, 1, ':') == F("aa")); - REQUIRE(makeHexString(hwaddr, 0, ':') == String::empty); + TEST_CASE("makeHexString") + { + uint8_t hwaddr[] = {0xaa, 0xbb, 0xcc, 0xdd, 0x12, 0x55, 0x00}; + REQUIRE(makeHexString(nullptr, 6) == String::empty); + REQUIRE(makeHexString(hwaddr, 0) == String::empty); + REQUIRE(makeHexString(hwaddr, 6) == F("aabbccdd1255")); + REQUIRE(makeHexString(hwaddr, 6, ':') == F("aa:bb:cc:dd:12:55")); + REQUIRE(makeHexString(hwaddr, 7) == F("aabbccdd125500")); + REQUIRE(makeHexString(hwaddr, 7, ':') == F("aa:bb:cc:dd:12:55:00")); + REQUIRE(makeHexString(hwaddr, 1, ':') == F("aa")); + REQUIRE(makeHexString(hwaddr, 0, ':') == String::empty); + } } }; diff --git a/tests/HostTests/modules/TemplateStream.cpp b/tests/HostTests/modules/TemplateStream.cpp index 3f325130e7..36c725dd5a 100644 --- a/tests/HostTests/modules/TemplateStream.cpp +++ b/tests/HostTests/modules/TemplateStream.cpp @@ -3,7 +3,6 @@ #include #include #include -#include #ifdef ARCH_HOST #include @@ -23,12 +22,6 @@ DEFINE_FSTR_LOCAL(template3_1, "Document Title