Merge remote-tracking branch 'origin/main' into q-and-d-uvc
This commit is contained in:
commit
1c95a85ceb
115 changed files with 1989 additions and 695 deletions
|
|
@ -16,7 +16,7 @@ runs:
|
||||||
tar -xaf dosfstools-4.2.tar.gz
|
tar -xaf dosfstools-4.2.tar.gz
|
||||||
cd dosfstools-4.2
|
cd dosfstools-4.2
|
||||||
./configure
|
./configure
|
||||||
make -j 2
|
make -j4
|
||||||
cd src
|
cd src
|
||||||
echo >> $GITHUB_PATH $(pwd)
|
echo >> $GITHUB_PATH $(pwd)
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ runs:
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Cache IDF submodules
|
- name: Cache IDF submodules
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
.git/modules/ports/espressif/esp-idf
|
.git/modules/ports/espressif/esp-idf
|
||||||
|
|
@ -26,7 +26,7 @@ runs:
|
||||||
key: submodules-idf-${{ steps.idf-commit.outputs.commit }}
|
key: submodules-idf-${{ steps.idf-commit.outputs.commit }}
|
||||||
|
|
||||||
- name: Cache IDF tools
|
- name: Cache IDF tools
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: ${{ env.IDF_TOOLS_PATH }}
|
path: ${{ env.IDF_TOOLS_PATH }}
|
||||||
key: ${{ runner.os }}-${{ env.pythonLocation }}-tools-idf-${{ steps.idf-commit.outputs.commit }}
|
key: ${{ runner.os }}-${{ env.pythonLocation }}-tools-idf-${{ steps.idf-commit.outputs.commit }}
|
||||||
|
|
|
||||||
4
.github/actions/deps/python/action.yml
vendored
4
.github/actions/deps/python/action.yml
vendored
|
|
@ -16,7 +16,7 @@ runs:
|
||||||
- name: Cache python dependencies
|
- name: Cache python dependencies
|
||||||
id: cache-python-deps
|
id: cache-python-deps
|
||||||
if: inputs.action == 'cache'
|
if: inputs.action == 'cache'
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: .cp_tools
|
path: .cp_tools
|
||||||
key: ${{ runner.os }}-${{ env.pythonLocation }}-tools-cp-${{ hashFiles('requirements-dev.txt') }}
|
key: ${{ runner.os }}-${{ env.pythonLocation }}-tools-cp-${{ hashFiles('requirements-dev.txt') }}
|
||||||
|
|
@ -24,7 +24,7 @@ runs:
|
||||||
- name: Restore python dependencies
|
- name: Restore python dependencies
|
||||||
id: restore-python-deps
|
id: restore-python-deps
|
||||||
if: inputs.action == 'restore'
|
if: inputs.action == 'restore'
|
||||||
uses: actions/cache/restore@v3
|
uses: actions/cache/restore@v4
|
||||||
with:
|
with:
|
||||||
path: .cp_tools
|
path: .cp_tools
|
||||||
key: ${{ runner.os }}-${{ env.pythonLocation }}-tools-cp-${{ hashFiles('requirements-dev.txt') }}
|
key: ${{ runner.os }}-${{ env.pythonLocation }}-tools-cp-${{ hashFiles('requirements-dev.txt') }}
|
||||||
|
|
|
||||||
4
.github/actions/deps/submodules/action.yml
vendored
4
.github/actions/deps/submodules/action.yml
vendored
|
|
@ -48,7 +48,7 @@ runs:
|
||||||
|
|
||||||
- name: Cache submodules
|
- name: Cache submodules
|
||||||
if: ${{ inputs.action == 'cache' }}
|
if: ${{ inputs.action == 'cache' }}
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: ".git/modules/\n${{ join(fromJSON(steps.create-submodule-status.outputs.submodules), '\n') }}"
|
path: ".git/modules/\n${{ join(fromJSON(steps.create-submodule-status.outputs.submodules), '\n') }}"
|
||||||
key: submodules-common-${{ hashFiles('submodule_status') }}
|
key: submodules-common-${{ hashFiles('submodule_status') }}
|
||||||
|
|
@ -56,7 +56,7 @@ runs:
|
||||||
|
|
||||||
- name: Restore submodules
|
- name: Restore submodules
|
||||||
if: ${{ inputs.action == 'restore' }}
|
if: ${{ inputs.action == 'restore' }}
|
||||||
uses: actions/cache/restore@v3
|
uses: actions/cache/restore@v4
|
||||||
with:
|
with:
|
||||||
path: ".git/modules/\n${{ join(fromJSON(steps.create-submodule-status.outputs.submodules), '\n') }}"
|
path: ".git/modules/\n${{ join(fromJSON(steps.create-submodule-status.outputs.submodules), '\n') }}"
|
||||||
key: submodules-common-${{ hashFiles('submodule_status') }}
|
key: submodules-common-${{ hashFiles('submodule_status') }}
|
||||||
|
|
|
||||||
6
.github/actions/mpy_cross/action.yml
vendored
6
.github/actions/mpy_cross/action.yml
vendored
|
|
@ -16,7 +16,7 @@ runs:
|
||||||
id: download-mpy-cross
|
id: download-mpy-cross
|
||||||
if: inputs.download == 'true'
|
if: inputs.download == 'true'
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
uses: actions/download-artifact@v3
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: mpy-cross
|
name: mpy-cross
|
||||||
path: mpy-cross/build
|
path: mpy-cross/build
|
||||||
|
|
@ -28,7 +28,7 @@ runs:
|
||||||
|
|
||||||
- name: Build mpy-cross
|
- name: Build mpy-cross
|
||||||
if: inputs.download == 'false' || steps.download-mpy-cross.outcome == 'failure'
|
if: inputs.download == 'false' || steps.download-mpy-cross.outcome == 'failure'
|
||||||
run: make -C mpy-cross -j2
|
run: make -C mpy-cross -j4
|
||||||
shell: bash
|
shell: bash
|
||||||
env:
|
env:
|
||||||
CP_VERSION: ${{ inputs.cp-version }}
|
CP_VERSION: ${{ inputs.cp-version }}
|
||||||
|
|
@ -36,7 +36,7 @@ runs:
|
||||||
- name: Upload mpy-cross
|
- name: Upload mpy-cross
|
||||||
if: inputs.download == 'false' || steps.download-mpy-cross.outcome == 'failure'
|
if: inputs.download == 'false' || steps.download-mpy-cross.outcome == 'failure'
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: mpy-cross
|
name: mpy-cross
|
||||||
path: mpy-cross/build/mpy-cross
|
path: mpy-cross/build/mpy-cross
|
||||||
|
|
|
||||||
7
.github/workflows/build-boards.yml
vendored
7
.github/workflows/build-boards.yml
vendored
|
|
@ -26,12 +26,13 @@ jobs:
|
||||||
board: ${{ fromJSON(inputs.boards) }}
|
board: ${{ fromJSON(inputs.boards) }}
|
||||||
steps:
|
steps:
|
||||||
- name: Set up repository
|
- name: Set up repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: false
|
submodules: false
|
||||||
|
show-progress: false
|
||||||
fetch-depth: 1
|
fetch-depth: 1
|
||||||
- name: Set up python
|
- name: Set up python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
- name: Set up port
|
- name: Set up port
|
||||||
|
|
@ -75,7 +76,7 @@ jobs:
|
||||||
PULL: ${{ github.event.number }}
|
PULL: ${{ github.event.number }}
|
||||||
|
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: ${{ matrix.board }}
|
name: ${{ matrix.board }}
|
||||||
path: bin/${{ matrix.board }}
|
path: bin/${{ matrix.board }}
|
||||||
|
|
|
||||||
9
.github/workflows/build-mpy-cross.yml
vendored
9
.github/workflows/build-mpy-cross.yml
vendored
|
|
@ -28,12 +28,13 @@ jobs:
|
||||||
OS_static-raspbian: linux-raspbian
|
OS_static-raspbian: linux-raspbian
|
||||||
steps:
|
steps:
|
||||||
- name: Set up repository
|
- name: Set up repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: false
|
submodules: false
|
||||||
|
show-progress: false
|
||||||
fetch-depth: 1
|
fetch-depth: 1
|
||||||
- name: Set up python
|
- name: Set up python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
- name: Set up submodules
|
- name: Set up submodules
|
||||||
|
|
@ -53,7 +54,7 @@ jobs:
|
||||||
sudo apt-get install -y mingw-w64
|
sudo apt-get install -y mingw-w64
|
||||||
|
|
||||||
- name: Build mpy-cross.${{ matrix.mpy-cross }}
|
- name: Build mpy-cross.${{ matrix.mpy-cross }}
|
||||||
run: make -C mpy-cross -j2 -f Makefile.${{ matrix.mpy-cross }}
|
run: make -C mpy-cross -j4 -f Makefile.${{ matrix.mpy-cross }}
|
||||||
|
|
||||||
- name: Set output
|
- name: Set output
|
||||||
run: |
|
run: |
|
||||||
|
|
@ -61,7 +62,7 @@ jobs:
|
||||||
echo >> $GITHUB_ENV "OS=${{ env[format('OS_{0}', matrix.mpy-cross)] }}"
|
echo >> $GITHUB_ENV "OS=${{ env[format('OS_{0}', matrix.mpy-cross)] }}"
|
||||||
|
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: mpy-cross.${{ env.EX }}
|
name: mpy-cross.${{ env.EX }}
|
||||||
path: mpy-cross/build-${{ matrix.mpy-cross }}/mpy-cross.${{ env.EX }}
|
path: mpy-cross/build-${{ matrix.mpy-cross }}/mpy-cross.${{ env.EX }}
|
||||||
|
|
|
||||||
52
.github/workflows/build.yml
vendored
52
.github/workflows/build.yml
vendored
|
|
@ -28,12 +28,13 @@ jobs:
|
||||||
env:
|
env:
|
||||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||||
- name: Set up repository
|
- name: Set up repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: false
|
submodules: false
|
||||||
|
show-progress: false
|
||||||
fetch-depth: 1
|
fetch-depth: 1
|
||||||
- name: Set up python
|
- name: Set up python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
- name: Duplicate USB VID/PID check
|
- name: Duplicate USB VID/PID check
|
||||||
|
|
@ -108,12 +109,13 @@ jobs:
|
||||||
CP_VERSION: ${{ needs.scheduler.outputs.cp-version }}
|
CP_VERSION: ${{ needs.scheduler.outputs.cp-version }}
|
||||||
steps:
|
steps:
|
||||||
- name: Set up repository
|
- name: Set up repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: false
|
submodules: false
|
||||||
|
show-progress: false
|
||||||
fetch-depth: 1
|
fetch-depth: 1
|
||||||
- name: Set up python
|
- name: Set up python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
- name: Set up submodules
|
- name: Set up submodules
|
||||||
|
|
@ -124,21 +126,21 @@ jobs:
|
||||||
python3 --version
|
python3 --version
|
||||||
msgfmt --version
|
msgfmt --version
|
||||||
- name: Build mpy-cross
|
- name: Build mpy-cross
|
||||||
run: make -C mpy-cross -j2
|
run: make -C mpy-cross -j4
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: mpy-cross-macos-11-x64
|
name: mpy-cross-macos-11-x64
|
||||||
path: mpy-cross/build/mpy-cross
|
path: mpy-cross/build/mpy-cross
|
||||||
- name: Build mpy-cross (arm64)
|
- name: Build mpy-cross (arm64)
|
||||||
run: make -C mpy-cross -j2 -f Makefile.m1 V=2
|
run: make -C mpy-cross -j4 -f Makefile.m1 V=2
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: mpy-cross-macos-11-arm64
|
name: mpy-cross-macos-11-arm64
|
||||||
path: mpy-cross/build-arm64/mpy-cross-arm64
|
path: mpy-cross/build-arm64/mpy-cross-arm64
|
||||||
- name: Make universal binary
|
- name: Make universal binary
|
||||||
run: lipo -create -output mpy-cross-macos-universal mpy-cross/build/mpy-cross mpy-cross/build-arm64/mpy-cross-arm64
|
run: lipo -create -output mpy-cross-macos-universal mpy-cross/build/mpy-cross mpy-cross/build-arm64/mpy-cross-arm64
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: mpy-cross-macos-11-universal
|
name: mpy-cross-macos-11-universal
|
||||||
path: mpy-cross-macos-universal
|
path: mpy-cross-macos-universal
|
||||||
|
|
@ -163,12 +165,13 @@ jobs:
|
||||||
CP_VERSION: ${{ needs.scheduler.outputs.cp-version }}
|
CP_VERSION: ${{ needs.scheduler.outputs.cp-version }}
|
||||||
steps:
|
steps:
|
||||||
- name: Set up repository
|
- name: Set up repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: false
|
submodules: false
|
||||||
|
show-progress: false
|
||||||
fetch-depth: 1
|
fetch-depth: 1
|
||||||
- name: Set up python
|
- name: Set up python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
- name: Set up submodules
|
- name: Set up submodules
|
||||||
|
|
@ -179,23 +182,23 @@ jobs:
|
||||||
sudo apt-get install -y latexmk librsvg2-bin texlive-fonts-recommended texlive-latex-recommended texlive-latex-extra
|
sudo apt-get install -y latexmk librsvg2-bin texlive-fonts-recommended texlive-latex-recommended texlive-latex-extra
|
||||||
pip install -r requirements-doc.txt
|
pip install -r requirements-doc.txt
|
||||||
- name: Build and Validate Stubs
|
- name: Build and Validate Stubs
|
||||||
run: make check-stubs -j2
|
run: make check-stubs -j4
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: stubs
|
name: stubs
|
||||||
path: circuitpython-stubs/dist/*
|
path: circuitpython-stubs/dist/*
|
||||||
- name: Test Documentation Build (HTML)
|
- name: Test Documentation Build (HTML)
|
||||||
run: sphinx-build -E -W -b html -D version=${{ env.CP_VERSION }} -D release=${{ env.CP_VERSION }} . _build/html
|
run: sphinx-build -E -W -b html -D version=${{ env.CP_VERSION }} -D release=${{ env.CP_VERSION }} . _build/html
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: docs
|
name: docs-html
|
||||||
path: _build/html
|
path: _build/html
|
||||||
- name: Test Documentation Build (LaTeX/PDF)
|
- name: Test Documentation Build (LaTeX/PDF)
|
||||||
run: |
|
run: |
|
||||||
make latexpdf
|
make latexpdf
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: docs
|
name: docs-latexpdf
|
||||||
path: _build/latex
|
path: _build/latex
|
||||||
- name: Upload to S3
|
- name: Upload to S3
|
||||||
uses: ./.github/actions/upload_aws
|
uses: ./.github/actions/upload_aws
|
||||||
|
|
@ -260,24 +263,25 @@ jobs:
|
||||||
which python; python --version; python -c "import cascadetoml"
|
which python; python --version; python -c "import cascadetoml"
|
||||||
which python3; python3 --version; python3 -c "import cascadetoml"
|
which python3; python3 --version; python3 -c "import cascadetoml"
|
||||||
- name: Set up repository
|
- name: Set up repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: false
|
submodules: false
|
||||||
|
show-progress: false
|
||||||
fetch-depth: 1
|
fetch-depth: 1
|
||||||
- name: Set up submodules
|
- name: Set up submodules
|
||||||
uses: ./.github/actions/deps/submodules
|
uses: ./.github/actions/deps/submodules
|
||||||
- name: build mpy-cross
|
- name: build mpy-cross
|
||||||
run: make -j2 -C mpy-cross
|
run: make -j4 -C mpy-cross
|
||||||
- name: build rp2040
|
- name: build rp2040
|
||||||
run: make -j2 -C ports/raspberrypi BOARD=adafruit_feather_rp2040 TRANSLATION=de_DE
|
run: make -j4 -C ports/raspberrypi BOARD=adafruit_feather_rp2040 TRANSLATION=de_DE
|
||||||
- name: build samd21
|
- name: build samd21
|
||||||
run: make -j2 -C ports/atmel-samd BOARD=feather_m0_express TRANSLATION=zh_Latn_pinyin
|
run: make -j4 -C ports/atmel-samd BOARD=feather_m0_express TRANSLATION=zh_Latn_pinyin
|
||||||
- name: build samd51
|
- name: build samd51
|
||||||
run: make -j2 -C ports/atmel-samd BOARD=feather_m4_express TRANSLATION=es
|
run: make -j4 -C ports/atmel-samd BOARD=feather_m4_express TRANSLATION=es
|
||||||
- name: build nrf
|
- name: build nrf
|
||||||
run: make -j2 -C ports/nrf BOARD=feather_nrf52840_express TRANSLATION=fr
|
run: make -j4 -C ports/nrf BOARD=feather_nrf52840_express TRANSLATION=fr
|
||||||
- name: build stm
|
- name: build stm
|
||||||
run: make -j2 -C ports/stm BOARD=feather_stm32f405_express TRANSLATION=pt_BR
|
run: make -j4 -C ports/stm BOARD=feather_stm32f405_express TRANSLATION=pt_BR
|
||||||
# I gave up trying to do esp builds on windows when I saw
|
# I gave up trying to do esp builds on windows when I saw
|
||||||
# ERROR: Platform MINGW64_NT-10.0-17763-x86_64 appears to be unsupported
|
# ERROR: Platform MINGW64_NT-10.0-17763-x86_64 appears to be unsupported
|
||||||
# https://github.com/espressif/esp-idf/issues/7062
|
# https://github.com/espressif/esp-idf/issues/7062
|
||||||
|
|
|
||||||
5
.github/workflows/create-website-pr.yml
vendored
5
.github/workflows/create-website-pr.yml
vendored
|
|
@ -17,12 +17,13 @@ jobs:
|
||||||
env:
|
env:
|
||||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||||
- name: Set up repository
|
- name: Set up repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: false
|
submodules: false
|
||||||
|
show-progress: false
|
||||||
fetch-depth: 1
|
fetch-depth: 1
|
||||||
- name: Set up python
|
- name: Set up python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
- name: Set up submodules
|
- name: Set up submodules
|
||||||
|
|
|
||||||
6
.github/workflows/custom-board-build.yml
vendored
6
.github/workflows/custom-board-build.yml
vendored
|
|
@ -42,7 +42,7 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
> custom-build && git add custom-build
|
> custom-build && git add custom-build
|
||||||
- name: Set up python
|
- name: Set up python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
- name: Set up port
|
- name: Set up port
|
||||||
|
|
@ -81,10 +81,10 @@ jobs:
|
||||||
riscv64-unknown-elf-gcc --version || true
|
riscv64-unknown-elf-gcc --version || true
|
||||||
mkfs.fat --version || true
|
mkfs.fat --version || true
|
||||||
- name: Build board
|
- name: Build board
|
||||||
run: make -j2 ${{ inputs.flags }} BOARD=${{ inputs.board }} DEBUG=${{ inputs.debug && '1' || '0' }} TRANSLATION=${{ inputs.language }}
|
run: make -j4 ${{ inputs.flags }} BOARD=${{ inputs.board }} DEBUG=${{ inputs.debug && '1' || '0' }} TRANSLATION=${{ inputs.language }}
|
||||||
working-directory: ports/${{ steps.set-up-port.outputs.port }}
|
working-directory: ports/${{ steps.set-up-port.outputs.port }}
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: ${{ inputs.board }}-${{ inputs.language }}-${{ inputs.version }}${{ inputs.flags != '' && '-custom' || '' }}${{ inputs.debug && '-debug' || '' }}
|
name: ${{ inputs.board }}-${{ inputs.language }}-${{ inputs.version }}${{ inputs.flags != '' && '-custom' || '' }}${{ inputs.debug && '-debug' || '' }}
|
||||||
path: ports/${{ steps.set-up-port.outputs.port }}/build-${{ inputs.board }}/firmware.*
|
path: ports/${{ steps.set-up-port.outputs.port }}/build-${{ inputs.board }}/firmware.*
|
||||||
|
|
|
||||||
7
.github/workflows/pre-commit.yml
vendored
7
.github/workflows/pre-commit.yml
vendored
|
|
@ -17,12 +17,13 @@ jobs:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- name: Set up repository
|
- name: Set up repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: false
|
submodules: false
|
||||||
|
show-progress: false
|
||||||
fetch-depth: 1
|
fetch-depth: 1
|
||||||
- name: Set up python
|
- name: Set up python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
- name: Set up submodules
|
- name: Set up submodules
|
||||||
|
|
@ -40,7 +41,7 @@ jobs:
|
||||||
run: git diff > ~/pre-commit.patch
|
run: git diff > ~/pre-commit.patch
|
||||||
- name: Upload patch
|
- name: Upload patch
|
||||||
if: failure()
|
if: failure()
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: patch
|
name: patch
|
||||||
path: ~/pre-commit.patch
|
path: ~/pre-commit.patch
|
||||||
|
|
|
||||||
11
.github/workflows/run-tests.yml
vendored
11
.github/workflows/run-tests.yml
vendored
|
|
@ -24,12 +24,13 @@ jobs:
|
||||||
TEST_native_mpy: --via-mpy --emit native -d basics float micropython
|
TEST_native_mpy: --via-mpy --emit native -d basics float micropython
|
||||||
steps:
|
steps:
|
||||||
- name: Set up repository
|
- name: Set up repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: false
|
submodules: false
|
||||||
|
show-progress: false
|
||||||
fetch-depth: 1
|
fetch-depth: 1
|
||||||
- name: Set up python
|
- name: Set up python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: 3.8
|
python-version: 3.8
|
||||||
- name: Set up submodules
|
- name: Set up submodules
|
||||||
|
|
@ -44,12 +45,12 @@ jobs:
|
||||||
with:
|
with:
|
||||||
cp-version: ${{ inputs.cp-version }}
|
cp-version: ${{ inputs.cp-version }}
|
||||||
- name: Build unix port
|
- name: Build unix port
|
||||||
run: make -C ports/unix VARIANT=coverage -j2
|
run: make -C ports/unix VARIANT=coverage -j4
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: ./run-tests.py -j2 ${{ env[format('TEST_{0}', matrix.test)] }}
|
run: ./run-tests.py -j4 ${{ env[format('TEST_{0}', matrix.test)] }}
|
||||||
working-directory: tests
|
working-directory: tests
|
||||||
- name: Print failure info
|
- name: Print failure info
|
||||||
run: ./run-tests.py -j2 --print-failures
|
run: ./run-tests.py -j4 --print-failures
|
||||||
if: failure()
|
if: failure()
|
||||||
working-directory: tests
|
working-directory: tests
|
||||||
- name: Build native modules
|
- name: Build native modules
|
||||||
|
|
|
||||||
|
|
@ -52,27 +52,9 @@ SRC_QSTR += $(SRC_C) $(SRC_BINDINGS_EXPANDED) $(STM_SRC_C)
|
||||||
The `Makefile` defines the modules to build and adds the sources to include the `shared-bindings` version and the `common-hal` version within the port specific directory. You may comment out certain subfolders to reduce the number of modules to add but don't comment out individual classes. It won't compile then.
|
The `Makefile` defines the modules to build and adds the sources to include the `shared-bindings` version and the `common-hal` version within the port specific directory. You may comment out certain subfolders to reduce the number of modules to add but don't comment out individual classes. It won't compile then.
|
||||||
|
|
||||||
### Hooking the modules in
|
### Hooking the modules in
|
||||||
Built in modules are typically defined in `mpconfigport.h`. To add support you should have something like:
|
Modules are registered by the macro `MP_REGISTER_MODULE` from `py/obj.h`. The macro takes two arguments: the module name as a QSTR and the module object itself. The `board` module is registered like so:
|
||||||
|
```py
|
||||||
```
|
MP_REGISTER_MODULE(MP_QSTR_board, board_module);
|
||||||
extern const struct _mp_obj_module_t microcontroller_module;
|
|
||||||
extern const struct _mp_obj_module_t analogio_module;
|
|
||||||
extern const struct _mp_obj_module_t digitalio_module;
|
|
||||||
extern const struct _mp_obj_module_t pulseio_module;
|
|
||||||
extern const struct _mp_obj_module_t busio_module;
|
|
||||||
extern const struct _mp_obj_module_t board_module;
|
|
||||||
extern const struct _mp_obj_module_t time_module;
|
|
||||||
extern const struct _mp_obj_module_t neopixel_write_module;
|
|
||||||
|
|
||||||
#define MICROPY_PORT_BUILTIN_MODULES \
|
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_microcontroller), (mp_obj_t)µcontroller_module }, \
|
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_analogio), (mp_obj_t)&analogio_module }, \
|
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_digitalio), (mp_obj_t)&digitalio_module }, \
|
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_pulseio), (mp_obj_t)&pulseio_module }, \
|
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_busio), (mp_obj_t)&busio_module }, \
|
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_board), (mp_obj_t)&board_module }, \
|
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, \
|
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_neopixel_write),(mp_obj_t)&neopixel_write_module } \
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Implementing the Common HAL
|
### Implementing the Common HAL
|
||||||
|
|
|
||||||
|
|
@ -173,6 +173,11 @@ def get_settings_from_makefile(port_dir, board_name):
|
||||||
|
|
||||||
This list must explicitly include any setting queried by tools/ci_set_matrix.py.
|
This list must explicitly include any setting queried by tools/ci_set_matrix.py.
|
||||||
"""
|
"""
|
||||||
|
if os.getenv('NO_BINDINGS_MATRIX'):
|
||||||
|
return {
|
||||||
|
'CIRCUITPY_BUILD_EXTENSIONS': '.bin'
|
||||||
|
}
|
||||||
|
|
||||||
contents = subprocess.run(
|
contents = subprocess.run(
|
||||||
["make", "-C", port_dir, "-f", "Makefile", f"BOARD={board_name}", "print-CFLAGS", "print-CIRCUITPY_BUILD_EXTENSIONS", "print-FROZEN_MPY_DIRS", "print-SRC_PATTERNS", "print-SRC_SUPERVISOR"],
|
["make", "-C", port_dir, "-f", "Makefile", f"BOARD={board_name}", "print-CFLAGS", "print-CIRCUITPY_BUILD_EXTENSIONS", "print-FROZEN_MPY_DIRS", "print-SRC_PATTERNS", "print-SRC_SUPERVISOR"],
|
||||||
encoding="utf-8",
|
encoding="utf-8",
|
||||||
|
|
|
||||||
|
|
@ -165,6 +165,13 @@ Returns a JSON representation of the directory.
|
||||||
* `403 Forbidden` - No `CIRCUITPY_WEB_API_PASSWORD` set
|
* `403 Forbidden` - No `CIRCUITPY_WEB_API_PASSWORD` set
|
||||||
* `404 Not Found` - Missing directory
|
* `404 Not Found` - Missing directory
|
||||||
|
|
||||||
|
Returns directory information:
|
||||||
|
* `free`: Count of free blocks on the disk holding this directory.
|
||||||
|
* `total`: Total blocks that make up the disk holding this directory.
|
||||||
|
* `block_size`: Size of a block in bytes.
|
||||||
|
* `writable`: True when CircuitPython and the web workflow can write to the disk. USB may claim a disk instead.
|
||||||
|
* `files`: Array of objects. One for each file.
|
||||||
|
|
||||||
Returns information about each file in the directory:
|
Returns information about each file in the directory:
|
||||||
|
|
||||||
* `name` - File name. No trailing `/` on directory names
|
* `name` - File name. No trailing `/` on directory names
|
||||||
|
|
@ -179,7 +186,12 @@ curl -v -u :passw0rd -H "Accept: application/json" -L --location-trusted http://
|
||||||
```
|
```
|
||||||
|
|
||||||
```json
|
```json
|
||||||
[
|
{
|
||||||
|
"free": 451623,
|
||||||
|
"total": 973344,
|
||||||
|
"block_size": 32768,
|
||||||
|
"writable": true,
|
||||||
|
"files": [
|
||||||
{
|
{
|
||||||
"name": "world.txt",
|
"name": "world.txt",
|
||||||
"directory": false,
|
"directory": false,
|
||||||
|
|
@ -187,6 +199,7 @@ curl -v -u :passw0rd -H "Accept: application/json" -L --location-trusted http://
|
||||||
"file_size": 12
|
"file_size": 12
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
##### PUT
|
##### PUT
|
||||||
|
|
@ -196,7 +209,7 @@ time resolution) used for the directories modification time. The RTC time will u
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
* `204 No Content` - Directory exists
|
* `204 No Content` - Directory or file exists
|
||||||
* `201 Created` - Directory created
|
* `201 Created` - Directory created
|
||||||
* `401 Unauthorized` - Incorrect password
|
* `401 Unauthorized` - Incorrect password
|
||||||
* `403 Forbidden` - No `CIRCUITPY_WEB_API_PASSWORD` set
|
* `403 Forbidden` - No `CIRCUITPY_WEB_API_PASSWORD` set
|
||||||
|
|
@ -373,10 +386,10 @@ curl -v -L http://circuitpython.local/cp/devices.json
|
||||||
Returns information about the attached disk(s). A list of objects, one per disk.
|
Returns information about the attached disk(s). A list of objects, one per disk.
|
||||||
|
|
||||||
* `root`: Filesystem path to the root of the disk.
|
* `root`: Filesystem path to the root of the disk.
|
||||||
* `free`: Count of free bytes on the disk.
|
* `free`: Count of free blocks on the disk.
|
||||||
|
* `total`: Total blocks that make up the disk.
|
||||||
* `block_size`: Size of a block in bytes.
|
* `block_size`: Size of a block in bytes.
|
||||||
* `writable`: True when CircuitPython and the web workflow can write to the disk. USB may claim a disk instead.
|
* `writable`: True when CircuitPython and the web workflow can write to the disk. USB may claim a disk instead.
|
||||||
* `total`: Total bytes that make up the disk.
|
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
```sh
|
```sh
|
||||||
|
|
@ -405,7 +418,7 @@ This is an authenticated endpoint in both modes.
|
||||||
|
|
||||||
Returns information about the device.
|
Returns information about the device.
|
||||||
|
|
||||||
* `web_api_version`: Between `1` and `3`. This versions the rest of the API and new versions may not be backwards compatible. See below for more info.
|
* `web_api_version`: Between `1` and `4`. This versions the rest of the API and new versions may not be backwards compatible. See below for more info.
|
||||||
* `version`: CircuitPython build version.
|
* `version`: CircuitPython build version.
|
||||||
* `build_date`: CircuitPython build date.
|
* `build_date`: CircuitPython build date.
|
||||||
* `board_name`: Human readable name of the board.
|
* `board_name`: Human readable name of the board.
|
||||||
|
|
@ -467,3 +480,5 @@ Only one WebSocket at a time is supported.
|
||||||
* `1` - Initial version.
|
* `1` - Initial version.
|
||||||
* `2` - Added `/cp/diskinfo.json`.
|
* `2` - Added `/cp/diskinfo.json`.
|
||||||
* `3` - Changed `/cp/diskinfo.json` to return a list in preparation for multi-disk support.
|
* `3` - Changed `/cp/diskinfo.json` to return a list in preparation for multi-disk support.
|
||||||
|
* `4` - Changed directory json to an object with additional data. File list is under `files` and is
|
||||||
|
the same as the old format.
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,8 @@
|
||||||
#define MP_BLOCKDEV_FLAG_USB_WRITABLE (0x0010)
|
#define MP_BLOCKDEV_FLAG_USB_WRITABLE (0x0010)
|
||||||
// Bit set when the above flag is checked before opening a file for write.
|
// Bit set when the above flag is checked before opening a file for write.
|
||||||
#define MP_BLOCKDEV_FLAG_CONCURRENT_WRITE_PROTECTED (0x0020)
|
#define MP_BLOCKDEV_FLAG_CONCURRENT_WRITE_PROTECTED (0x0020)
|
||||||
|
// Bit set when something has claimed the right to mutate the blockdev.
|
||||||
|
#define MP_BLOCKDEV_FLAG_LOCKED (0x0040)
|
||||||
|
|
||||||
// constants for block protocol ioctl
|
// constants for block protocol ioctl
|
||||||
#define MP_BLOCKDEV_IOCTL_INIT (1)
|
#define MP_BLOCKDEV_IOCTL_INIT (1)
|
||||||
|
|
|
||||||
|
|
@ -30,12 +30,41 @@
|
||||||
#include "py/mperrno.h"
|
#include "py/mperrno.h"
|
||||||
#include "extmod/vfs.h"
|
#include "extmod/vfs.h"
|
||||||
|
|
||||||
|
#if CIRCUITPY_SDCARDIO
|
||||||
|
#include "shared-bindings/sdcardio/SDCard.h"
|
||||||
|
#endif
|
||||||
|
#if CIRCUITPY_SDIOIO
|
||||||
|
#include "shared-bindings/sdioio/SDCard.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if MICROPY_VFS
|
#if MICROPY_VFS
|
||||||
|
|
||||||
void mp_vfs_blockdev_init(mp_vfs_blockdev_t *self, mp_obj_t bdev) {
|
void mp_vfs_blockdev_init(mp_vfs_blockdev_t *self, mp_obj_t bdev) {
|
||||||
mp_load_method(bdev, MP_QSTR_readblocks, self->readblocks);
|
mp_load_method(bdev, MP_QSTR_readblocks, self->readblocks);
|
||||||
mp_load_method_maybe(bdev, MP_QSTR_writeblocks, self->writeblocks);
|
mp_load_method_maybe(bdev, MP_QSTR_writeblocks, self->writeblocks);
|
||||||
mp_load_method_maybe(bdev, MP_QSTR_ioctl, self->u.ioctl);
|
mp_load_method_maybe(bdev, MP_QSTR_ioctl, self->u.ioctl);
|
||||||
|
|
||||||
|
// CIRCUITPY-CHANGE: Support native SD cards.
|
||||||
|
#if CIRCUITPY_SDCARDIO
|
||||||
|
if (mp_obj_get_type(bdev) == &sdcardio_SDCard_type) {
|
||||||
|
self->flags |= MP_BLOCKDEV_FLAG_NATIVE | MP_BLOCKDEV_FLAG_HAVE_IOCTL;
|
||||||
|
self->readblocks[0] = mp_const_none;
|
||||||
|
self->readblocks[1] = bdev;
|
||||||
|
self->readblocks[2] = (mp_obj_t)sdcardio_sdcard_readblocks; // native version
|
||||||
|
self->writeblocks[0] = mp_const_none;
|
||||||
|
self->writeblocks[1] = bdev;
|
||||||
|
self->writeblocks[2] = (mp_obj_t)sdcardio_sdcard_writeblocks; // native version
|
||||||
|
self->u.ioctl[0] = mp_const_none;
|
||||||
|
self->u.ioctl[1] = bdev;
|
||||||
|
self->u.ioctl[2] = (mp_obj_t)sdcardio_sdcard_ioctl; // native version
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if CIRCUITPY_SDIOIO
|
||||||
|
if (mp_obj_get_type(bdev) == &sdioio_SDCard_type) {
|
||||||
|
// TODO: Enable native blockdev for SDIO too.
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (self->u.ioctl[0] != MP_OBJ_NULL) {
|
if (self->u.ioctl[0] != MP_OBJ_NULL) {
|
||||||
// Device supports new block protocol, so indicate it
|
// Device supports new block protocol, so indicate it
|
||||||
self->flags |= MP_BLOCKDEV_FLAG_HAVE_IOCTL;
|
self->flags |= MP_BLOCKDEV_FLAG_HAVE_IOCTL;
|
||||||
|
|
@ -48,8 +77,10 @@ void mp_vfs_blockdev_init(mp_vfs_blockdev_t *self, mp_obj_t bdev) {
|
||||||
|
|
||||||
int mp_vfs_blockdev_read(mp_vfs_blockdev_t *self, size_t block_num, size_t num_blocks, uint8_t *buf) {
|
int mp_vfs_blockdev_read(mp_vfs_blockdev_t *self, size_t block_num, size_t num_blocks, uint8_t *buf) {
|
||||||
if (self->flags & MP_BLOCKDEV_FLAG_NATIVE) {
|
if (self->flags & MP_BLOCKDEV_FLAG_NATIVE) {
|
||||||
mp_uint_t (*f)(uint8_t *, uint32_t, uint32_t) = (void *)(uintptr_t)self->readblocks[2];
|
// CIRCUITPY-CHANGE: Pass the blockdev object into native readblocks so
|
||||||
return f(buf, block_num, num_blocks);
|
// it has the corresponding state.
|
||||||
|
mp_uint_t (*f)(mp_obj_t self, uint8_t *, uint32_t, uint32_t) = (void *)(uintptr_t)self->readblocks[2];
|
||||||
|
return f(self->readblocks[1], buf, block_num, num_blocks);
|
||||||
} else {
|
} else {
|
||||||
mp_obj_array_t ar = {{&mp_type_bytearray}, BYTEARRAY_TYPECODE, 0, num_blocks *self->block_size, buf};
|
mp_obj_array_t ar = {{&mp_type_bytearray}, BYTEARRAY_TYPECODE, 0, num_blocks *self->block_size, buf};
|
||||||
self->readblocks[2] = MP_OBJ_NEW_SMALL_INT(block_num);
|
self->readblocks[2] = MP_OBJ_NEW_SMALL_INT(block_num);
|
||||||
|
|
@ -80,8 +111,10 @@ int mp_vfs_blockdev_write(mp_vfs_blockdev_t *self, size_t block_num, size_t num_
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->flags & MP_BLOCKDEV_FLAG_NATIVE) {
|
if (self->flags & MP_BLOCKDEV_FLAG_NATIVE) {
|
||||||
mp_uint_t (*f)(const uint8_t *, uint32_t, uint32_t) = (void *)(uintptr_t)self->writeblocks[2];
|
// CIRCUITPY-CHANGE: Pass the blockdev object into native readblocks so
|
||||||
return f(buf, block_num, num_blocks);
|
// it has the corresponding state.
|
||||||
|
mp_uint_t (*f)(mp_obj_t self, const uint8_t *, uint32_t, uint32_t) = (void *)(uintptr_t)self->writeblocks[2];
|
||||||
|
return f(self->writeblocks[1], buf, block_num, num_blocks);
|
||||||
} else {
|
} else {
|
||||||
mp_obj_array_t ar = {{&mp_type_bytearray}, BYTEARRAY_TYPECODE, 0, num_blocks *self->block_size, (void *)buf};
|
mp_obj_array_t ar = {{&mp_type_bytearray}, BYTEARRAY_TYPECODE, 0, num_blocks *self->block_size, (void *)buf};
|
||||||
self->writeblocks[2] = MP_OBJ_NEW_SMALL_INT(block_num);
|
self->writeblocks[2] = MP_OBJ_NEW_SMALL_INT(block_num);
|
||||||
|
|
@ -112,6 +145,16 @@ int mp_vfs_blockdev_write_ext(mp_vfs_blockdev_t *self, size_t block_num, size_t
|
||||||
|
|
||||||
mp_obj_t mp_vfs_blockdev_ioctl(mp_vfs_blockdev_t *self, uintptr_t cmd, uintptr_t arg) {
|
mp_obj_t mp_vfs_blockdev_ioctl(mp_vfs_blockdev_t *self, uintptr_t cmd, uintptr_t arg) {
|
||||||
if (self->flags & MP_BLOCKDEV_FLAG_HAVE_IOCTL) {
|
if (self->flags & MP_BLOCKDEV_FLAG_HAVE_IOCTL) {
|
||||||
|
// CIRCUITPY-CHANGE: Support native IOCTL so it can run outside of the VM.
|
||||||
|
if (self->flags & MP_BLOCKDEV_FLAG_NATIVE) {
|
||||||
|
size_t out_value;
|
||||||
|
bool (*f)(mp_obj_t self, uint32_t, uint32_t, size_t *) = (void *)(uintptr_t)self->u.ioctl[2];
|
||||||
|
bool b = f(self->u.ioctl[1], cmd, arg, &out_value);
|
||||||
|
if (!b) {
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
return MP_OBJ_NEW_SMALL_INT(out_value);
|
||||||
|
}
|
||||||
// New protocol with ioctl
|
// New protocol with ioctl
|
||||||
self->u.ioctl[2] = MP_OBJ_NEW_SMALL_INT(cmd);
|
self->u.ioctl[2] = MP_OBJ_NEW_SMALL_INT(cmd);
|
||||||
self->u.ioctl[3] = MP_OBJ_NEW_SMALL_INT(arg);
|
self->u.ioctl[3] = MP_OBJ_NEW_SMALL_INT(arg);
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,10 @@ typedef struct _fs_user_mount_t {
|
||||||
mp_obj_base_t base;
|
mp_obj_base_t base;
|
||||||
mp_vfs_blockdev_t blockdev;
|
mp_vfs_blockdev_t blockdev;
|
||||||
FATFS fatfs;
|
FATFS fatfs;
|
||||||
|
|
||||||
|
// CIRCUITPY-CHANGE: Count the users that are manipulating the blockdev via
|
||||||
|
// native fatfs so we can lock and unlock the blockdev.
|
||||||
|
int8_t lock_count;
|
||||||
} fs_user_mount_t;
|
} fs_user_mount_t;
|
||||||
|
|
||||||
extern const byte fresult_to_errno_table[20];
|
extern const byte fresult_to_errno_table[20];
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 267219f161d002e7a724859e01d000a88dc08683
|
Subproject commit 76dd808fa4a8bc5c20fa2660d3b45ce9b33e2be6
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit f975229b3f0182e7ea857446ca610dee6e54cc95
|
Subproject commit f90a7cbccfd698f6c2fb36bf787295bcf9ddb910
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 1f35b4a552045bd1a216507b17833960364dce2c
|
Subproject commit 0adb75b898a133d929eb14baa2e54b7e9e23899c
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 4754bf3e5fdb559be9ea085bfb65bd435039e887
|
Subproject commit 178dbc30ff660fb93dc8fd8d1c193a00067398e4
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 8efd9f76ceaeae0fc43892108ff71335b8da1888
|
Subproject commit 5417f6225fb0573853972852ebdfa3aa080fed93
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 3203fbaea4f6ebc97ff7c3a1dc8dfaa899ff6216
|
Subproject commit b9c8eedd7b2c7e657ebb8195dde7a6190ae9b866
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit db3b03c4c68a4d4d32a3d145f6fad8935a89a345
|
Subproject commit 7469b5fd5e24b856f01d59a03eed1c8e7049f0d9
|
||||||
|
|
@ -207,7 +207,8 @@ msgid "%q must be multiple of 8."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c
|
#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c
|
||||||
#: shared-bindings/canio/CAN.c shared-bindings/digitalio/Pull.c
|
#: shared-bindings/bitmapfilter/__init__.c shared-bindings/canio/CAN.c
|
||||||
|
#: shared-bindings/digitalio/Pull.c shared-bindings/supervisor/__init__.c
|
||||||
#: shared-module/synthio/Synthesizer.c
|
#: shared-module/synthio/Synthesizer.c
|
||||||
msgid "%q must be of type %q or %q, not %q"
|
msgid "%q must be of type %q or %q, not %q"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -216,7 +217,7 @@ msgstr ""
|
||||||
msgid "%q must be of type %q, %q, or %q, not %q"
|
msgid "%q must be of type %q, %q, or %q, not %q"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c shared-bindings/bitmapfilter/__init__.c
|
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
||||||
#: shared-module/synthio/__init__.c
|
#: shared-module/synthio/__init__.c
|
||||||
msgid "%q must be of type %q, not %q"
|
msgid "%q must be of type %q, not %q"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -234,7 +235,7 @@ msgstr ""
|
||||||
#: ports/nrf/common-hal/pulseio/PulseIn.c
|
#: ports/nrf/common-hal/pulseio/PulseIn.c
|
||||||
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
|
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
|
||||||
#: ports/stm/common-hal/pulseio/PulseIn.c py/argcheck.c
|
#: ports/stm/common-hal/pulseio/PulseIn.c py/argcheck.c
|
||||||
#: shared-bindings/canio/Match.c
|
#: shared-bindings/canio/Match.c shared-bindings/time/__init__.c
|
||||||
msgid "%q out of range"
|
msgid "%q out of range"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
@ -498,7 +499,6 @@ msgstr ""
|
||||||
#: ports/nrf/common-hal/countio/Counter.c
|
#: ports/nrf/common-hal/countio/Counter.c
|
||||||
#: ports/nrf/common-hal/pulseio/PulseIn.c
|
#: ports/nrf/common-hal/pulseio/PulseIn.c
|
||||||
#: ports/nrf/common-hal/rotaryio/IncrementalEncoder.c
|
#: ports/nrf/common-hal/rotaryio/IncrementalEncoder.c
|
||||||
#: shared-bindings/pwmio/PWMOut.c
|
|
||||||
msgid "All channels in use"
|
msgid "All channels in use"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
@ -521,13 +521,11 @@ msgid "All sync event channels in use"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ports/raspberrypi/common-hal/picodvi/Framebuffer.c
|
#: ports/raspberrypi/common-hal/picodvi/Framebuffer.c
|
||||||
#: shared-bindings/pwmio/PWMOut.c
|
|
||||||
msgid "All timers for this pin are in use"
|
msgid "All timers for this pin are in use"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ports/atmel-samd/common-hal/_pew/PewPew.c
|
#: ports/atmel-samd/common-hal/_pew/PewPew.c
|
||||||
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
|
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
|
||||||
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
|
|
||||||
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
|
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
|
||||||
#: ports/atmel-samd/common-hal/pulseio/PulseOut.c
|
#: ports/atmel-samd/common-hal/pulseio/PulseOut.c
|
||||||
#: ports/cxd56/common-hal/pulseio/PulseOut.c
|
#: ports/cxd56/common-hal/pulseio/PulseOut.c
|
||||||
|
|
@ -538,7 +536,7 @@ msgstr ""
|
||||||
#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
|
#: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c
|
||||||
#: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c
|
#: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c
|
||||||
#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c
|
#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c
|
||||||
#: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c
|
#: ports/stm/peripherals/timers.c
|
||||||
msgid "All timers in use"
|
msgid "All timers in use"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
@ -778,12 +776,6 @@ msgstr ""
|
||||||
msgid "Cannot remount '/' when visible via USB."
|
msgid "Cannot remount '/' when visible via USB."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ports/atmel-samd/common-hal/microcontroller/__init__.c
|
|
||||||
#: ports/cxd56/common-hal/microcontroller/__init__.c
|
|
||||||
#: ports/mimxrt10xx/common-hal/microcontroller/__init__.c
|
|
||||||
msgid "Cannot reset into bootloader because no bootloader is present"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: ports/espressif/common-hal/socketpool/Socket.c
|
#: ports/espressif/common-hal/socketpool/Socket.c
|
||||||
msgid "Cannot set socket options"
|
msgid "Cannot set socket options"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -801,10 +793,6 @@ msgstr ""
|
||||||
msgid "Cannot subclass slice"
|
msgid "Cannot subclass slice"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: shared-bindings/pwmio/PWMOut.c
|
|
||||||
msgid "Cannot vary frequency on a timer that is already in use"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: ports/nrf/common-hal/alarm/pin/PinAlarm.c
|
#: ports/nrf/common-hal/alarm/pin/PinAlarm.c
|
||||||
msgid "Cannot wake on pin edge, only level"
|
msgid "Cannot wake on pin edge, only level"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -847,10 +835,6 @@ msgstr ""
|
||||||
msgid "Could not set address"
|
msgid "Could not set address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: shared-bindings/pwmio/PWMOut.c
|
|
||||||
msgid "Could not start PWM"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: ports/stm/common-hal/busio/UART.c
|
#: ports/stm/common-hal/busio/UART.c
|
||||||
msgid "Could not start interrupt, RX busy"
|
msgid "Could not start interrupt, RX busy"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -942,16 +926,6 @@ msgstr ""
|
||||||
msgid "ESP-IDF memory allocation failed"
|
msgid "ESP-IDF memory allocation failed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c
|
|
||||||
#: ports/atmel-samd/common-hal/countio/Counter.c
|
|
||||||
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
|
|
||||||
#: ports/atmel-samd/common-hal/ps2io/Ps2.c
|
|
||||||
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
|
|
||||||
#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c
|
|
||||||
#: ports/cxd56/common-hal/pulseio/PulseIn.c
|
|
||||||
msgid "EXTINT channel already in use"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: extmod/modre.c
|
#: extmod/modre.c
|
||||||
msgid "Error in regex"
|
msgid "Error in regex"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -1084,10 +1058,6 @@ msgid ""
|
||||||
"Frequency must be 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 or 1008 Mhz"
|
"Frequency must be 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 or 1008 Mhz"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: shared-bindings/pwmio/PWMOut.c
|
|
||||||
msgid "Frequency must match existing PWMOut using this timer"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: shared-bindings/bitbangio/I2C.c shared-bindings/bitbangio/SPI.c
|
#: shared-bindings/bitbangio/I2C.c shared-bindings/bitbangio/SPI.c
|
||||||
#: shared-bindings/busio/I2C.c shared-bindings/busio/SPI.c
|
#: shared-bindings/busio/I2C.c shared-bindings/busio/SPI.c
|
||||||
msgid "Function requires lock"
|
msgid "Function requires lock"
|
||||||
|
|
@ -1122,11 +1092,6 @@ msgstr ""
|
||||||
msgid "Heap allocation when VM not running."
|
msgid "Heap allocation when VM not running."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: supervisor/shared/safe_mode.c
|
|
||||||
msgid ""
|
|
||||||
"Heap was corrupted because the stack was too small. Increase stack size."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: extmod/vfs_posix_file.c py/objstringio.c
|
#: extmod/vfs_posix_file.c py/objstringio.c
|
||||||
msgid "I/O operation on closed file"
|
msgid "I/O operation on closed file"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -1202,7 +1167,7 @@ msgid "Internal define error"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c
|
#: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c
|
||||||
#: shared-module/os/getenv.c
|
#: shared-bindings/pwmio/PWMOut.c shared-module/os/getenv.c
|
||||||
msgid "Internal error"
|
msgid "Internal error"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
@ -1211,6 +1176,16 @@ msgstr ""
|
||||||
msgid "Internal error #%d"
|
msgid "Internal error #%d"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c
|
||||||
|
#: ports/atmel-samd/common-hal/countio/Counter.c
|
||||||
|
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
|
||||||
|
#: ports/atmel-samd/common-hal/ps2io/Ps2.c
|
||||||
|
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
|
||||||
|
#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c
|
||||||
|
#: ports/cxd56/common-hal/pulseio/PulseIn.c shared-bindings/pwmio/PWMOut.c
|
||||||
|
msgid "Internal resource(s) in use"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: supervisor/shared/safe_mode.c
|
#: supervisor/shared/safe_mode.c
|
||||||
msgid "Internal watchdog timer expired."
|
msgid "Internal watchdog timer expired."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -1228,7 +1203,7 @@ msgstr ""
|
||||||
#: ports/raspberrypi/bindings/picodvi/Framebuffer.c
|
#: ports/raspberrypi/bindings/picodvi/Framebuffer.c
|
||||||
#: ports/raspberrypi/common-hal/picodvi/Framebuffer.c py/argcheck.c
|
#: ports/raspberrypi/common-hal/picodvi/Framebuffer.c py/argcheck.c
|
||||||
#: shared-bindings/digitalio/DigitalInOut.c
|
#: shared-bindings/digitalio/DigitalInOut.c
|
||||||
#: shared-bindings/epaperdisplay/EPaperDisplay.c
|
#: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c
|
||||||
msgid "Invalid %q"
|
msgid "Invalid %q"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
@ -1376,6 +1351,10 @@ msgstr ""
|
||||||
msgid "Missing jmp_pin. %q[%u] jumps on pin"
|
msgid "Missing jmp_pin. %q[%u] jumps on pin"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: shared-module/storage/__init__.c
|
||||||
|
msgid "Mount point directory missing"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c
|
#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c
|
||||||
msgid "Must be a %q subclass."
|
msgid "Must be a %q subclass."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -1460,8 +1439,10 @@ msgstr ""
|
||||||
msgid "No IP"
|
msgid "No IP"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
|
#: ports/atmel-samd/common-hal/microcontroller/__init__.c
|
||||||
msgid "No available clocks"
|
#: ports/cxd56/common-hal/microcontroller/__init__.c
|
||||||
|
#: ports/mimxrt10xx/common-hal/microcontroller/__init__.c
|
||||||
|
msgid "No bootloader present"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ports/espressif/common-hal/imagecapture/ParallelImageCapture.c
|
#: ports/espressif/common-hal/imagecapture/ParallelImageCapture.c
|
||||||
|
|
@ -1480,15 +1461,12 @@ msgstr ""
|
||||||
msgid "No default %q bus"
|
msgid "No default %q bus"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
|
||||||
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
|
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
|
||||||
#: ports/atmel-samd/common-hal/touchio/TouchIn.c
|
#: ports/atmel-samd/common-hal/touchio/TouchIn.c
|
||||||
msgid "No free GCLKs"
|
msgid "No free GCLKs"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
|
|
||||||
msgid "No free GLCKs"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: shared-bindings/os/__init__.c
|
#: shared-bindings/os/__init__.c
|
||||||
msgid "No hardware random available"
|
msgid "No hardware random available"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -1687,11 +1665,6 @@ msgstr ""
|
||||||
msgid "Out-buffer elements must be <= 4 bytes long"
|
msgid "Out-buffer elements must be <= 4 bytes long"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: shared-bindings/pwmio/PWMOut.c
|
|
||||||
msgid ""
|
|
||||||
"PWM frequency not writable when variable_frequency is False on construction."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: ports/stm/common-hal/pwmio/PWMOut.c
|
#: ports/stm/common-hal/pwmio/PWMOut.c
|
||||||
msgid "PWM restart"
|
msgid "PWM restart"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -1737,11 +1710,6 @@ msgstr ""
|
||||||
msgid "Pin must be on PWM Channel B"
|
msgid "Pin must be on PWM Channel B"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ports/atmel-samd/common-hal/countio/Counter.c
|
|
||||||
#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c
|
|
||||||
msgid "Pin must support hardware interrupts"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: shared-bindings/rgbmatrix/RGBMatrix.c
|
#: shared-bindings/rgbmatrix/RGBMatrix.c
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
|
|
@ -1972,6 +1940,10 @@ msgstr ""
|
||||||
msgid "Specify exactly one of data0 or data_pins"
|
msgid "Specify exactly one of data0 or data_pins"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: supervisor/shared/safe_mode.c
|
||||||
|
msgid "Stack overflow. Increase stack size."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: shared-bindings/alarm/time/TimeAlarm.c
|
#: shared-bindings/alarm/time/TimeAlarm.c
|
||||||
msgid "Supply one of monotonic_time or epoch_time"
|
msgid "Supply one of monotonic_time or epoch_time"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -2078,10 +2050,6 @@ msgstr ""
|
||||||
msgid "Traceback (most recent call last):\n"
|
msgid "Traceback (most recent call last):\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: shared-bindings/time/__init__.c
|
|
||||||
msgid "Tuple or struct_time argument required"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: ports/stm/common-hal/busio/UART.c
|
#: ports/stm/common-hal/busio/UART.c
|
||||||
msgid "UART de-init"
|
msgid "UART de-init"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -2435,10 +2403,6 @@ msgstr ""
|
||||||
msgid "argsort is not implemented for flattened arrays"
|
msgid "argsort is not implemented for flattened arrays"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: py/runtime.c shared-bindings/supervisor/__init__.c
|
|
||||||
msgid "argument has wrong type"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: py/compile.c
|
#: py/compile.c
|
||||||
msgid "argument name reused"
|
msgid "argument name reused"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -2448,10 +2412,6 @@ msgstr ""
|
||||||
msgid "argument num/types mismatch"
|
msgid "argument num/types mismatch"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: py/runtime.c
|
|
||||||
msgid "argument should be a '%q' not a '%q'"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/numpy/transform.c
|
#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/numpy/transform.c
|
||||||
msgid "arguments must be ndarrays"
|
msgid "arguments must be ndarrays"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -2636,7 +2596,7 @@ msgstr ""
|
||||||
msgid "can't convert %s to float"
|
msgid "can't convert %s to float"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: py/runtime.c
|
#: py/objint.c py/runtime.c
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "can't convert %s to int"
|
msgid "can't convert %s to int"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -2645,18 +2605,10 @@ msgstr ""
|
||||||
msgid "can't convert '%q' object to %q implicitly"
|
msgid "can't convert '%q' object to %q implicitly"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: py/objint.c
|
|
||||||
msgid "can't convert NaN to int"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: extmod/ulab/code/numpy/vector.c
|
#: extmod/ulab/code/numpy/vector.c
|
||||||
msgid "can't convert complex to float"
|
msgid "can't convert complex to float"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: py/objint.c
|
|
||||||
msgid "can't convert inf to int"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: py/obj.c
|
#: py/obj.c
|
||||||
msgid "can't convert to complex"
|
msgid "can't convert to complex"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -3144,10 +3096,6 @@ msgstr ""
|
||||||
msgid "function takes %d positional arguments but %d were given"
|
msgid "function takes %d positional arguments but %d were given"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: shared-bindings/time/__init__.c
|
|
||||||
msgid "function takes exactly 9 arguments"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: py/objgenerator.c
|
#: py/objgenerator.c
|
||||||
msgid "generator already executing"
|
msgid "generator already executing"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -3998,10 +3946,6 @@ msgstr ""
|
||||||
msgid "size is defined for ndarrays only"
|
msgid "size is defined for ndarrays only"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: shared-bindings/time/__init__.c
|
|
||||||
msgid "sleep length must be non-negative"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: py/nativeglue.c
|
#: py/nativeglue.c
|
||||||
msgid "slice unsupported"
|
msgid "slice unsupported"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
|
||||||
2
main.c
2
main.c
|
|
@ -1099,7 +1099,7 @@ int __attribute__((used)) main(void) {
|
||||||
exit_code = run_repl(get_safe_mode());
|
exit_code = run_repl(get_safe_mode());
|
||||||
supervisor_set_run_reason(RUN_REASON_REPL_RELOAD);
|
supervisor_set_run_reason(RUN_REASON_REPL_RELOAD);
|
||||||
}
|
}
|
||||||
if (exit_code == PYEXEC_FORCED_EXIT) {
|
if (exit_code & (PYEXEC_FORCED_EXIT | PYEXEC_RELOAD)) {
|
||||||
if (!simulate_reset) {
|
if (!simulate_reset) {
|
||||||
serial_write_compressed(MP_ERROR_TEXT("soft reboot\n"));
|
serial_write_compressed(MP_ERROR_TEXT("soft reboot\n"));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -235,7 +235,7 @@ static void pinalarm_set_alarms_light(size_t n_alarms, const mp_obj_t *alarms) {
|
||||||
case PINALARM_ERR_NOEXTINT:
|
case PINALARM_ERR_NOEXTINT:
|
||||||
raise_ValueError_invalid_pin();
|
raise_ValueError_invalid_pin();
|
||||||
case PINALARM_ERR_NOCHANNEL:
|
case PINALARM_ERR_NOCHANNEL:
|
||||||
mp_raise_RuntimeError(MP_ERROR_TEXT("EXTINT channel already in use"));
|
mp_raise_RuntimeError(MP_ERROR_TEXT("Internal resource(s) in use"));
|
||||||
default:
|
default:
|
||||||
mp_raise_RuntimeError(MP_ERROR_TEXT("Unknown reason."));
|
mp_raise_RuntimeError(MP_ERROR_TEXT("Unknown reason."));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -243,7 +243,7 @@ void common_hal_audiobusio_i2sout_play(audiobusio_i2sout_obj_t *self,
|
||||||
// Find a free GCLK to generate the MCLK signal.
|
// Find a free GCLK to generate the MCLK signal.
|
||||||
uint8_t gclk = find_free_gclk(divisor);
|
uint8_t gclk = find_free_gclk(divisor);
|
||||||
if (gclk > GCLK_GEN_NUM) {
|
if (gclk > GCLK_GEN_NUM) {
|
||||||
mp_raise_RuntimeError(MP_ERROR_TEXT("No free GLCKs"));
|
mp_raise_RuntimeError(MP_ERROR_TEXT("No free GCLKs"));
|
||||||
}
|
}
|
||||||
self->gclk = gclk;
|
self->gclk = gclk;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
|
|
||||||
#include "common-hal/countio/Counter.h"
|
#include "common-hal/countio/Counter.h"
|
||||||
#include "shared-bindings/countio/Counter.h"
|
#include "shared-bindings/countio/Counter.h"
|
||||||
|
#include "shared-bindings/microcontroller/Pin.h"
|
||||||
|
|
||||||
#include "atmel_start_pins.h"
|
#include "atmel_start_pins.h"
|
||||||
|
|
||||||
|
|
@ -11,13 +12,13 @@
|
||||||
void common_hal_countio_counter_construct(countio_counter_obj_t *self,
|
void common_hal_countio_counter_construct(countio_counter_obj_t *self,
|
||||||
const mcu_pin_obj_t *pin, countio_edge_t edge, digitalio_pull_t pull) {
|
const mcu_pin_obj_t *pin, countio_edge_t edge, digitalio_pull_t pull) {
|
||||||
if (!pin->has_extint) {
|
if (!pin->has_extint) {
|
||||||
mp_raise_RuntimeError(MP_ERROR_TEXT("Pin must support hardware interrupts"));
|
raise_ValueError_invalid_pin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (eic_get_enable()) {
|
if (eic_get_enable()) {
|
||||||
if (!eic_channel_free(pin->extint_channel)) {
|
if (!eic_channel_free(pin->extint_channel)) {
|
||||||
mp_raise_RuntimeError(MP_ERROR_TEXT("EXTINT channel already in use"));
|
mp_raise_RuntimeError(MP_ERROR_TEXT("Internal resource(s) in use"));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
turn_on_external_interrupt_controller();
|
turn_on_external_interrupt_controller();
|
||||||
|
|
|
||||||
|
|
@ -295,12 +295,12 @@ void common_hal_frequencyio_frequencyin_construct(frequencyio_frequencyin_obj_t*
|
||||||
#ifdef SAM_D5X_E5X
|
#ifdef SAM_D5X_E5X
|
||||||
((EIC->INTENSET.bit.EXTINT & mask) != 0 || (EIC->EVCTRL.bit.EXTINTEO & mask) != 0)) {
|
((EIC->INTENSET.bit.EXTINT & mask) != 0 || (EIC->EVCTRL.bit.EXTINTEO & mask) != 0)) {
|
||||||
#endif
|
#endif
|
||||||
mp_raise_RuntimeError(MP_ERROR_TEXT("EXTINT channel already in use"));
|
mp_raise_RuntimeError(MP_ERROR_TEXT("Internal resource(s) in use"));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t timer_index = find_free_timer();
|
uint8_t timer_index = find_free_timer();
|
||||||
if (timer_index == 0xff) {
|
if (timer_index == 0xff) {
|
||||||
mp_raise_RuntimeError(MP_ERROR_TEXT("All timers in use"));
|
mp_raise_RuntimeError(MP_ERROR_TEXT("Internal resource(s) in use"));
|
||||||
}
|
}
|
||||||
Tc *tc = tc_insts[timer_index];
|
Tc *tc = tc_insts[timer_index];
|
||||||
|
|
||||||
|
|
@ -329,7 +329,7 @@ void common_hal_frequencyio_frequencyin_construct(frequencyio_frequencyin_obj_t*
|
||||||
frequencyin_samd51_start_dpll();
|
frequencyin_samd51_start_dpll();
|
||||||
if (dpll_gclk == 0xff && !clock_get_enabled(0, GCLK_SOURCE_DPLL1)) {
|
if (dpll_gclk == 0xff && !clock_get_enabled(0, GCLK_SOURCE_DPLL1)) {
|
||||||
common_hal_frequencyio_frequencyin_deinit(self);
|
common_hal_frequencyio_frequencyin_deinit(self);
|
||||||
mp_raise_RuntimeError(MP_ERROR_TEXT("No available clocks"));
|
mp_raise_RuntimeError(MP_ERROR_TEXT("Internal resource(s) in use"));
|
||||||
}
|
}
|
||||||
set_timer_handler(timer_index, dpll_gclk, TC_HANDLER_NO_INTERRUPT);
|
set_timer_handler(timer_index, dpll_gclk, TC_HANDLER_NO_INTERRUPT);
|
||||||
turn_on_clocks(true, timer_index, dpll_gclk);
|
turn_on_clocks(true, timer_index, dpll_gclk);
|
||||||
|
|
@ -399,7 +399,7 @@ void common_hal_frequencyio_frequencyin_construct(frequencyio_frequencyin_obj_t*
|
||||||
reference_tc = find_free_timer();
|
reference_tc = find_free_timer();
|
||||||
if (reference_tc == 0xff) {
|
if (reference_tc == 0xff) {
|
||||||
common_hal_frequencyio_frequencyin_deinit(self);
|
common_hal_frequencyio_frequencyin_deinit(self);
|
||||||
mp_raise_RuntimeError(MP_ERROR_TEXT("All timers in use"));
|
mp_raise_RuntimeError(MP_ERROR_TEXT("Internal resource(s) in use"));
|
||||||
}
|
}
|
||||||
frequencyin_reference_tc_init();
|
frequencyin_reference_tc_init();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ void common_hal_mcu_enable_interrupts(void) {
|
||||||
void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) {
|
void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) {
|
||||||
if ((runmode == RUNMODE_BOOTLOADER) || (runmode == RUNMODE_UF2)) {
|
if ((runmode == RUNMODE_BOOTLOADER) || (runmode == RUNMODE_UF2)) {
|
||||||
if (!bootloader_available()) {
|
if (!bootloader_available()) {
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("Cannot reset into bootloader because no bootloader is present"));
|
mp_raise_ValueError(MP_ERROR_TEXT("No bootloader present"));
|
||||||
}
|
}
|
||||||
// Pretend to be the first of the two reset presses needed to enter the
|
// Pretend to be the first of the two reset presses needed to enter the
|
||||||
// bootloader. That way one reset will end in the bootloader.
|
// bootloader. That way one reset will end in the bootloader.
|
||||||
|
|
|
||||||
|
|
@ -248,7 +248,7 @@ void common_hal_ps2io_ps2_construct(ps2io_ps2_obj_t *self,
|
||||||
mp_arg_error_invalid(MP_QSTR_clock_pin);
|
mp_arg_error_invalid(MP_QSTR_clock_pin);
|
||||||
}
|
}
|
||||||
if (eic_get_enable() && !eic_channel_free(clock_pin->extint_channel)) {
|
if (eic_get_enable() && !eic_channel_free(clock_pin->extint_channel)) {
|
||||||
mp_raise_RuntimeError(MP_ERROR_TEXT("EXTINT channel already in use"));
|
mp_raise_RuntimeError(MP_ERROR_TEXT("Internal resource(s) in use"));
|
||||||
}
|
}
|
||||||
|
|
||||||
clk_hi(self);
|
clk_hi(self);
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,7 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self,
|
||||||
raise_ValueError_invalid_pin();
|
raise_ValueError_invalid_pin();
|
||||||
}
|
}
|
||||||
if (eic_get_enable() && !eic_channel_free(pin->extint_channel)) {
|
if (eic_get_enable() && !eic_channel_free(pin->extint_channel)) {
|
||||||
mp_raise_RuntimeError(MP_ERROR_TEXT("EXTINT channel already in use"));
|
mp_raise_RuntimeError(MP_ERROR_TEXT("Internal resource(s) in use"));
|
||||||
}
|
}
|
||||||
|
|
||||||
self->buffer = (uint16_t *)m_malloc(maxlen * sizeof(uint16_t));
|
self->buffer = (uint16_t *)m_malloc(maxlen * sizeof(uint16_t));
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,6 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t *self,
|
||||||
// one output so we start with the TCs to see if they work.
|
// one output so we start with the TCs to see if they work.
|
||||||
int8_t direction = -1;
|
int8_t direction = -1;
|
||||||
uint8_t start = NUM_TIMERS_PER_PIN - 1;
|
uint8_t start = NUM_TIMERS_PER_PIN - 1;
|
||||||
bool found = false;
|
|
||||||
if (variable_frequency) {
|
if (variable_frequency) {
|
||||||
direction = 1;
|
direction = 1;
|
||||||
start = 0;
|
start = 0;
|
||||||
|
|
@ -162,7 +161,6 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t *self,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (t->is_tc) {
|
if (t->is_tc) {
|
||||||
found = true;
|
|
||||||
Tc *tc = tc_insts[t->index];
|
Tc *tc = tc_insts[t->index];
|
||||||
if (tc->COUNT16.CTRLA.bit.ENABLE == 0 && t->wave_output == 1) {
|
if (tc->COUNT16.CTRLA.bit.ENABLE == 0 && t->wave_output == 1) {
|
||||||
timer = t;
|
timer = t;
|
||||||
|
|
@ -178,10 +176,7 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t *self,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timer == NULL) {
|
if (timer == NULL) {
|
||||||
if (found) {
|
return PWMOUT_INTERNAL_RESOURCES_IN_USE;
|
||||||
return PWMOUT_ALL_TIMERS_ON_PIN_IN_USE;
|
|
||||||
}
|
|
||||||
return PWMOUT_ALL_TIMERS_IN_USE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t resolution = 0;
|
uint8_t resolution = 0;
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "common-hal/rotaryio/IncrementalEncoder.h"
|
#include "common-hal/rotaryio/IncrementalEncoder.h"
|
||||||
|
#include "shared-bindings/microcontroller/Pin.h"
|
||||||
#include "shared-bindings/rotaryio/IncrementalEncoder.h"
|
#include "shared-bindings/rotaryio/IncrementalEncoder.h"
|
||||||
#include "shared-module/rotaryio/IncrementalEncoder.h"
|
#include "shared-module/rotaryio/IncrementalEncoder.h"
|
||||||
|
|
||||||
|
|
@ -36,8 +37,11 @@
|
||||||
|
|
||||||
void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencoder_obj_t *self,
|
void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencoder_obj_t *self,
|
||||||
const mcu_pin_obj_t *pin_a, const mcu_pin_obj_t *pin_b) {
|
const mcu_pin_obj_t *pin_a, const mcu_pin_obj_t *pin_b) {
|
||||||
if (!pin_a->has_extint || !pin_b->has_extint) {
|
if (!pin_a->has_extint) {
|
||||||
mp_raise_RuntimeError(MP_ERROR_TEXT("Pin must support hardware interrupts"));
|
raise_ValueError_invalid_pin_name(MP_QSTR_pin_a);
|
||||||
|
}
|
||||||
|
if (!pin_b->has_extint) {
|
||||||
|
raise_ValueError_invalid_pin_name(MP_QSTR_pin_b);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: The SAMD51 has a peripheral dedicated to quadrature encoder debugging. Use it instead
|
// TODO: The SAMD51 has a peripheral dedicated to quadrature encoder debugging. Use it instead
|
||||||
|
|
@ -45,7 +49,7 @@ void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencode
|
||||||
|
|
||||||
if (eic_get_enable()) {
|
if (eic_get_enable()) {
|
||||||
if (!eic_channel_free(pin_a->extint_channel) || !eic_channel_free(pin_b->extint_channel)) {
|
if (!eic_channel_free(pin_a->extint_channel) || !eic_channel_free(pin_b->extint_channel)) {
|
||||||
mp_raise_RuntimeError(MP_ERROR_TEXT("EXTINT channel already in use"));
|
mp_raise_RuntimeError(MP_ERROR_TEXT("Internal resource(s) in use"));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
turn_on_external_interrupt_controller();
|
turn_on_external_interrupt_controller();
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ void common_hal_mcu_enable_interrupts(void) {
|
||||||
|
|
||||||
void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) {
|
void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) {
|
||||||
if (runmode == RUNMODE_BOOTLOADER) {
|
if (runmode == RUNMODE_BOOTLOADER) {
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("Cannot reset into bootloader because no bootloader is present"));
|
mp_raise_ValueError(MP_ERROR_TEXT("No bootloader present"));
|
||||||
} else if (runmode == RUNMODE_SAFE_MODE) {
|
} else if (runmode == RUNMODE_SAFE_MODE) {
|
||||||
safe_mode_on_next_reset(SAFE_MODE_PROGRAMMATIC);
|
safe_mode_on_next_reset(SAFE_MODE_PROGRAMMATIC);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self,
|
||||||
|
|
||||||
int irq = pulsein_set_config(self, true);
|
int irq = pulsein_set_config(self, true);
|
||||||
if (irq < 0) {
|
if (irq < 0) {
|
||||||
mp_raise_RuntimeError(MP_ERROR_TEXT("EXTINT channel already in use"));
|
mp_raise_RuntimeError(MP_ERROR_TEXT("Internal resource(s) in use"));
|
||||||
} else {
|
} else {
|
||||||
pulsein_objects[irq - CXD56_IRQ_EXDEVICE_0] = self;
|
pulsein_objects[irq - CXD56_IRQ_EXDEVICE_0] = self;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Scott Shawcroft for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "supervisor/board.h"
|
||||||
|
|
||||||
|
// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here.
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Dan Halbert for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Micropython setup
|
||||||
|
|
||||||
|
#define MICROPY_HW_BOARD_NAME "Espressif ESP32 DevKitc V4 WROOM-32E"
|
||||||
|
#define MICROPY_HW_MCU_NAME "ESP32"
|
||||||
|
|
||||||
|
#define CIRCUITPY_BOARD_I2C (1)
|
||||||
|
#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO22, .sda = &pin_GPIO23}}
|
||||||
|
|
||||||
|
#define CIRCUITPY_BOARD_SPI (1)
|
||||||
|
#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO5, .mosi = &pin_GPIO18, .miso = &pin_GPIO19}}
|
||||||
|
|
||||||
|
#define CIRCUITPY_BOARD_UART (1)
|
||||||
|
#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO17, .rx = &pin_GPIO16}}
|
||||||
|
|
||||||
|
// UART pins attached to the USB-serial converter chip
|
||||||
|
#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1)
|
||||||
|
#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3)
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
CIRCUITPY_CREATOR_ID = 0x000C303A
|
||||||
|
CIRCUITPY_CREATION_ID = 0x0032C002
|
||||||
|
|
||||||
|
IDF_TARGET = esp32
|
||||||
|
|
||||||
|
CIRCUITPY_ESP_FLASH_MODE = qio
|
||||||
|
CIRCUITPY_ESP_FLASH_FREQ = 40m
|
||||||
|
CIRCUITPY_ESP_FLASH_SIZE = 4MB
|
||||||
|
|
||||||
|
CIRCUITPY_ESPCAMERA = 0
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
#include "shared-bindings/board/__init__.h"
|
||||||
|
|
||||||
|
STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
|
||||||
|
CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS
|
||||||
|
|
||||||
|
// External pins are in silkscreen order, from top to bottom, left side, then right side
|
||||||
|
// Left Side
|
||||||
|
// Pins dedicated to SPI flash
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_CLK), MP_ROM_PTR(&pin_GPIO6) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO7) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO8) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) },
|
||||||
|
|
||||||
|
// Normal pins
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) },
|
||||||
|
|
||||||
|
// UART on silkscreen
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO3) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO1) },
|
||||||
|
|
||||||
|
// Normal pins
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO22), MP_ROM_PTR(&pin_GPIO22) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO23), MP_ROM_PTR(&pin_GPIO23) },
|
||||||
|
|
||||||
|
// Right side
|
||||||
|
// Pins dedicated to SPI flash
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_CMD), MP_ROM_PTR(&pin_GPIO11) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO10) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO9) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) },
|
||||||
|
|
||||||
|
// Normal pins
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO27), MP_ROM_PTR(&pin_GPIO27) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO26), MP_ROM_PTR(&pin_GPIO26) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO25), MP_ROM_PTR(&pin_GPIO25) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO32), MP_ROM_PTR(&pin_GPIO32) },
|
||||||
|
|
||||||
|
// Input-only pins, VP/VN on silkscreen
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_I35), MP_ROM_PTR(&pin_GPIO35) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_I34), MP_ROM_PTR(&pin_GPIO34) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_I39), MP_ROM_PTR(&pin_GPIO39) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_VN), MP_ROM_PTR(&pin_GPIO39) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_I36), MP_ROM_PTR(&pin_GPIO36) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_VP), MP_ROM_PTR(&pin_GPIO36) },
|
||||||
|
|
||||||
|
// Button
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO0) }
|
||||||
|
|
||||||
|
};
|
||||||
|
MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Scott Shawcroft for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "supervisor/board.h"
|
||||||
|
|
||||||
|
// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here.
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Dan Halbert for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Micropython setup
|
||||||
|
|
||||||
|
#define MICROPY_HW_BOARD_NAME "Espressif ESP32 DevKitc V4 WROVER"
|
||||||
|
#define MICROPY_HW_MCU_NAME "ESP32"
|
||||||
|
|
||||||
|
#define CIRCUITPY_BOARD_I2C (1)
|
||||||
|
#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO22, .sda = &pin_GPIO23}}
|
||||||
|
|
||||||
|
#define CIRCUITPY_BOARD_SPI (1)
|
||||||
|
#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO5, .mosi = &pin_GPIO18, .miso = &pin_GPIO19}}
|
||||||
|
|
||||||
|
#define CIRCUITPY_BOARD_UART (1)
|
||||||
|
#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO17, .rx = &pin_GPIO16}}
|
||||||
|
|
||||||
|
// UART pins attached to the USB-serial converter chip
|
||||||
|
#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1)
|
||||||
|
#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3)
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
CIRCUITPY_CREATOR_ID = 0x000C303A
|
||||||
|
CIRCUITPY_CREATION_ID = 0x0032C003
|
||||||
|
|
||||||
|
IDF_TARGET = esp32
|
||||||
|
|
||||||
|
CIRCUITPY_ESP_FLASH_MODE = qio
|
||||||
|
CIRCUITPY_ESP_FLASH_FREQ = 40m
|
||||||
|
CIRCUITPY_ESP_FLASH_SIZE = 8MB
|
||||||
|
|
||||||
|
CIRCUITPY_ESPCAMERA = 0
|
||||||
|
|
||||||
|
CIRCUITPY_ESP_PSRAM_SIZE = 8MB
|
||||||
|
CIRCUITPY_ESP_PSRAM_MODE = qio
|
||||||
|
CIRCUITPY_ESP_PSRAM_FREQ = 40m
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
#include "shared-bindings/board/__init__.h"
|
||||||
|
|
||||||
|
STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
|
||||||
|
CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS
|
||||||
|
|
||||||
|
// External pins are in silkscreen order, from top to bottom, left side, then right side
|
||||||
|
// Left Side
|
||||||
|
// Pins dedicated to SPI flash & mem
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_CLK), MP_ROM_PTR(&pin_GPIO6) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO7) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO8) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) },
|
||||||
|
|
||||||
|
// Normal pins
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) },
|
||||||
|
|
||||||
|
// UART on silkscreen
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO3) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO1) },
|
||||||
|
|
||||||
|
// Normal pins
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO22), MP_ROM_PTR(&pin_GPIO22) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO23), MP_ROM_PTR(&pin_GPIO23) },
|
||||||
|
|
||||||
|
// Right side
|
||||||
|
// Pins dedicated to SPI flash & mem
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_CMD), MP_ROM_PTR(&pin_GPIO11) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO10) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO9) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) },
|
||||||
|
|
||||||
|
// Normal pins
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO27), MP_ROM_PTR(&pin_GPIO27) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO26), MP_ROM_PTR(&pin_GPIO26) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO25), MP_ROM_PTR(&pin_GPIO25) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_IO32), MP_ROM_PTR(&pin_GPIO32) },
|
||||||
|
|
||||||
|
// Input-only pins, VP/VN on silkscreen
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_I35), MP_ROM_PTR(&pin_GPIO35) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_I34), MP_ROM_PTR(&pin_GPIO34) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_I39), MP_ROM_PTR(&pin_GPIO39) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_VN), MP_ROM_PTR(&pin_GPIO39) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_I36), MP_ROM_PTR(&pin_GPIO36) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_VP), MP_ROM_PTR(&pin_GPIO36) },
|
||||||
|
|
||||||
|
// Button
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO0) }
|
||||||
|
|
||||||
|
};
|
||||||
|
MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
|
||||||
|
|
@ -27,9 +27,8 @@
|
||||||
#define MICROPY_HW_BOARD_NAME "DFRobot FireBeetle 2 ESP32-S3"
|
#define MICROPY_HW_BOARD_NAME "DFRobot FireBeetle 2 ESP32-S3"
|
||||||
#define MICROPY_HW_MCU_NAME "ESP32S3"
|
#define MICROPY_HW_MCU_NAME "ESP32S3"
|
||||||
|
|
||||||
#define CIRCUITPY_BOARD_I2C (2)
|
#define CIRCUITPY_BOARD_I2C (1)
|
||||||
#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO2, .sda = &pin_GPIO3}, \
|
#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO2, .sda = &pin_GPIO1}}
|
||||||
{.scl = &pin_GPIO2, .sda = &pin_GPIO1}}
|
|
||||||
|
|
||||||
#define DEFAULT_SPI_BUS_SCK (&pin_GPIO17)
|
#define DEFAULT_SPI_BUS_SCK (&pin_GPIO17)
|
||||||
#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO15)
|
#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO15)
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,6 @@
|
||||||
#include "shared-bindings/board/__init__.h"
|
#include "shared-bindings/board/__init__.h"
|
||||||
#include "shared-module/displayio/__init__.h"
|
#include "shared-module/displayio/__init__.h"
|
||||||
|
|
||||||
CIRCUITPY_BOARD_BUS_SINGLETON(cam_i2c, i2c, 1) // Camera sensor
|
|
||||||
|
|
||||||
STATIC const mp_rom_obj_tuple_t camera_data_tuple = {
|
STATIC const mp_rom_obj_tuple_t camera_data_tuple = {
|
||||||
// The order matters.
|
// The order matters.
|
||||||
// They must be ordered from low to high (Y2, Y3 .. Y9).
|
// They must be ordered from low to high (Y2, Y3 .. Y9).
|
||||||
|
|
@ -43,9 +41,8 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
|
||||||
{ MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO2) },
|
{ MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO2) },
|
||||||
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) },
|
{ MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO3) },
|
{ MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO1) },
|
||||||
|
|
||||||
// I2C cannot be used when CAM_I2C is in use.
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
|
||||||
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) },
|
{ MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) },
|
||||||
|
|
@ -118,7 +115,5 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
|
||||||
{ MP_ROM_QSTR(MP_QSTR_CAM_HREF), MP_ROM_PTR(&pin_GPIO42)},
|
{ MP_ROM_QSTR(MP_QSTR_CAM_HREF), MP_ROM_PTR(&pin_GPIO42)},
|
||||||
{ MP_ROM_QSTR(MP_QSTR_CAM_PCLK), MP_ROM_PTR(&pin_GPIO5) },
|
{ MP_ROM_QSTR(MP_QSTR_CAM_PCLK), MP_ROM_PTR(&pin_GPIO5) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_CAM_XCLK), MP_ROM_PTR(&pin_GPIO45)},
|
{ MP_ROM_QSTR(MP_QSTR_CAM_XCLK), MP_ROM_PTR(&pin_GPIO45)},
|
||||||
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_CAM_I2C), MP_ROM_PTR(&board_cam_i2c_obj)},
|
|
||||||
};
|
};
|
||||||
MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
|
MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
|
||||||
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
|
||||||
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)}
|
// TODO: Uncomment once the display initialization code is added.
|
||||||
|
// { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)}
|
||||||
};
|
};
|
||||||
MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
|
MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,8 @@
|
||||||
void board_init(void) {
|
void board_init(void) {
|
||||||
mp_import_stat_t stat_b = mp_import_stat("boot.py");
|
mp_import_stat_t stat_b = mp_import_stat("boot.py");
|
||||||
if (stat_b != MP_IMPORT_STAT_FILE) {
|
if (stat_b != MP_IMPORT_STAT_FILE) {
|
||||||
FATFS *fatfs = filesystem_circuitpy();
|
fs_user_mount_t *fs_mount = filesystem_circuitpy();
|
||||||
|
FATFS *fatfs = &fs_mount->fatfs;
|
||||||
FIL fs;
|
FIL fs;
|
||||||
UINT char_written = 0;
|
UINT char_written = 0;
|
||||||
const byte buffer[] = "#Serial port upload mode\nimport storage\nstorage.remount(\"/\", False)\nstorage.disable_usb_drive()\n";
|
const byte buffer[] = "#Serial port upload mode\nimport storage\nstorage.remount(\"/\", False)\nstorage.disable_usb_drive()\n";
|
||||||
|
|
@ -44,7 +45,7 @@ void board_init(void) {
|
||||||
f_open(fatfs, &fs, "/boot.py", FA_WRITE | FA_CREATE_ALWAYS);
|
f_open(fatfs, &fs, "/boot.py", FA_WRITE | FA_CREATE_ALWAYS);
|
||||||
f_write(&fs, buffer, sizeof(buffer) - 1, &char_written);
|
f_write(&fs, buffer, sizeof(buffer) - 1, &char_written);
|
||||||
f_close(&fs);
|
f_close(&fs);
|
||||||
// Delete code.Py, use main.py
|
// Delete code.py, use main.py
|
||||||
mp_import_stat_t stat_c = mp_import_stat("code.py");
|
mp_import_stat_t stat_c = mp_import_stat("code.py");
|
||||||
if (stat_c == MP_IMPORT_STAT_FILE) {
|
if (stat_c == MP_IMPORT_STAT_FILE) {
|
||||||
f_unlink(fatfs, "/code.py");
|
f_unlink(fatfs, "/code.py");
|
||||||
|
|
|
||||||
|
|
@ -37,16 +37,16 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
|
||||||
{ MP_ROM_QSTR(MP_QSTR_I2S_MIC_SEL), MP_ROM_PTR(&pin_GPIO39) },
|
{ MP_ROM_QSTR(MP_QSTR_I2S_MIC_SEL), MP_ROM_PTR(&pin_GPIO39) },
|
||||||
|
|
||||||
// I2S Amplifier MAX98357A
|
// I2S Amplifier MAX98357A
|
||||||
{ MP_ROM_QSTR(MP_QSTR_I2S_MIC_LRCLK), MP_ROM_PTR(&pin_GPIO1) },
|
{ MP_ROM_QSTR(MP_QSTR_I2S_AMP_LRCLK), MP_ROM_PTR(&pin_GPIO1) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_I2S_MIC_BCLK), MP_ROM_PTR(&pin_GPIO2) },
|
{ MP_ROM_QSTR(MP_QSTR_I2S_AMP_BCLK), MP_ROM_PTR(&pin_GPIO2) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_I2S_MIC_DATA), MP_ROM_PTR(&pin_GPIO3) },
|
{ MP_ROM_QSTR(MP_QSTR_I2S_AMP_DATA), MP_ROM_PTR(&pin_GPIO3) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_I2S_MIC_SD), MP_ROM_PTR(&pin_GPIO4) },
|
{ MP_ROM_QSTR(MP_QSTR_I2S_AMP_SD), MP_ROM_PTR(&pin_GPIO4) },
|
||||||
|
|
||||||
// RTC Interrupt Pin
|
// RTC Interrupt Pin
|
||||||
{ MP_ROM_QSTR(MP_QSTR_RTC_INT), MP_ROM_PTR(&pin_GPIO7) },
|
{ MP_ROM_QSTR(MP_QSTR_RTC_INT), MP_ROM_PTR(&pin_GPIO7) },
|
||||||
|
|
||||||
// LED Matrix
|
// LED Matrix
|
||||||
{ MP_ROM_QSTR(MP_QSTR_MATRIX_POWER), MP_ROM_PTR(&pin_GPIO5) },
|
{ MP_ROM_QSTR(MP_QSTR_MATRIX_POWER), MP_ROM_PTR(&pin_GPIO6) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_MATRIX_DATA), MP_ROM_PTR(&pin_GPIO18) },
|
{ MP_ROM_QSTR(MP_QSTR_MATRIX_DATA), MP_ROM_PTR(&pin_GPIO18) },
|
||||||
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t *self,
|
||||||
}
|
}
|
||||||
if (timer_index == INDEX_EMPTY) {
|
if (timer_index == INDEX_EMPTY) {
|
||||||
// Running out of timers isn't pin related on ESP32S2.
|
// Running out of timers isn't pin related on ESP32S2.
|
||||||
return PWMOUT_ALL_TIMERS_IN_USE;
|
return PWMOUT_INTERNAL_RESOURCES_IN_USE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find a viable channel
|
// Find a viable channel
|
||||||
|
|
@ -114,7 +114,7 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t *self,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (channel_index == INDEX_EMPTY) {
|
if (channel_index == INDEX_EMPTY) {
|
||||||
return PWMOUT_ALL_CHANNELS_IN_USE;
|
return PWMOUT_INTERNAL_RESOURCES_IN_USE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run configuration
|
// Run configuration
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,8 @@ STATIC uint32_t _cache_lba = 0xffffffff;
|
||||||
#define SECSIZE(fs) ((fs)->ssize)
|
#define SECSIZE(fs) ((fs)->ssize)
|
||||||
#endif // FF_MAX_SS == FF_MIN_SS
|
#endif // FF_MAX_SS == FF_MIN_SS
|
||||||
STATIC DWORD fatfs_bytes(void) {
|
STATIC DWORD fatfs_bytes(void) {
|
||||||
FATFS *fatfs = filesystem_circuitpy();
|
fs_user_mount_t *fs_mount = filesystem_circuitpy();
|
||||||
|
FATFS *fatfs = &fs_mount->fatfs;
|
||||||
return (fatfs->csize * SECSIZE(fatfs)) * (fatfs->n_fatent - 2);
|
return (fatfs->csize * SECSIZE(fatfs)) * (fatfs->n_fatent - 2);
|
||||||
}
|
}
|
||||||
STATIC bool storage_extended = true;
|
STATIC bool storage_extended = true;
|
||||||
|
|
|
||||||
|
|
@ -107,9 +107,6 @@
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#define TAG "port"
|
#define TAG "port"
|
||||||
|
|
||||||
uint32_t *heap;
|
|
||||||
uint32_t heap_size;
|
|
||||||
|
|
||||||
STATIC esp_timer_handle_t _tick_timer;
|
STATIC esp_timer_handle_t _tick_timer;
|
||||||
STATIC esp_timer_handle_t _sleep_timer;
|
STATIC esp_timer_handle_t _sleep_timer;
|
||||||
|
|
||||||
|
|
@ -255,9 +252,6 @@ safe_mode_t port_init(void) {
|
||||||
esp_rom_install_uart_printf();
|
esp_rom_install_uart_printf();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
heap = NULL;
|
|
||||||
heap_size = 0;
|
|
||||||
|
|
||||||
#define pin_GPIOn(n) pin_GPIO##n
|
#define pin_GPIOn(n) pin_GPIO##n
|
||||||
#define pin_GPIOn_EXPAND(x) pin_GPIOn(x)
|
#define pin_GPIOn_EXPAND(x) pin_GPIOn(x)
|
||||||
|
|
||||||
|
|
@ -329,7 +323,16 @@ void *port_malloc(size_t size, bool dma_capable) {
|
||||||
if (dma_capable) {
|
if (dma_capable) {
|
||||||
caps |= MALLOC_CAP_DMA;
|
caps |= MALLOC_CAP_DMA;
|
||||||
}
|
}
|
||||||
return heap_caps_malloc(size, caps);
|
|
||||||
|
void *ptr = NULL;
|
||||||
|
// Try SPIRAM first when available.
|
||||||
|
#ifdef CONFIG_SPIRAM
|
||||||
|
ptr = heap_caps_malloc(size, caps | MALLOC_CAP_SPIRAM);
|
||||||
|
#endif
|
||||||
|
if (ptr == NULL) {
|
||||||
|
ptr = heap_caps_malloc(size, caps);
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void port_free(void *ptr) {
|
void port_free(void *ptr) {
|
||||||
|
|
@ -341,7 +344,7 @@ void *port_realloc(void *ptr, size_t size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t port_heap_get_largest_free_size(void) {
|
size_t port_heap_get_largest_free_size(void) {
|
||||||
size_t free_size = heap_caps_get_largest_free_block(0);
|
size_t free_size = heap_caps_get_largest_free_block(MALLOC_CAP_8BIT);
|
||||||
return free_size;
|
return free_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ void PLACE_IN_ITCM(common_hal_mcu_enable_interrupts)(void) {
|
||||||
void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) {
|
void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) {
|
||||||
if (runmode == RUNMODE_BOOTLOADER) {
|
if (runmode == RUNMODE_BOOTLOADER) {
|
||||||
if (!bootloader_available()) {
|
if (!bootloader_available()) {
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("Cannot reset into bootloader because no bootloader is present"));
|
mp_raise_ValueError(MP_ERROR_TEXT("No bootloader present"));
|
||||||
}
|
}
|
||||||
// Pretend to be the first of the two reset presses needed to enter the
|
// Pretend to be the first of the two reset presses needed to enter the
|
||||||
// bootloader. That way one reset will end in the bootloader.
|
// bootloader. That way one reset will end in the bootloader.
|
||||||
|
|
|
||||||
|
|
@ -189,7 +189,7 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t *self,
|
||||||
if (((flexpwm->MCTRL >> PWM_MCTRL_RUN_SHIFT) & sm_mask) != 0) {
|
if (((flexpwm->MCTRL >> PWM_MCTRL_RUN_SHIFT) & sm_mask) != 0) {
|
||||||
// Another output has claimed this submodule for variable frequency already.
|
// Another output has claimed this submodule for variable frequency already.
|
||||||
if ((_pwm_variable_frequency[flexpwm_index] & sm_mask) != 0) {
|
if ((_pwm_variable_frequency[flexpwm_index] & sm_mask) != 0) {
|
||||||
return PWMOUT_ALL_TIMERS_ON_PIN_IN_USE;
|
return PWMOUT_INTERNAL_RESOURCES_IN_USE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We want variable frequency but another class has already claim a fixed frequency.
|
// We want variable frequency but another class has already claim a fixed frequency.
|
||||||
|
|
@ -199,7 +199,7 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t *self,
|
||||||
|
|
||||||
// Another pin is already using this output.
|
// Another pin is already using this output.
|
||||||
if ((flexpwm->OUTEN & outen_mask) != 0) {
|
if ((flexpwm->OUTEN & outen_mask) != 0) {
|
||||||
return PWMOUT_ALL_TIMERS_ON_PIN_IN_USE;
|
return PWMOUT_INTERNAL_RESOURCES_IN_USE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frequency != _pwm_sm_frequencies[flexpwm_index][submodule]) {
|
if (frequency != _pwm_sm_frequencies[flexpwm_index][submodule]) {
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@
|
||||||
#include "shared-bindings/busio/I2C.h"
|
#include "shared-bindings/busio/I2C.h"
|
||||||
#include "shared-bindings/microcontroller/__init__.h"
|
#include "shared-bindings/microcontroller/__init__.h"
|
||||||
#include "shared-bindings/microcontroller/Pin.h"
|
#include "shared-bindings/microcontroller/Pin.h"
|
||||||
|
#include "supervisor/shared/tick.h"
|
||||||
#include "py/mperrno.h"
|
#include "py/mperrno.h"
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
|
|
||||||
|
|
@ -39,18 +40,23 @@
|
||||||
|
|
||||||
// all TWI instances have the same max size
|
// all TWI instances have the same max size
|
||||||
// 16 bits for 840, 10 bits for 810, 8 bits for 832
|
// 16 bits for 840, 10 bits for 810, 8 bits for 832
|
||||||
#define I2C_MAX_XFER_LEN ((1UL << TWIM0_EASYDMA_MAXCNT_SIZE) - 1)
|
#define I2C_MAX_XFER_LEN MIN(((1UL << TWIM0_EASYDMA_MAXCNT_SIZE) - 1), 1024)
|
||||||
|
#define I2C_TIMEOUT 1000 // 1 second timeout
|
||||||
|
|
||||||
STATIC twim_peripheral_t twim_peripherals[] = {
|
STATIC twim_peripheral_t twim_peripherals[] = {
|
||||||
#if NRFX_CHECK(NRFX_TWIM0_ENABLED)
|
#if NRFX_CHECK(NRFX_TWIM0_ENABLED)
|
||||||
// SPIM0 and TWIM0 share an address.
|
// SPIM0 and TWIM0 share an address.
|
||||||
{ .twim = NRFX_TWIM_INSTANCE(0),
|
{ .twim = NRFX_TWIM_INSTANCE(0),
|
||||||
.in_use = false},
|
.in_use = false,
|
||||||
|
.transferring = false,
|
||||||
|
.last_event_type = NRFX_TWIM_EVT_DONE},
|
||||||
#endif
|
#endif
|
||||||
#if NRFX_CHECK(NRFX_TWIM1_ENABLED)
|
#if NRFX_CHECK(NRFX_TWIM1_ENABLED)
|
||||||
// SPIM1 and TWIM1 share an address.
|
// SPIM1 and TWIM1 share an address.
|
||||||
{ .twim = NRFX_TWIM_INSTANCE(1),
|
{ .twim = NRFX_TWIM_INSTANCE(1),
|
||||||
.in_use = false},
|
.in_use = false,
|
||||||
|
.transferring = false,
|
||||||
|
.last_event_type = NRFX_TWIM_EVT_DONE},
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -84,9 +90,12 @@ static uint8_t twi_error_to_mp(const nrfx_err_t err) {
|
||||||
return MP_ENODEV;
|
return MP_ENODEV;
|
||||||
case NRFX_ERROR_BUSY:
|
case NRFX_ERROR_BUSY:
|
||||||
return MP_EBUSY;
|
return MP_EBUSY;
|
||||||
case NRFX_ERROR_DRV_TWI_ERR_DNACK:
|
|
||||||
case NRFX_ERROR_INVALID_ADDR:
|
case NRFX_ERROR_INVALID_ADDR:
|
||||||
|
case NRFX_ERROR_DRV_TWI_ERR_DNACK:
|
||||||
|
case NRFX_ERROR_DRV_TWI_ERR_OVERRUN:
|
||||||
return MP_EIO;
|
return MP_EIO;
|
||||||
|
case NRFX_ERROR_TIMEOUT:
|
||||||
|
return MP_ETIMEDOUT;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -94,6 +103,13 @@ static uint8_t twi_error_to_mp(const nrfx_err_t err) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void twim_event_handler(nrfx_twim_evt_t const *p_event, void *p_context) {
|
||||||
|
// this is the callback handler - sets transferring to false and records the most recent event.
|
||||||
|
twim_peripheral_t *peripheral = (twim_peripheral_t *)p_context;
|
||||||
|
peripheral->last_event_type = p_event->type;
|
||||||
|
peripheral->transferring = false;
|
||||||
|
}
|
||||||
|
|
||||||
void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) {
|
void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) {
|
||||||
if (scl->number == sda->number) {
|
if (scl->number == sda->number) {
|
||||||
raise_ValueError_invalid_pins();
|
raise_ValueError_invalid_pins();
|
||||||
|
|
@ -155,7 +171,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *
|
||||||
|
|
||||||
// About to init. If we fail after this point, common_hal_busio_i2c_deinit() will set in_use to false.
|
// About to init. If we fail after this point, common_hal_busio_i2c_deinit() will set in_use to false.
|
||||||
self->twim_peripheral->in_use = true;
|
self->twim_peripheral->in_use = true;
|
||||||
nrfx_err_t err = nrfx_twim_init(&self->twim_peripheral->twim, &config, NULL, NULL);
|
nrfx_err_t err = nrfx_twim_init(&self->twim_peripheral->twim, &config, twim_event_handler, self->twim_peripheral);
|
||||||
if (err != NRFX_SUCCESS) {
|
if (err != NRFX_SUCCESS) {
|
||||||
common_hal_busio_i2c_deinit(self);
|
common_hal_busio_i2c_deinit(self);
|
||||||
mp_raise_OSError(MP_EIO);
|
mp_raise_OSError(MP_EIO);
|
||||||
|
|
@ -238,6 +254,37 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) {
|
||||||
self->has_lock = false;
|
self->has_lock = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATIC nrfx_err_t _twim_xfer_with_timeout(busio_i2c_obj_t *self, nrfx_twim_xfer_desc_t const *p_xfer_desc, uint32_t flags) {
|
||||||
|
// does non-blocking transfer and raises and exception if it takes longer than I2C_TIMEOUT ms to complete
|
||||||
|
uint64_t deadline = supervisor_ticks_ms64() + I2C_TIMEOUT;
|
||||||
|
nrfx_err_t err = NRFX_SUCCESS;
|
||||||
|
self->twim_peripheral->transferring = true;
|
||||||
|
err = nrfx_twim_xfer(&self->twim_peripheral->twim, p_xfer_desc, flags);
|
||||||
|
if (err != NRFX_SUCCESS) {
|
||||||
|
self->twim_peripheral->transferring = false;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
while (self->twim_peripheral->transferring) {
|
||||||
|
if (supervisor_ticks_ms64() > deadline) {
|
||||||
|
self->twim_peripheral->transferring = false;
|
||||||
|
return NRFX_ERROR_TIMEOUT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (self->twim_peripheral->last_event_type) {
|
||||||
|
case NRFX_TWIM_EVT_DONE: ///< Transfer completed event.
|
||||||
|
return NRFX_SUCCESS;
|
||||||
|
case NRFX_TWIM_EVT_ADDRESS_NACK: ///< Error event: NACK received after sending the address.
|
||||||
|
return NRFX_ERROR_DRV_TWI_ERR_ANACK;
|
||||||
|
case NRFX_TWIM_EVT_BUS_ERROR: ///< Error event: An unexpected transition occurred on the bus.
|
||||||
|
case NRFX_TWIM_EVT_DATA_NACK: ///< Error event: NACK received after sending a data byte.
|
||||||
|
return NRFX_ERROR_DRV_TWI_ERR_DNACK;
|
||||||
|
case NRFX_TWIM_EVT_OVERRUN: ///< Error event: The unread data is replaced by new data.
|
||||||
|
return NRFX_ERROR_DRV_TWI_ERR_OVERRUN;
|
||||||
|
default: /// unknown error...
|
||||||
|
return NRFX_ERROR_INTERNAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
STATIC uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool stopBit) {
|
STATIC uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool stopBit) {
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
return common_hal_busio_i2c_probe(self, addr) ? 0 : MP_ENODEV;
|
return common_hal_busio_i2c_probe(self, addr) ? 0 : MP_ENODEV;
|
||||||
|
|
@ -253,7 +300,7 @@ STATIC uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
|
||||||
nrfx_twim_xfer_desc_t xfer_desc = NRFX_TWIM_XFER_DESC_TX(addr, (uint8_t *)data, xact_len);
|
nrfx_twim_xfer_desc_t xfer_desc = NRFX_TWIM_XFER_DESC_TX(addr, (uint8_t *)data, xact_len);
|
||||||
uint32_t const flags = (stopBit ? 0 : NRFX_TWIM_FLAG_TX_NO_STOP);
|
uint32_t const flags = (stopBit ? 0 : NRFX_TWIM_FLAG_TX_NO_STOP);
|
||||||
|
|
||||||
if (NRFX_SUCCESS != (err = nrfx_twim_xfer(&self->twim_peripheral->twim, &xfer_desc, flags))) {
|
if (NRFX_SUCCESS != (err = _twim_xfer_with_timeout(self, &xfer_desc, flags))) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -284,7 +331,7 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t
|
||||||
const size_t xact_len = MIN(len, I2C_MAX_XFER_LEN);
|
const size_t xact_len = MIN(len, I2C_MAX_XFER_LEN);
|
||||||
nrfx_twim_xfer_desc_t xfer_desc = NRFX_TWIM_XFER_DESC_RX(addr, data, xact_len);
|
nrfx_twim_xfer_desc_t xfer_desc = NRFX_TWIM_XFER_DESC_RX(addr, data, xact_len);
|
||||||
|
|
||||||
if (NRFX_SUCCESS != (err = nrfx_twim_xfer(&self->twim_peripheral->twim, &xfer_desc, 0))) {
|
if (NRFX_SUCCESS != (err = _twim_xfer_with_timeout(self, &xfer_desc, 0))) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,9 @@
|
||||||
typedef struct {
|
typedef struct {
|
||||||
nrfx_twim_t twim;
|
nrfx_twim_t twim;
|
||||||
bool in_use;
|
bool in_use;
|
||||||
|
volatile bool transferring;
|
||||||
|
nrfx_twim_evt_type_t last_event_type;
|
||||||
|
uint32_t timeout;
|
||||||
} twim_peripheral_t;
|
} twim_peripheral_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
||||||
|
|
@ -220,7 +220,7 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t *self,
|
||||||
&channel, &pwm_already_in_use, NULL);
|
&channel, &pwm_already_in_use, NULL);
|
||||||
|
|
||||||
if (self->pwm == NULL) {
|
if (self->pwm == NULL) {
|
||||||
return PWMOUT_ALL_TIMERS_IN_USE;
|
return PWMOUT_INTERNAL_RESOURCES_IN_USE;
|
||||||
}
|
}
|
||||||
|
|
||||||
self->channel = channel;
|
self->channel = channel;
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 3f55e49eb11e6db0da1da09e189bb094222702c9
|
Subproject commit ab21106ea57b63d97b757a9f17201ddf298ffab0
|
||||||
114
ports/raspberrypi/boards/heiafr_picomo_v2/board.c
Normal file
114
ports/raspberrypi/boards/heiafr_picomo_v2/board.c
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Scott Shawcroft for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "supervisor/board.h"
|
||||||
|
#include "mpconfigboard.h"
|
||||||
|
#include "shared-bindings/busio/SPI.h"
|
||||||
|
#include "shared-bindings/fourwire/FourWire.h"
|
||||||
|
#include "shared-module/displayio/__init__.h"
|
||||||
|
#include "shared-module/displayio/mipi_constants.h"
|
||||||
|
#include "supervisor/shared/board.h"
|
||||||
|
|
||||||
|
fourwire_fourwire_obj_t board_display_obj;
|
||||||
|
|
||||||
|
#define DELAY 0x80
|
||||||
|
|
||||||
|
uint8_t display_init_sequence[] = {
|
||||||
|
0x01, 0 | DELAY, 150, // SWRESET
|
||||||
|
|
||||||
|
0x36, 1, 0x04, // MADCTL
|
||||||
|
0x35, 1, 0x00, // TEON
|
||||||
|
0xB2, 5, 0x0c, 0x0c, 0x00, 0x33, 0x33, // FRMCTR2
|
||||||
|
0x3A, 1, 0x05, // COLMOD
|
||||||
|
0xB7, 1, 0x14, // GCTRL
|
||||||
|
0xBB, 1, 0x37, // VCOMS
|
||||||
|
0xC0, 1, 0x2c, // LCMCTRL
|
||||||
|
0xC2, 1, 0x01, // VDVVRHEN
|
||||||
|
0xC3, 1, 0x12, // VRHS
|
||||||
|
0xC4, 1, 0x20, // VDVS
|
||||||
|
0xD0, 2, 0xa4, 0xa1, // PWRCTRL1
|
||||||
|
0xC6, 1, 0x0f, // FRCTRL2
|
||||||
|
0xE0, 14, 0xd0, 0x04, 0x0d, 0x11, 0x13, 0x2b, 0x3f, 0x54, 0x4c, 0x18, 0x0d, 0x0b, 0x1f, 0x23, // GMCTRP1
|
||||||
|
0xE1, 14, 0xd0, 0x04, 0x0c, 0x11, 0x13, 0x2c, 0x3f, 0x44, 0x51, 0x2f, 0x1f, 0x1f, 0x20, 0x23, // GMCTRN1
|
||||||
|
0x21, 0, // INVON
|
||||||
|
|
||||||
|
0x11, 0 | DELAY, 255, // SLPOUT
|
||||||
|
0x29, 0 | DELAY, 100, // DISPON
|
||||||
|
|
||||||
|
0x2a, 4, 0x00, 0, 0x00, 0xfe, // CASET
|
||||||
|
0x2b, 4, 0x00, 0, 0x00, 0xfe, // RASET
|
||||||
|
0x2c, 0, // RAMWR
|
||||||
|
};
|
||||||
|
|
||||||
|
void board_init(void) {
|
||||||
|
fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus;
|
||||||
|
busio_spi_obj_t *spi = &bus->inline_bus;
|
||||||
|
common_hal_busio_spi_construct(spi, &pin_GPIO18, &pin_GPIO19, NULL, false);
|
||||||
|
common_hal_busio_spi_never_reset(spi);
|
||||||
|
|
||||||
|
bus->base.type = &fourwire_fourwire_type;
|
||||||
|
common_hal_fourwire_fourwire_construct(bus,
|
||||||
|
spi,
|
||||||
|
&pin_GPIO16, // TFT_DC Command or data
|
||||||
|
&pin_GPIO17, // TFT_CS Chip select
|
||||||
|
NULL, // TFT_RST Reset
|
||||||
|
62500000, // Baudrate
|
||||||
|
0, // Polarity
|
||||||
|
0); // Phase
|
||||||
|
|
||||||
|
busdisplay_busdisplay_obj_t *display = &allocate_display()->display;
|
||||||
|
display->base.type = &busdisplay_busdisplay_type;
|
||||||
|
common_hal_busdisplay_busdisplay_construct(display,
|
||||||
|
bus,
|
||||||
|
240, // Width
|
||||||
|
280, // Height
|
||||||
|
0, // column start
|
||||||
|
20, // row start
|
||||||
|
0, // rotation
|
||||||
|
16, // Color depth
|
||||||
|
false, // Grayscale
|
||||||
|
false, // pixels in a byte share a row. Only valid for depths < 8
|
||||||
|
1, // bytes per cell. Only valid for depths < 8
|
||||||
|
false, // reverse_pixels_in_byte. Only valid for depths < 8
|
||||||
|
true, // reverse_bytes_in_word
|
||||||
|
MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command
|
||||||
|
MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command
|
||||||
|
MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command
|
||||||
|
display_init_sequence,
|
||||||
|
sizeof(display_init_sequence),
|
||||||
|
NULL, // no backlight pin
|
||||||
|
NO_BRIGHTNESS_COMMAND,
|
||||||
|
1.0f, // brightness
|
||||||
|
false, // single_byte_bounds
|
||||||
|
false, // data_as_commands
|
||||||
|
true, // auto_refresh
|
||||||
|
60, // native_frames_per_second
|
||||||
|
true, // backlight_on_high
|
||||||
|
false, // SH1107_addressing
|
||||||
|
0); // backlight pwm frequency
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here.
|
||||||
12
ports/raspberrypi/boards/heiafr_picomo_v2/mpconfigboard.h
Normal file
12
ports/raspberrypi/boards/heiafr_picomo_v2/mpconfigboard.h
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
#define MICROPY_HW_BOARD_NAME "HEIA-FR Picomo V2"
|
||||||
|
#define MICROPY_HW_MCU_NAME "rp2040"
|
||||||
|
|
||||||
|
#define CIRCUITPY_RGB_STATUS_R (&pin_GPIO10)
|
||||||
|
#define CIRCUITPY_RGB_STATUS_G (&pin_GPIO9)
|
||||||
|
#define CIRCUITPY_RGB_STATUS_B (&pin_GPIO8)
|
||||||
|
|
||||||
|
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO21)
|
||||||
|
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO20)
|
||||||
|
|
||||||
|
#define DEFAULT_SPI_BUS_SCK (&pin_GPIO18)
|
||||||
|
#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO19)
|
||||||
18
ports/raspberrypi/boards/heiafr_picomo_v2/mpconfigboard.mk
Normal file
18
ports/raspberrypi/boards/heiafr_picomo_v2/mpconfigboard.mk
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
USB_VID = 0x2E8A
|
||||||
|
USB_PID = 0x107D
|
||||||
|
|
||||||
|
USB_PRODUCT = "Picomo V2"
|
||||||
|
USB_MANUFACTURER = "HEIA-FR"
|
||||||
|
|
||||||
|
CHIP_VARIANT = RP2040
|
||||||
|
CHIP_FAMILY = rp2
|
||||||
|
|
||||||
|
EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ"
|
||||||
|
|
||||||
|
CIRCUITPY__EVE = 1
|
||||||
|
|
||||||
|
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Register
|
||||||
|
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_ST7789
|
||||||
|
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Display_Shapes
|
||||||
|
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Display_Text
|
||||||
|
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_ProgressBar
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
// Put board-specific pico-sdk definitions here. This file must exist.
|
||||||
99
ports/raspberrypi/boards/heiafr_picomo_v2/pins.c
Normal file
99
ports/raspberrypi/boards/heiafr_picomo_v2/pins.c
Normal file
|
|
@ -0,0 +1,99 @@
|
||||||
|
#include "shared-bindings/board/__init__.h"
|
||||||
|
#include "shared-module/displayio/__init__.h"
|
||||||
|
|
||||||
|
STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
|
||||||
|
CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_SW_UP), MP_ROM_PTR(&pin_GPIO3) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_S1), MP_ROM_PTR(&pin_GPIO3) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_SW_MID), MP_ROM_PTR(&pin_GPIO4) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_S5), MP_ROM_PTR(&pin_GPIO4) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_SW_DOWN), MP_ROM_PTR(&pin_GPIO5) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_S2), MP_ROM_PTR(&pin_GPIO5) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_SW_TOPR), MP_ROM_PTR(&pin_GPIO6) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_BOOTSEL), MP_ROM_PTR(&pin_GPIO6) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_S7), MP_ROM_PTR(&pin_GPIO6) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_SW_RIGHT), MP_ROM_PTR(&pin_GPIO7) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_S4), MP_ROM_PTR(&pin_GPIO7) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_LED_B), MP_ROM_PTR(&pin_GPIO8) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_LED_G), MP_ROM_PTR(&pin_GPIO9) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_LED_R), MP_ROM_PTR(&pin_GPIO10) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_BUZZER), MP_ROM_PTR(&pin_GPIO11) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_DISP_DC), MP_ROM_PTR(&pin_GPIO16) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_DISP_CS), MP_ROM_PTR(&pin_GPIO17) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_DISP_SCL), MP_ROM_PTR(&pin_GPIO18) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_DISP_SDA), MP_ROM_PTR(&pin_GPIO19) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_TEMP_SDA), MP_ROM_PTR(&pin_GPIO20) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_TEMP_SCL), MP_ROM_PTR(&pin_GPIO21) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_SW_LEFT), MP_ROM_PTR(&pin_GPIO22) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_S3), MP_ROM_PTR(&pin_GPIO22) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_SW_TOPL), MP_ROM_PTR(&pin_GPIO23) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_S6), MP_ROM_PTR(&pin_GPIO23) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_USB_OVCUR), MP_ROM_PTR(&pin_GPIO24) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP24), MP_ROM_PTR(&pin_GPIO24) },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29) },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)},
|
||||||
|
};
|
||||||
|
MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
|
||||||
|
|
@ -119,21 +119,21 @@ pwmout_result_t pwmout_allocate(uint8_t slice, uint8_t ab_channel, bool variable
|
||||||
|
|
||||||
// Check the channel first.
|
// Check the channel first.
|
||||||
if ((channel_use & channel_use_mask) != 0) {
|
if ((channel_use & channel_use_mask) != 0) {
|
||||||
return PWMOUT_ALL_TIMERS_ON_PIN_IN_USE;
|
return PWMOUT_INTERNAL_RESOURCES_IN_USE;
|
||||||
}
|
}
|
||||||
// Now check if the slice is in use and if we can share with it.
|
// Now check if the slice is in use and if we can share with it.
|
||||||
if (target_slice_frequencies[slice] > 0) {
|
if (target_slice_frequencies[slice] > 0) {
|
||||||
// If we want to change frequency then we can't share.
|
// If we want to change frequency then we can't share.
|
||||||
if (variable_frequency) {
|
if (variable_frequency) {
|
||||||
return PWMOUT_ALL_TIMERS_ON_PIN_IN_USE;
|
return PWMOUT_VARIABLE_FREQUENCY_NOT_AVAILABLE;
|
||||||
}
|
}
|
||||||
// If the other user wants a variable frequency then we can't share either.
|
// If the other user wants a variable frequency then we can't share either.
|
||||||
if ((slice_variable_frequency & (1 << slice)) != 0) {
|
if ((slice_variable_frequency & (1 << slice)) != 0) {
|
||||||
return PWMOUT_ALL_TIMERS_ON_PIN_IN_USE;
|
return PWMOUT_INTERNAL_RESOURCES_IN_USE;
|
||||||
}
|
}
|
||||||
// If we're both fixed frequency but we don't match target frequencies then we can't share.
|
// If we're both fixed frequency but we don't match target frequencies then we can't share.
|
||||||
if (target_slice_frequencies[slice] != frequency) {
|
if (target_slice_frequencies[slice] != frequency) {
|
||||||
return PWMOUT_ALL_TIMERS_ON_PIN_IN_USE;
|
return PWMOUT_INVALID_FREQUENCY_ON_PIN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t *self,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->tim == NULL) {
|
if (self->tim == NULL) {
|
||||||
return PWMOUT_ALL_TIMERS_ON_PIN_IN_USE;
|
return PWMOUT_INTERNAL_RESOURCES_IN_USE;
|
||||||
}
|
}
|
||||||
|
|
||||||
self->duty_cycle = duty;
|
self->duty_cycle = duty;
|
||||||
|
|
|
||||||
|
|
@ -26,3 +26,9 @@ MCU_PACKAGE = UFQFPN48
|
||||||
|
|
||||||
LD_COMMON = boards/common_nvm.ld
|
LD_COMMON = boards/common_nvm.ld
|
||||||
LD_FILE = boards/STM32F411_nvm_nofs.ld
|
LD_FILE = boards/STM32F411_nvm_nofs.ld
|
||||||
|
|
||||||
|
# Disable TERMINALIO on translations with missing characters.
|
||||||
|
ifneq (,$(filter $(TRANSLATION),ja ko ru))
|
||||||
|
CIRCUITPY_TERMINALIO = 0
|
||||||
|
RELEASE_NEEDS_CLEAN_BUILD = $(CIRCUITPY_DISPLAYIO)
|
||||||
|
endif
|
||||||
|
|
|
||||||
|
|
@ -110,12 +110,12 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t *self,
|
||||||
if (tim_index < TIM_BANK_ARRAY_LEN && tim_channels_taken[tim_index] != 0) {
|
if (tim_index < TIM_BANK_ARRAY_LEN && tim_channels_taken[tim_index] != 0) {
|
||||||
// Timer has already been reserved by an internal module
|
// Timer has already been reserved by an internal module
|
||||||
if (stm_peripherals_timer_is_reserved(mcu_tim_banks[tim_index])) {
|
if (stm_peripherals_timer_is_reserved(mcu_tim_banks[tim_index])) {
|
||||||
last_failure = PWMOUT_ALL_TIMERS_ON_PIN_IN_USE;
|
last_failure = PWMOUT_INTERNAL_RESOURCES_IN_USE;
|
||||||
continue; // keep looking
|
continue; // keep looking
|
||||||
}
|
}
|
||||||
// is it the same channel? (or all channels reserved by a var-freq)
|
// is it the same channel? (or all channels reserved by a var-freq)
|
||||||
if (tim_channels_taken[tim_index] & (1 << tim_channel_index)) {
|
if (tim_channels_taken[tim_index] & (1 << tim_channel_index)) {
|
||||||
last_failure = PWMOUT_ALL_TIMERS_ON_PIN_IN_USE;
|
last_failure = PWMOUT_INTERNAL_RESOURCES_IN_USE;
|
||||||
continue; // keep looking, might be another viable option
|
continue; // keep looking, might be another viable option
|
||||||
}
|
}
|
||||||
// If the frequencies are the same it's ok
|
// If the frequencies are the same it's ok
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ extern void common_hal_mcu_enable_interrupts(void);
|
||||||
#define MICROPY_TRACKED_ALLOC (CIRCUITPY_SSL_MBEDTLS)
|
#define MICROPY_TRACKED_ALLOC (CIRCUITPY_SSL_MBEDTLS)
|
||||||
#define MICROPY_ENABLE_SOURCE_LINE (1)
|
#define MICROPY_ENABLE_SOURCE_LINE (1)
|
||||||
#define MICROPY_EPOCH_IS_1970 (1)
|
#define MICROPY_EPOCH_IS_1970 (1)
|
||||||
#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_NORMAL)
|
#define MICROPY_ERROR_REPORTING (CIRCUITPY_FULL_BUILD ? MICROPY_ERROR_REPORTING_NORMAL : MICROPY_ERROR_REPORTING_TERSE)
|
||||||
#define MICROPY_FLOAT_HIGH_QUALITY_HASH (0)
|
#define MICROPY_FLOAT_HIGH_QUALITY_HASH (0)
|
||||||
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT)
|
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT)
|
||||||
#define MICROPY_GC_ALLOC_THRESHOLD (0)
|
#define MICROPY_GC_ALLOC_THRESHOLD (0)
|
||||||
|
|
|
||||||
42
py/objdict.c
42
py/objdict.c
|
|
@ -49,6 +49,22 @@ const mp_obj_dict_t mp_const_empty_dict_obj = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// CIRCUITPY-CHANGE: Native methods are passed the subclass instance so they can
|
||||||
|
// refer to subclass members. Dict only cares about the native struct so this
|
||||||
|
// function gets it.
|
||||||
|
STATIC mp_obj_dict_t *native_dict(mp_obj_t self_in) {
|
||||||
|
// Check for OrderedDict first because it is marked as a subclass of dict. However, it doesn't
|
||||||
|
// store its state in subobj like python types to native types do.
|
||||||
|
mp_obj_t native_instance = MP_OBJ_NULL;
|
||||||
|
#if MICROPY_PY_COLLECTIONS_ORDEREDDICT
|
||||||
|
native_instance = mp_obj_cast_to_native_base(self_in, MP_OBJ_FROM_PTR(&mp_type_ordereddict));
|
||||||
|
#endif
|
||||||
|
if (native_instance == MP_OBJ_NULL) {
|
||||||
|
native_instance = mp_obj_cast_to_native_base(self_in, MP_OBJ_FROM_PTR(&mp_type_dict));
|
||||||
|
}
|
||||||
|
return MP_OBJ_TO_PTR(native_instance);
|
||||||
|
}
|
||||||
|
|
||||||
STATIC mp_obj_t dict_update(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs);
|
STATIC mp_obj_t dict_update(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs);
|
||||||
|
|
||||||
// This is a helper function to iterate through a dictionary. The state of
|
// This is a helper function to iterate through a dictionary. The state of
|
||||||
|
|
@ -71,7 +87,7 @@ STATIC mp_map_elem_t *dict_iter_next(mp_obj_dict_t *dict, size_t *cur) {
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC void dict_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
STATIC void dict_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||||
mp_obj_dict_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_obj_dict_t *self = native_dict(self_in);
|
||||||
bool first = true;
|
bool first = true;
|
||||||
const char *item_separator = ", ";
|
const char *item_separator = ", ";
|
||||||
const char *key_separator = ": ";
|
const char *key_separator = ": ";
|
||||||
|
|
@ -144,7 +160,7 @@ mp_obj_t mp_obj_dict_make_new(const mp_obj_type_t *type, size_t n_args, size_t n
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC mp_obj_t dict_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
|
STATIC mp_obj_t dict_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
|
||||||
mp_obj_dict_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_obj_dict_t *self = native_dict(self_in);
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case MP_UNARY_OP_BOOL:
|
case MP_UNARY_OP_BOOL:
|
||||||
return mp_obj_new_bool(self->map.used != 0);
|
return mp_obj_new_bool(self->map.used != 0);
|
||||||
|
|
@ -162,7 +178,7 @@ STATIC mp_obj_t dict_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC mp_obj_t dict_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
STATIC mp_obj_t dict_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||||
mp_obj_dict_t *o = MP_OBJ_TO_PTR(lhs_in);
|
mp_obj_dict_t *o = native_dict(lhs_in);
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case MP_BINARY_OP_CONTAINS: {
|
case MP_BINARY_OP_CONTAINS: {
|
||||||
mp_map_elem_t *elem = mp_map_lookup(&o->map, rhs_in, MP_MAP_LOOKUP);
|
mp_map_elem_t *elem = mp_map_lookup(&o->map, rhs_in, MP_MAP_LOOKUP);
|
||||||
|
|
@ -223,7 +239,7 @@ STATIC mp_obj_t dict_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_
|
||||||
|
|
||||||
// Note: Make sure this is inlined in load part of dict_subscr() below.
|
// Note: Make sure this is inlined in load part of dict_subscr() below.
|
||||||
mp_obj_t mp_obj_dict_get(mp_obj_t self_in, mp_obj_t index) {
|
mp_obj_t mp_obj_dict_get(mp_obj_t self_in, mp_obj_t index) {
|
||||||
mp_obj_dict_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_obj_dict_t *self = native_dict(self_in);
|
||||||
mp_map_elem_t *elem = mp_map_lookup(&self->map, index, MP_MAP_LOOKUP);
|
mp_map_elem_t *elem = mp_map_lookup(&self->map, index, MP_MAP_LOOKUP);
|
||||||
if (elem == NULL) {
|
if (elem == NULL) {
|
||||||
mp_raise_type_arg(&mp_type_KeyError, index);
|
mp_raise_type_arg(&mp_type_KeyError, index);
|
||||||
|
|
@ -239,7 +255,7 @@ STATIC mp_obj_t dict_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
} else if (value == MP_OBJ_SENTINEL) {
|
} else if (value == MP_OBJ_SENTINEL) {
|
||||||
// load
|
// load
|
||||||
mp_obj_dict_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_obj_dict_t *self = native_dict(self_in);
|
||||||
mp_map_elem_t *elem = mp_map_lookup(&self->map, index, MP_MAP_LOOKUP);
|
mp_map_elem_t *elem = mp_map_lookup(&self->map, index, MP_MAP_LOOKUP);
|
||||||
if (elem == NULL) {
|
if (elem == NULL) {
|
||||||
mp_raise_type_arg(&mp_type_KeyError, index);
|
mp_raise_type_arg(&mp_type_KeyError, index);
|
||||||
|
|
@ -264,7 +280,7 @@ STATIC void PLACE_IN_ITCM(mp_ensure_not_fixed)(const mp_obj_dict_t * dict) {
|
||||||
|
|
||||||
STATIC mp_obj_t dict_clear(mp_obj_t self_in) {
|
STATIC mp_obj_t dict_clear(mp_obj_t self_in) {
|
||||||
mp_check_self(mp_obj_is_dict_or_ordereddict(self_in));
|
mp_check_self(mp_obj_is_dict_or_ordereddict(self_in));
|
||||||
mp_obj_dict_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_obj_dict_t *self = native_dict(self_in);
|
||||||
mp_ensure_not_fixed(self);
|
mp_ensure_not_fixed(self);
|
||||||
|
|
||||||
mp_map_clear(&self->map);
|
mp_map_clear(&self->map);
|
||||||
|
|
@ -275,9 +291,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(dict_clear_obj, dict_clear);
|
||||||
|
|
||||||
mp_obj_t mp_obj_dict_copy(mp_obj_t self_in) {
|
mp_obj_t mp_obj_dict_copy(mp_obj_t self_in) {
|
||||||
mp_check_self(mp_obj_is_dict_or_ordereddict(self_in));
|
mp_check_self(mp_obj_is_dict_or_ordereddict(self_in));
|
||||||
mp_obj_dict_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_obj_dict_t *self = native_dict(self_in);
|
||||||
mp_obj_t other_out = mp_obj_new_dict(self->map.alloc);
|
mp_obj_t other_out = mp_obj_new_dict(self->map.alloc);
|
||||||
mp_obj_dict_t *other = MP_OBJ_TO_PTR(other_out);
|
mp_obj_dict_t *other = native_dict(other_out);
|
||||||
other->base.type = self->base.type;
|
other->base.type = self->base.type;
|
||||||
other->map.used = self->map.used;
|
other->map.used = self->map.used;
|
||||||
other->map.all_keys_are_qstrs = self->map.all_keys_are_qstrs;
|
other->map.all_keys_are_qstrs = self->map.all_keys_are_qstrs;
|
||||||
|
|
@ -324,7 +340,7 @@ STATIC MP_DEFINE_CONST_CLASSMETHOD_OBJ(dict_fromkeys_obj, MP_ROM_PTR(&dict_fromk
|
||||||
|
|
||||||
STATIC mp_obj_t dict_get_helper(size_t n_args, const mp_obj_t *args, mp_map_lookup_kind_t lookup_kind) {
|
STATIC mp_obj_t dict_get_helper(size_t n_args, const mp_obj_t *args, mp_map_lookup_kind_t lookup_kind) {
|
||||||
mp_check_self(mp_obj_is_dict_or_ordereddict(args[0]));
|
mp_check_self(mp_obj_is_dict_or_ordereddict(args[0]));
|
||||||
mp_obj_dict_t *self = MP_OBJ_TO_PTR(args[0]);
|
mp_obj_dict_t *self = native_dict(args[0]);
|
||||||
if (lookup_kind != MP_MAP_LOOKUP) {
|
if (lookup_kind != MP_MAP_LOOKUP) {
|
||||||
mp_ensure_not_fixed(self);
|
mp_ensure_not_fixed(self);
|
||||||
}
|
}
|
||||||
|
|
@ -369,7 +385,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(dict_setdefault_obj, 2, 3, dict_setde
|
||||||
|
|
||||||
STATIC mp_obj_t dict_popitem(mp_obj_t self_in) {
|
STATIC mp_obj_t dict_popitem(mp_obj_t self_in) {
|
||||||
mp_check_self(mp_obj_is_dict_or_ordereddict(self_in));
|
mp_check_self(mp_obj_is_dict_or_ordereddict(self_in));
|
||||||
mp_obj_dict_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_obj_dict_t *self = native_dict(self_in);
|
||||||
mp_ensure_not_fixed(self);
|
mp_ensure_not_fixed(self);
|
||||||
if (self->map.used == 0) {
|
if (self->map.used == 0) {
|
||||||
mp_raise_msg_varg(&mp_type_KeyError, MP_ERROR_TEXT("pop from empty %q"), MP_QSTR_dict);
|
mp_raise_msg_varg(&mp_type_KeyError, MP_ERROR_TEXT("pop from empty %q"), MP_QSTR_dict);
|
||||||
|
|
@ -394,7 +410,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(dict_popitem_obj, dict_popitem);
|
||||||
|
|
||||||
STATIC mp_obj_t dict_update(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
|
STATIC mp_obj_t dict_update(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
|
||||||
mp_check_self(mp_obj_is_dict_or_ordereddict(args[0]));
|
mp_check_self(mp_obj_is_dict_or_ordereddict(args[0]));
|
||||||
mp_obj_dict_t *self = MP_OBJ_TO_PTR(args[0]);
|
mp_obj_dict_t *self = native_dict(args[0]);
|
||||||
mp_ensure_not_fixed(self);
|
mp_ensure_not_fixed(self);
|
||||||
|
|
||||||
mp_arg_check_num(n_args, kwargs->used, 1, 2, true);
|
mp_arg_check_num(n_args, kwargs->used, 1, 2, true);
|
||||||
|
|
@ -520,7 +536,7 @@ typedef struct _mp_obj_dict_view_t {
|
||||||
STATIC mp_obj_t dict_view_it_iternext(mp_obj_t self_in) {
|
STATIC mp_obj_t dict_view_it_iternext(mp_obj_t self_in) {
|
||||||
mp_check_self(mp_obj_is_type(self_in, &mp_type_dict_view_it));
|
mp_check_self(mp_obj_is_type(self_in, &mp_type_dict_view_it));
|
||||||
mp_obj_dict_view_it_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_obj_dict_view_it_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
mp_map_elem_t *next = dict_iter_next(MP_OBJ_TO_PTR(self->dict), &self->cur);
|
mp_map_elem_t *next = dict_iter_next(native_dict(self->dict), &self->cur);
|
||||||
|
|
||||||
if (next == NULL) {
|
if (next == NULL) {
|
||||||
return MP_OBJ_STOP_ITERATION;
|
return MP_OBJ_STOP_ITERATION;
|
||||||
|
|
@ -726,7 +742,7 @@ size_t mp_obj_dict_len(mp_obj_t self_in) {
|
||||||
|
|
||||||
mp_obj_t mp_obj_dict_store(mp_obj_t self_in, mp_obj_t key, mp_obj_t value) {
|
mp_obj_t mp_obj_dict_store(mp_obj_t self_in, mp_obj_t key, mp_obj_t value) {
|
||||||
mp_check_self(mp_obj_is_dict_or_ordereddict(self_in));
|
mp_check_self(mp_obj_is_dict_or_ordereddict(self_in));
|
||||||
mp_obj_dict_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_obj_dict_t *self = native_dict(self_in);
|
||||||
mp_ensure_not_fixed(self);
|
mp_ensure_not_fixed(self);
|
||||||
mp_map_lookup(&self->map, key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value;
|
mp_map_lookup(&self->map, key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value;
|
||||||
return self_in;
|
return self_in;
|
||||||
|
|
|
||||||
|
|
@ -140,9 +140,9 @@ mp_obj_t mp_obj_new_int_from_float(mp_float_t val) {
|
||||||
if (u.p.exp == ((1 << MP_FLOAT_EXP_BITS) - 1)) {
|
if (u.p.exp == ((1 << MP_FLOAT_EXP_BITS) - 1)) {
|
||||||
// ...then number is Inf (positive or negative) if fraction is 0, else NaN.
|
// ...then number is Inf (positive or negative) if fraction is 0, else NaN.
|
||||||
if (u.p.frc == 0) {
|
if (u.p.frc == 0) {
|
||||||
mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("can't convert inf to int"));
|
mp_raise_msg_varg(&mp_type_OverflowError, MP_ERROR_TEXT("can't convert %s to int"), "inf");
|
||||||
} else {
|
} else {
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("can't convert NaN to int"));
|
mp_raise_ValueError_varg(MP_ERROR_TEXT("can't convert %s to int"), "NaN");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mp_fp_as_int_class_t icl = mp_classify_fp_as_int(val);
|
mp_fp_as_int_class_t icl = mp_classify_fp_as_int(val);
|
||||||
|
|
|
||||||
|
|
@ -27,22 +27,26 @@
|
||||||
#include "py/obj.h"
|
#include "py/obj.h"
|
||||||
#include "py/builtin.h"
|
#include "py/builtin.h"
|
||||||
|
|
||||||
|
// CIRCUITPY-CHANGE: These three functions are used by dict only. In CP, we hard
|
||||||
|
// code the type to dict so that subclassed types still use the native dict
|
||||||
|
// subscr. MP doesn't have this problem because it passes the native instance
|
||||||
|
// in. CP passes the subclass instance.
|
||||||
STATIC mp_obj_t op_getitem(mp_obj_t self_in, mp_obj_t key_in) {
|
STATIC mp_obj_t op_getitem(mp_obj_t self_in, mp_obj_t key_in) {
|
||||||
const mp_obj_type_t *type = mp_obj_get_type(self_in);
|
const mp_obj_type_t *type = &mp_type_dict;
|
||||||
// Note: assumes type must have subscr (only used by dict).
|
// Note: assumes type must have subscr (only used by dict).
|
||||||
return MP_OBJ_TYPE_GET_SLOT(type, subscr)(self_in, key_in, MP_OBJ_SENTINEL);
|
return MP_OBJ_TYPE_GET_SLOT(type, subscr)(self_in, key_in, MP_OBJ_SENTINEL);
|
||||||
}
|
}
|
||||||
MP_DEFINE_CONST_FUN_OBJ_2(mp_op_getitem_obj, op_getitem);
|
MP_DEFINE_CONST_FUN_OBJ_2(mp_op_getitem_obj, op_getitem);
|
||||||
|
|
||||||
STATIC mp_obj_t op_setitem(mp_obj_t self_in, mp_obj_t key_in, mp_obj_t value_in) {
|
STATIC mp_obj_t op_setitem(mp_obj_t self_in, mp_obj_t key_in, mp_obj_t value_in) {
|
||||||
const mp_obj_type_t *type = mp_obj_get_type(self_in);
|
const mp_obj_type_t *type = &mp_type_dict;
|
||||||
// Note: assumes type must have subscr (only used by dict).
|
// Note: assumes type must have subscr (only used by dict).
|
||||||
return MP_OBJ_TYPE_GET_SLOT(type, subscr)(self_in, key_in, value_in);
|
return MP_OBJ_TYPE_GET_SLOT(type, subscr)(self_in, key_in, value_in);
|
||||||
}
|
}
|
||||||
MP_DEFINE_CONST_FUN_OBJ_3(mp_op_setitem_obj, op_setitem);
|
MP_DEFINE_CONST_FUN_OBJ_3(mp_op_setitem_obj, op_setitem);
|
||||||
|
|
||||||
STATIC mp_obj_t op_delitem(mp_obj_t self_in, mp_obj_t key_in) {
|
STATIC mp_obj_t op_delitem(mp_obj_t self_in, mp_obj_t key_in) {
|
||||||
const mp_obj_type_t *type = mp_obj_get_type(self_in);
|
const mp_obj_type_t *type = &mp_type_dict;
|
||||||
// Note: assumes type must have subscr (only used by dict).
|
// Note: assumes type must have subscr (only used by dict).
|
||||||
return MP_OBJ_TYPE_GET_SLOT(type, subscr)(self_in, key_in, MP_OBJ_NULL);
|
return MP_OBJ_TYPE_GET_SLOT(type, subscr)(self_in, key_in, MP_OBJ_NULL);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1095,12 +1095,7 @@ STATIC mp_obj_t checked_fun_call(mp_obj_t self_in, size_t n_args, size_t n_kw, c
|
||||||
if (n_args > 0) {
|
if (n_args > 0) {
|
||||||
const mp_obj_type_t *arg0_type = mp_obj_get_type(args[0]);
|
const mp_obj_type_t *arg0_type = mp_obj_get_type(args[0]);
|
||||||
if (arg0_type != self->type) {
|
if (arg0_type != self->type) {
|
||||||
#if MICROPY_ERROR_REPORTING != MICROPY_ERROR_REPORTING_DETAILED
|
mp_raise_TypeError_varg(MP_ERROR_TEXT("%q must be of type %q, not %q"), MP_QSTR_self, self->type->name, arg0_type->name);
|
||||||
mp_raise_TypeError(MP_ERROR_TEXT("argument has wrong type"));
|
|
||||||
#else
|
|
||||||
mp_raise_msg_varg(&mp_type_TypeError,
|
|
||||||
MP_ERROR_TEXT("argument should be a '%q' not a '%q'"), self->type->name, arg0_type->name);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return mp_call_function_n_kw(self->fun, n_args, n_kw, args);
|
return mp_call_function_n_kw(self->fun, n_args, n_kw, args);
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ STATIC mp_obj_t bitmapfilter_morph(size_t n_args, const mp_obj_t *pos_args, mp_m
|
||||||
mp_obj_t weights = args[ARG_weights].u_obj;
|
mp_obj_t weights = args[ARG_weights].u_obj;
|
||||||
mp_obj_t obj_len = mp_obj_len(weights);
|
mp_obj_t obj_len = mp_obj_len(weights);
|
||||||
if (obj_len == MP_OBJ_NULL || !mp_obj_is_small_int(obj_len)) {
|
if (obj_len == MP_OBJ_NULL || !mp_obj_is_small_int(obj_len)) {
|
||||||
mp_raise_ValueError_varg(MP_ERROR_TEXT("%q must be of type %q, not %q"), MP_QSTR_weights, MP_QSTR_Sequence, mp_obj_get_type(weights)->name);
|
mp_raise_ValueError_varg(MP_ERROR_TEXT("%q must be of type %q, not %q"), MP_QSTR_weights, MP_QSTR_Sequence, mp_obj_get_type_qstr(weights));
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t n_weights = MP_OBJ_SMALL_INT_VALUE(obj_len);
|
size_t n_weights = MP_OBJ_SMALL_INT_VALUE(obj_len);
|
||||||
|
|
@ -608,8 +608,131 @@ STATIC mp_obj_t bitmapfilter_false_color(size_t n_args, const mp_obj_t *pos_args
|
||||||
shared_module_bitmapfilter_false_color(bitmap, mask, palette->colors);
|
shared_module_bitmapfilter_false_color(bitmap, mask, palette->colors);
|
||||||
return args[ARG_bitmap].u_obj;
|
return args[ARG_bitmap].u_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
MP_DEFINE_CONST_FUN_OBJ_KW(bitmapfilter_false_color_obj, 0, bitmapfilter_false_color);
|
MP_DEFINE_CONST_FUN_OBJ_KW(bitmapfilter_false_color_obj, 0, bitmapfilter_false_color);
|
||||||
|
|
||||||
|
#define BLEND_TABLE_SIZE (4096)
|
||||||
|
STATIC uint8_t *get_blend_table(mp_obj_t lookup, int mode) {
|
||||||
|
mp_buffer_info_t lookup_buf;
|
||||||
|
if (!mp_get_buffer(lookup, &lookup_buf, mode) || lookup_buf.len != BLEND_TABLE_SIZE) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return lookup_buf.buf;
|
||||||
|
}
|
||||||
|
//|
|
||||||
|
//| BlendFunction = Callable[[float, float], float]
|
||||||
|
//| """A function used to blend two images"""
|
||||||
|
//|
|
||||||
|
//| BlendTable = bytearray
|
||||||
|
//| """A precomputed blend table
|
||||||
|
//|
|
||||||
|
//| There is not actually a BlendTable type. The real type is actually any
|
||||||
|
//| buffer 4096 bytes in length."""
|
||||||
|
//|
|
||||||
|
//| def blend_precompute(lookup: BlendFunction, table: BlendTable | None = None) -> BlendTable:
|
||||||
|
//| """Precompute a BlendTable from a BlendFunction
|
||||||
|
//|
|
||||||
|
//| If the optional ``table`` argument is provided, an existing `BlendTable` is updated
|
||||||
|
//| with the new function values.
|
||||||
|
//|
|
||||||
|
//| The function's two arguments will range from 0 to 1. The returned value should also range from 0 to 1.
|
||||||
|
//|
|
||||||
|
//| A function to do a 33% blend of each source image could look like this:
|
||||||
|
//|
|
||||||
|
//| .. code-block:: python
|
||||||
|
//|
|
||||||
|
//| def blend_one_third(a, b):
|
||||||
|
//| return a * .33 + b * .67
|
||||||
|
//| """
|
||||||
|
//|
|
||||||
|
STATIC mp_obj_t blend_precompute(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||||
|
enum { ARG_lookup, ARG_table };
|
||||||
|
static const mp_arg_t allowed_args[] = {
|
||||||
|
{ MP_QSTR_lookup, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = MP_OBJ_NULL } },
|
||||||
|
{ MP_QSTR_table, MP_ARG_OBJ, { .u_obj = MP_ROM_NONE } },
|
||||||
|
};
|
||||||
|
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||||
|
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||||
|
|
||||||
|
mp_obj_t table = args[ARG_table].u_obj;
|
||||||
|
if (table == mp_const_none) {
|
||||||
|
table = mp_obj_new_bytearray_of_zeros(BLEND_TABLE_SIZE);
|
||||||
|
}
|
||||||
|
uint8_t *buf = get_blend_table(table, MP_BUFFER_WRITE);
|
||||||
|
if (!buf) {
|
||||||
|
mp_raise_TypeError_varg(MP_ERROR_TEXT("%q must be of type %q or %q, not %q"),
|
||||||
|
MP_QSTR_table, MP_QSTR_NoneType, MP_QSTR_WritableBuffer,
|
||||||
|
mp_obj_get_type_qstr(table));
|
||||||
|
}
|
||||||
|
shared_module_bitmapfilter_blend_precompute(args[ARG_lookup].u_obj, buf);
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_KW(bitmapfilter_blend_precompute_obj, 0, blend_precompute);
|
||||||
|
|
||||||
|
//|
|
||||||
|
//| def blend(
|
||||||
|
//| dest: displayio.Bitmap,
|
||||||
|
//| src1: displayio.Bitmap,
|
||||||
|
//| src2: displayio.Bitmap,
|
||||||
|
//| lookup: BlendFunction | BlendTable,
|
||||||
|
//| mask: displayio.Bitmap | None = None,
|
||||||
|
//| ) -> displayio.Bitmap:
|
||||||
|
//| """Blend the 'src1' and 'src2' images according to lookup function or table 'lookup'
|
||||||
|
//|
|
||||||
|
//| If ``lookup`` is a function, it is converted to a `BlendTable` by
|
||||||
|
//| internally calling blend_precompute. If a blend function is used repeatedly
|
||||||
|
//| it can be more efficient to compute it once with `blend_precompute`.
|
||||||
|
//|
|
||||||
|
//| If the mask is supplied, pixels from ``src1`` are taken unchanged in masked areas.
|
||||||
|
//|
|
||||||
|
//| The source and destination bitmaps may be the same bitmap.
|
||||||
|
//|
|
||||||
|
//| The destination bitmap is returned.
|
||||||
|
//| """
|
||||||
|
//|
|
||||||
|
|
||||||
|
STATIC mp_obj_t bitmapfilter_blend(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||||
|
enum { ARG_dest, ARG_src1, ARG_src2, ARG_lookup, ARG_mask };
|
||||||
|
static const mp_arg_t allowed_args[] = {
|
||||||
|
{ MP_QSTR_dest, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = MP_OBJ_NULL } },
|
||||||
|
{ MP_QSTR_src1, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = MP_OBJ_NULL } },
|
||||||
|
{ MP_QSTR_src2, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = MP_OBJ_NULL } },
|
||||||
|
{ MP_QSTR_lookup, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = MP_OBJ_NULL } },
|
||||||
|
{ MP_QSTR_mask, MP_ARG_OBJ, { .u_obj = MP_ROM_NONE } },
|
||||||
|
};
|
||||||
|
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||||
|
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||||
|
|
||||||
|
mp_arg_validate_type(args[ARG_dest].u_obj, &displayio_bitmap_type, MP_QSTR_dest);
|
||||||
|
displayio_bitmap_t *dest = MP_OBJ_TO_PTR(args[ARG_dest].u_obj);
|
||||||
|
|
||||||
|
mp_arg_validate_type(args[ARG_src1].u_obj, &displayio_bitmap_type, MP_QSTR_src1);
|
||||||
|
displayio_bitmap_t *src1 = MP_OBJ_TO_PTR(args[ARG_src1].u_obj);
|
||||||
|
|
||||||
|
mp_arg_validate_type(args[ARG_src2].u_obj, &displayio_bitmap_type, MP_QSTR_src2);
|
||||||
|
displayio_bitmap_t *src2 = MP_OBJ_TO_PTR(args[ARG_src2].u_obj);
|
||||||
|
|
||||||
|
mp_obj_t lookup = args[ARG_lookup].u_obj;
|
||||||
|
if (mp_obj_is_callable(lookup)) {
|
||||||
|
lookup = mp_call_function_1(MP_OBJ_FROM_PTR(&bitmapfilter_blend_precompute_obj), lookup);
|
||||||
|
}
|
||||||
|
uint8_t *lookup_buf = get_blend_table(lookup, MP_BUFFER_READ);
|
||||||
|
if (!lookup_buf) {
|
||||||
|
mp_raise_TypeError_varg(MP_ERROR_TEXT("%q must be of type %q or %q, not %q"),
|
||||||
|
MP_QSTR_lookup, MP_QSTR_callable, MP_QSTR_ReadableBuffer,
|
||||||
|
mp_obj_get_type_qstr(lookup));
|
||||||
|
}
|
||||||
|
|
||||||
|
displayio_bitmap_t *mask = NULL;
|
||||||
|
if (args[ARG_mask].u_obj != mp_const_none) {
|
||||||
|
mp_arg_validate_type(args[ARG_mask].u_obj, &displayio_bitmap_type, MP_QSTR_mask);
|
||||||
|
mask = MP_OBJ_TO_PTR(args[ARG_mask].u_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_module_bitmapfilter_blend(dest, src1, src2, mask, lookup_buf);
|
||||||
|
return args[ARG_dest].u_obj;
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_KW(bitmapfilter_blend_obj, 0, bitmapfilter_blend);
|
||||||
|
|
||||||
STATIC const mp_rom_map_elem_t bitmapfilter_module_globals_table[] = {
|
STATIC const mp_rom_map_elem_t bitmapfilter_module_globals_table[] = {
|
||||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bitmapfilter) },
|
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bitmapfilter) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_morph), MP_ROM_PTR(&bitmapfilter_morph_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_morph), MP_ROM_PTR(&bitmapfilter_morph_obj) },
|
||||||
|
|
@ -621,6 +744,8 @@ STATIC const mp_rom_map_elem_t bitmapfilter_module_globals_table[] = {
|
||||||
{ MP_ROM_QSTR(MP_QSTR_ChannelScaleOffset), MP_ROM_PTR(&bitmapfilter_channel_scale_offset_type) },
|
{ MP_ROM_QSTR(MP_QSTR_ChannelScaleOffset), MP_ROM_PTR(&bitmapfilter_channel_scale_offset_type) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_ChannelMixer), MP_ROM_PTR(&bitmapfilter_channel_mixer_type) },
|
{ MP_ROM_QSTR(MP_QSTR_ChannelMixer), MP_ROM_PTR(&bitmapfilter_channel_mixer_type) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_ChannelMixerOffset), MP_ROM_PTR(&bitmapfilter_channel_mixer_offset_type) },
|
{ MP_ROM_QSTR(MP_QSTR_ChannelMixerOffset), MP_ROM_PTR(&bitmapfilter_channel_mixer_offset_type) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_blend), MP_ROM_PTR(&bitmapfilter_blend_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_blend_precompute), MP_ROM_PTR(&bitmapfilter_blend_precompute_obj) },
|
||||||
};
|
};
|
||||||
STATIC MP_DEFINE_CONST_DICT(bitmapfilter_module_globals, bitmapfilter_module_globals_table);
|
STATIC MP_DEFINE_CONST_DICT(bitmapfilter_module_globals, bitmapfilter_module_globals_table);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,3 +73,12 @@ void shared_module_bitmapfilter_false_color(
|
||||||
displayio_bitmap_t *bitmap,
|
displayio_bitmap_t *bitmap,
|
||||||
displayio_bitmap_t *mask,
|
displayio_bitmap_t *mask,
|
||||||
_displayio_color_t palette[256]);
|
_displayio_color_t palette[256]);
|
||||||
|
|
||||||
|
void shared_module_bitmapfilter_blend_precompute(mp_obj_t fun, uint8_t lookup[4096]);
|
||||||
|
|
||||||
|
void shared_module_bitmapfilter_blend(
|
||||||
|
displayio_bitmap_t *dest,
|
||||||
|
displayio_bitmap_t *src1,
|
||||||
|
displayio_bitmap_t *src2,
|
||||||
|
displayio_bitmap_t *mask,
|
||||||
|
const uint8_t lookup[4096]);
|
||||||
|
|
|
||||||
|
|
@ -1063,10 +1063,10 @@ STATIC mp_obj_t bitmaptools_obj_blit(size_t n_args, const mp_obj_t *pos_args, mp
|
||||||
uint16_t x = mp_arg_validate_int_range(args[ARG_x].u_int, 0, destination->width, MP_QSTR_x);
|
uint16_t x = mp_arg_validate_int_range(args[ARG_x].u_int, 0, destination->width, MP_QSTR_x);
|
||||||
uint16_t y = mp_arg_validate_int_range(args[ARG_y].u_int, 0, destination->height, MP_QSTR_y);
|
uint16_t y = mp_arg_validate_int_range(args[ARG_y].u_int, 0, destination->height, MP_QSTR_y);
|
||||||
|
|
||||||
bitmaptools_rect_t lim = bitmaptools_validate_coord_range_pair(&args[ARG_x1], destination->width, destination->height);
|
|
||||||
|
|
||||||
displayio_bitmap_t *source = mp_arg_validate_type(args[ARG_source].u_obj, &displayio_bitmap_type, MP_QSTR_source_bitmap);
|
displayio_bitmap_t *source = mp_arg_validate_type(args[ARG_source].u_obj, &displayio_bitmap_type, MP_QSTR_source_bitmap);
|
||||||
|
|
||||||
|
bitmaptools_rect_t lim = bitmaptools_validate_coord_range_pair(&args[ARG_x1], source->width, source->height);
|
||||||
|
|
||||||
|
|
||||||
// ensure that the target bitmap (self) has at least as many `bits_per_value` as the source
|
// ensure that the target bitmap (self) has at least as many `bits_per_value` as the source
|
||||||
if (destination->bits_per_value < source->bits_per_value) {
|
if (destination->bits_per_value < source->bits_per_value) {
|
||||||
|
|
|
||||||
|
|
@ -46,23 +46,17 @@ void common_hal_pwmio_pwmout_raise_error(pwmout_result_t result) {
|
||||||
mp_arg_error_invalid(MP_QSTR_frequency);
|
mp_arg_error_invalid(MP_QSTR_frequency);
|
||||||
break;
|
break;
|
||||||
case PWMOUT_INVALID_FREQUENCY_ON_PIN:
|
case PWMOUT_INVALID_FREQUENCY_ON_PIN:
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("Frequency must match existing PWMOut using this timer"));
|
mp_arg_error_invalid(MP_QSTR_frequency);
|
||||||
break;
|
break;
|
||||||
case PWMOUT_VARIABLE_FREQUENCY_NOT_AVAILABLE:
|
case PWMOUT_VARIABLE_FREQUENCY_NOT_AVAILABLE:
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("Cannot vary frequency on a timer that is already in use"));
|
mp_arg_error_invalid(MP_QSTR_variable_frequency);
|
||||||
break;
|
break;
|
||||||
case PWMOUT_ALL_TIMERS_ON_PIN_IN_USE:
|
case PWMOUT_INTERNAL_RESOURCES_IN_USE:
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("All timers for this pin are in use"));
|
mp_raise_RuntimeError(MP_ERROR_TEXT("Internal resource(s) in use"));
|
||||||
break;
|
|
||||||
case PWMOUT_ALL_TIMERS_IN_USE:
|
|
||||||
mp_raise_RuntimeError(MP_ERROR_TEXT("All timers in use"));
|
|
||||||
break;
|
|
||||||
case PWMOUT_ALL_CHANNELS_IN_USE:
|
|
||||||
mp_raise_RuntimeError(MP_ERROR_TEXT("All channels in use"));
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
case PWMOUT_INITIALIZATION_ERROR:
|
case PWMOUT_INITIALIZATION_ERROR:
|
||||||
mp_raise_RuntimeError(MP_ERROR_TEXT("Could not start PWM"));
|
mp_raise_RuntimeError(MP_ERROR_TEXT("Internal error"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -268,8 +262,7 @@ STATIC mp_obj_t pwmio_pwmout_obj_set_frequency(mp_obj_t self_in, mp_obj_t freque
|
||||||
pwmio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
pwmio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
check_for_deinit(self);
|
check_for_deinit(self);
|
||||||
if (!common_hal_pwmio_pwmout_get_variable_frequency(self)) {
|
if (!common_hal_pwmio_pwmout_get_variable_frequency(self)) {
|
||||||
mp_raise_AttributeError(MP_ERROR_TEXT(
|
mp_raise_msg_varg(&mp_type_AttributeError, MP_ERROR_TEXT("Invalid %q"), MP_QSTR_variable_frequency);
|
||||||
"PWM frequency not writable when variable_frequency is False on construction."));
|
|
||||||
}
|
}
|
||||||
mp_int_t freq = mp_obj_get_int(frequency);
|
mp_int_t freq = mp_obj_get_int(frequency);
|
||||||
if (freq == 0) {
|
if (freq == 0) {
|
||||||
|
|
|
||||||
|
|
@ -38,9 +38,7 @@ typedef enum pwmout_result_t {
|
||||||
PWMOUT_INVALID_FREQUENCY,
|
PWMOUT_INVALID_FREQUENCY,
|
||||||
PWMOUT_INVALID_FREQUENCY_ON_PIN,
|
PWMOUT_INVALID_FREQUENCY_ON_PIN,
|
||||||
PWMOUT_VARIABLE_FREQUENCY_NOT_AVAILABLE,
|
PWMOUT_VARIABLE_FREQUENCY_NOT_AVAILABLE,
|
||||||
PWMOUT_ALL_TIMERS_ON_PIN_IN_USE,
|
PWMOUT_INTERNAL_RESOURCES_IN_USE,
|
||||||
PWMOUT_ALL_TIMERS_IN_USE,
|
|
||||||
PWMOUT_ALL_CHANNELS_IN_USE,
|
|
||||||
PWMOUT_INITIALIZATION_ERROR,
|
PWMOUT_INITIALIZATION_ERROR,
|
||||||
} pwmout_result_t;
|
} pwmout_result_t;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(sdcardio_sdcard_deinit_obj, sdcardio_sdcard_deinit);
|
||||||
//|
|
//|
|
||||||
//| :return: None"""
|
//| :return: None"""
|
||||||
|
|
||||||
STATIC mp_obj_t sdcardio_sdcard_readblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) {
|
STATIC mp_obj_t _sdcardio_sdcard_readblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) {
|
||||||
uint32_t start_block = mp_obj_get_int(start_block_in);
|
uint32_t start_block = mp_obj_get_int(start_block_in);
|
||||||
mp_buffer_info_t bufinfo;
|
mp_buffer_info_t bufinfo;
|
||||||
mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_WRITE);
|
mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_WRITE);
|
||||||
|
|
@ -143,7 +143,7 @@ STATIC mp_obj_t sdcardio_sdcard_readblocks(mp_obj_t self_in, mp_obj_t start_bloc
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
|
|
||||||
MP_DEFINE_CONST_FUN_OBJ_3(sdcardio_sdcard_readblocks_obj, sdcardio_sdcard_readblocks);
|
MP_DEFINE_CONST_FUN_OBJ_3(sdcardio_sdcard_readblocks_obj, _sdcardio_sdcard_readblocks);
|
||||||
|
|
||||||
//| def sync(self) -> None:
|
//| def sync(self) -> None:
|
||||||
//| """Ensure all blocks written are actually committed to the SD card
|
//| """Ensure all blocks written are actually committed to the SD card
|
||||||
|
|
@ -171,7 +171,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(sdcardio_sdcard_sync_obj, sdcardio_sdcard_sync);
|
||||||
//| :return: None"""
|
//| :return: None"""
|
||||||
//|
|
//|
|
||||||
|
|
||||||
STATIC mp_obj_t sdcardio_sdcard_writeblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) {
|
STATIC mp_obj_t _sdcardio_sdcard_writeblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) {
|
||||||
uint32_t start_block = mp_obj_get_int(start_block_in);
|
uint32_t start_block = mp_obj_get_int(start_block_in);
|
||||||
mp_buffer_info_t bufinfo;
|
mp_buffer_info_t bufinfo;
|
||||||
mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ);
|
mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ);
|
||||||
|
|
@ -182,7 +182,7 @@ STATIC mp_obj_t sdcardio_sdcard_writeblocks(mp_obj_t self_in, mp_obj_t start_blo
|
||||||
}
|
}
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
MP_DEFINE_CONST_FUN_OBJ_3(sdcardio_sdcard_writeblocks_obj, sdcardio_sdcard_writeblocks);
|
MP_DEFINE_CONST_FUN_OBJ_3(sdcardio_sdcard_writeblocks_obj, _sdcardio_sdcard_writeblocks);
|
||||||
|
|
||||||
STATIC const mp_rom_map_elem_t sdcardio_sdcard_locals_dict_table[] = {
|
STATIC const mp_rom_map_elem_t sdcardio_sdcard_locals_dict_table[] = {
|
||||||
{ MP_ROM_QSTR(MP_QSTR_count), MP_ROM_PTR(&sdcardio_sdcard_count_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_count), MP_ROM_PTR(&sdcardio_sdcard_count_obj) },
|
||||||
|
|
|
||||||
|
|
@ -27,4 +27,19 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "shared-module/sdcardio/SDCard.h"
|
||||||
|
|
||||||
extern const mp_obj_type_t sdcardio_SDCard_type;
|
extern const mp_obj_type_t sdcardio_SDCard_type;
|
||||||
|
|
||||||
|
void common_hal_sdcardio_sdcard_construct(sdcardio_sdcard_obj_t *self, busio_spi_obj_t *spi, const mcu_pin_obj_t *cs, int baudrate);
|
||||||
|
void common_hal_sdcardio_sdcard_deinit(sdcardio_sdcard_obj_t *self);
|
||||||
|
void common_hal_sdcardio_sdcard_check_for_deinit(sdcardio_sdcard_obj_t *self);
|
||||||
|
int common_hal_sdcardio_sdcard_get_blockcount(sdcardio_sdcard_obj_t *self);
|
||||||
|
int common_hal_sdcardio_sdcard_readblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf);
|
||||||
|
int common_hal_sdcardio_sdcard_sync(sdcardio_sdcard_obj_t *self);
|
||||||
|
int common_hal_sdcardio_sdcard_writeblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf);
|
||||||
|
|
||||||
|
// Used by native vfs blockdev.
|
||||||
|
mp_uint_t sdcardio_sdcard_readblocks(mp_obj_t self_in, uint8_t *buf, uint32_t start_block, uint32_t buflen);
|
||||||
|
mp_uint_t sdcardio_sdcard_writeblocks(mp_obj_t self_in, uint8_t *buf, uint32_t start_block, uint32_t buflen);
|
||||||
|
bool sdcardio_sdcard_ioctl(mp_obj_t self_in, size_t cmd, size_t arg, mp_int_t *out_value);
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(sdioio_sdcard_count_obj, sdioio_sdcard_count);
|
||||||
//| :param ~circuitpython_typing.WriteableBuffer buf: The buffer to write into. Length must be multiple of 512.
|
//| :param ~circuitpython_typing.WriteableBuffer buf: The buffer to write into. Length must be multiple of 512.
|
||||||
//|
|
//|
|
||||||
//| :return: None"""
|
//| :return: None"""
|
||||||
STATIC mp_obj_t sdioio_sdcard_readblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) {
|
STATIC mp_obj_t _sdioio_sdcard_readblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) {
|
||||||
uint32_t start_block = mp_obj_get_int(start_block_in);
|
uint32_t start_block = mp_obj_get_int(start_block_in);
|
||||||
mp_buffer_info_t bufinfo;
|
mp_buffer_info_t bufinfo;
|
||||||
mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_WRITE);
|
mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_WRITE);
|
||||||
|
|
@ -176,7 +176,7 @@ STATIC mp_obj_t sdioio_sdcard_readblocks(mp_obj_t self_in, mp_obj_t start_block_
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
|
|
||||||
MP_DEFINE_CONST_FUN_OBJ_3(sdioio_sdcard_readblocks_obj, sdioio_sdcard_readblocks);
|
MP_DEFINE_CONST_FUN_OBJ_3(sdioio_sdcard_readblocks_obj, _sdioio_sdcard_readblocks);
|
||||||
|
|
||||||
//| def writeblocks(self, start_block: int, buf: ReadableBuffer) -> None:
|
//| def writeblocks(self, start_block: int, buf: ReadableBuffer) -> None:
|
||||||
//| """Write one or more blocks to the card
|
//| """Write one or more blocks to the card
|
||||||
|
|
@ -185,7 +185,7 @@ MP_DEFINE_CONST_FUN_OBJ_3(sdioio_sdcard_readblocks_obj, sdioio_sdcard_readblocks
|
||||||
//| :param ~circuitpython_typing.ReadableBuffer buf: The buffer to read from. Length must be multiple of 512.
|
//| :param ~circuitpython_typing.ReadableBuffer buf: The buffer to read from. Length must be multiple of 512.
|
||||||
//|
|
//|
|
||||||
//| :return: None"""
|
//| :return: None"""
|
||||||
STATIC mp_obj_t sdioio_sdcard_writeblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) {
|
STATIC mp_obj_t _sdioio_sdcard_writeblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) {
|
||||||
uint32_t start_block = mp_obj_get_int(start_block_in);
|
uint32_t start_block = mp_obj_get_int(start_block_in);
|
||||||
mp_buffer_info_t bufinfo;
|
mp_buffer_info_t bufinfo;
|
||||||
mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ);
|
mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ);
|
||||||
|
|
@ -197,7 +197,7 @@ STATIC mp_obj_t sdioio_sdcard_writeblocks(mp_obj_t self_in, mp_obj_t start_block
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
|
|
||||||
MP_DEFINE_CONST_FUN_OBJ_3(sdioio_sdcard_writeblocks_obj, sdioio_sdcard_writeblocks);
|
MP_DEFINE_CONST_FUN_OBJ_3(sdioio_sdcard_writeblocks_obj, _sdioio_sdcard_writeblocks);
|
||||||
|
|
||||||
//| frequency: int
|
//| frequency: int
|
||||||
//| """The actual SDIO bus frequency. This may not match the frequency
|
//| """The actual SDIO bus frequency. This may not match the frequency
|
||||||
|
|
|
||||||
|
|
@ -130,11 +130,12 @@ STATIC mp_obj_t supervisor_set_next_code_file(size_t n_args, const mp_obj_t *pos
|
||||||
mp_arg_val_t sticky_on_reload;
|
mp_arg_val_t sticky_on_reload;
|
||||||
} args;
|
} args;
|
||||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t *)&args);
|
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t *)&args);
|
||||||
if (!mp_obj_is_str_or_bytes(args.filename.u_obj) && args.filename.u_obj != mp_const_none) {
|
mp_obj_t filename_obj = args.filename.u_obj;
|
||||||
mp_raise_TypeError(MP_ERROR_TEXT("argument has wrong type"));
|
if (!mp_obj_is_str_or_bytes(filename_obj) && filename_obj != mp_const_none) {
|
||||||
|
mp_raise_TypeError_varg(MP_ERROR_TEXT("%q must be of type %q or %q, not %q"), MP_QSTR_filename, MP_QSTR_str, MP_QSTR_None, mp_obj_get_type(filename_obj)->name);
|
||||||
}
|
}
|
||||||
if (args.filename.u_obj == mp_const_none) {
|
if (filename_obj == mp_const_none) {
|
||||||
args.filename.u_obj = mp_const_empty_bytes;
|
filename_obj = mp_const_empty_bytes;
|
||||||
}
|
}
|
||||||
uint8_t options = 0;
|
uint8_t options = 0;
|
||||||
if (args.reload_on_success.u_bool) {
|
if (args.reload_on_success.u_bool) {
|
||||||
|
|
@ -153,7 +154,7 @@ STATIC mp_obj_t supervisor_set_next_code_file(size_t n_args, const mp_obj_t *pos
|
||||||
options |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_RELOAD;
|
options |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_RELOAD;
|
||||||
}
|
}
|
||||||
size_t len;
|
size_t len;
|
||||||
const char *filename = mp_obj_str_get_data(args.filename.u_obj, &len);
|
const char *filename = mp_obj_str_get_data(filename_obj, &len);
|
||||||
if (next_code_configuration != NULL) {
|
if (next_code_configuration != NULL) {
|
||||||
port_free(next_code_configuration);
|
port_free(next_code_configuration);
|
||||||
next_code_configuration = NULL;
|
next_code_configuration = NULL;
|
||||||
|
|
|
||||||
|
|
@ -83,9 +83,7 @@ STATIC mp_obj_t time_sleep(mp_obj_t seconds_o) {
|
||||||
mp_int_t seconds = mp_obj_get_int(seconds_o);
|
mp_int_t seconds = mp_obj_get_int(seconds_o);
|
||||||
mp_int_t msecs = 1000 * seconds;
|
mp_int_t msecs = 1000 * seconds;
|
||||||
#endif
|
#endif
|
||||||
if (seconds < 0) {
|
mp_arg_validate_int_min(msecs, 0, MP_QSTR_seconds);
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("sleep length must be non-negative"));
|
|
||||||
}
|
|
||||||
common_hal_time_delay_ms(msecs);
|
common_hal_time_delay_ms(msecs);
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
|
|
@ -161,13 +159,13 @@ void struct_time_to_tm(mp_obj_t t, timeutils_struct_time_t *tm) {
|
||||||
mp_obj_t *elems;
|
mp_obj_t *elems;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
if (!mp_obj_is_type(t, &mp_type_tuple) && !mp_obj_is_type(t, (mp_obj_type_t *)&struct_time_type_obj.base)) {
|
if (!mp_obj_is_type(t, &mp_type_tuple)) {
|
||||||
mp_raise_TypeError(MP_ERROR_TEXT("Tuple or struct_time argument required"));
|
mp_arg_validate_type(t, (mp_obj_type_t *)&struct_time_type_obj.base, MP_QSTR_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_tuple_get(t, &len, &elems);
|
mp_obj_tuple_get(t, &len, &elems);
|
||||||
if (len != 9) {
|
if (len != 9) {
|
||||||
mp_raise_TypeError(MP_ERROR_TEXT("function takes exactly 9 arguments"));
|
mp_raise_TypeError_varg(MP_ERROR_TEXT("function takes %d positional arguments but %d were given"), 9, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
tm->tm_year = mp_obj_get_int(elems[0]);
|
tm->tm_year = mp_obj_get_int(elems[0]);
|
||||||
|
|
@ -277,8 +275,8 @@ STATIC mp_obj_t time_mktime(mp_obj_t t) {
|
||||||
mp_obj_t *elem;
|
mp_obj_t *elem;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
if (!mp_obj_is_type(t, &mp_type_tuple) && !mp_obj_is_type(t, (mp_obj_type_t *)&struct_time_type_obj.base)) {
|
if (!mp_obj_is_type(t, &mp_type_tuple)) {
|
||||||
mp_raise_TypeError(MP_ERROR_TEXT("Tuple or struct_time argument required"));
|
mp_arg_validate_type(t, (mp_obj_type_t *)&struct_time_type_obj.base, MP_QSTR_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_tuple_get(t, &len, &elem);
|
mp_obj_tuple_get(t, &len, &elem);
|
||||||
|
|
@ -287,7 +285,7 @@ STATIC mp_obj_t time_mktime(mp_obj_t t) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mp_obj_get_int(elem[0]) < 2000) {
|
if (mp_obj_get_int(elem[0]) < 2000) {
|
||||||
mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("timestamp out of range for platform time_t"));
|
mp_raise_msg_varg(&mp_type_OverflowError, MP_ERROR_TEXT("%q out of range"), MP_QSTR_tm_year);
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_uint_t secs = timeutils_mktime(mp_obj_get_int(elem[0]), mp_obj_get_int(elem[1]), mp_obj_get_int(elem[2]),
|
mp_uint_t secs = timeutils_mktime(mp_obj_get_int(elem[0]), mp_obj_get_int(elem[1]), mp_obj_get_int(elem[2]),
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,9 @@
|
||||||
//| in_report_lengths=(5, 2),
|
//| in_report_lengths=(5, 2),
|
||||||
//| out_report_lengths=(6, 0),
|
//| out_report_lengths=(6, 0),
|
||||||
//| )
|
//| )
|
||||||
|
//|
|
||||||
|
//| The HID device is able to wake up a suspended (sleeping) host computer.
|
||||||
|
//| See `send_report()` for details.
|
||||||
//| """
|
//| """
|
||||||
//| ...
|
//| ...
|
||||||
//| KEYBOARD: Device
|
//| KEYBOARD: Device
|
||||||
|
|
@ -166,6 +169,16 @@ STATIC mp_obj_t usb_hid_device_make_new(const mp_obj_type_t *type, size_t n_args
|
||||||
//| """Send an HID report. If the device descriptor specifies zero or one report id's,
|
//| """Send an HID report. If the device descriptor specifies zero or one report id's,
|
||||||
//| you can supply `None` (the default) as the value of ``report_id``.
|
//| you can supply `None` (the default) as the value of ``report_id``.
|
||||||
//| Otherwise you must specify which report id to use when sending the report.
|
//| Otherwise you must specify which report id to use when sending the report.
|
||||||
|
//|
|
||||||
|
//| If the USB host is suspended (sleeping), then `send_report()` will request that the host wake up.
|
||||||
|
//| The ``report`` itself will be discarded, to prevent unwanted extraneous characters,
|
||||||
|
//| mouse clicks, etc.
|
||||||
|
//|
|
||||||
|
//| Note: Host operating systems allow enabling and disabling specific devices
|
||||||
|
//| and kinds of devices to do wakeup.
|
||||||
|
//| The defaults are different for different operating systems.
|
||||||
|
//| For instance, on Linux, only the primary keyboard may be enabled.
|
||||||
|
//| In addition, there may be USB wakeup settings in the host computer BIOS/UEFI.
|
||||||
//| """
|
//| """
|
||||||
//| ...
|
//| ...
|
||||||
STATIC mp_obj_t usb_hid_device_send_report(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
STATIC mp_obj_t usb_hid_device_send_report(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@
|
||||||
#pragma GCC diagnostic ignored "-Wshadow"
|
#pragma GCC diagnostic ignored "-Wshadow"
|
||||||
|
|
||||||
static void check_matching_details(displayio_bitmap_t *b1, displayio_bitmap_t *b2) {
|
static void check_matching_details(displayio_bitmap_t *b1, displayio_bitmap_t *b2) {
|
||||||
if (b1->width != b2->width || b1->height != b2->height) {
|
if (b1->width != b2->width || b1->height != b2->height || b1->bits_per_value != b2->bits_per_value) {
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("bitmap size and depth must match"));
|
mp_raise_ValueError(MP_ERROR_TEXT("bitmap size and depth must match"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -105,8 +105,6 @@ void shared_module_bitmapfilter_morph(
|
||||||
const int32_t m_int = (int32_t)MICROPY_FLOAT_C_FUN(round)(65536 * m);
|
const int32_t m_int = (int32_t)MICROPY_FLOAT_C_FUN(round)(65536 * m);
|
||||||
const int32_t b_int = (int32_t)MICROPY_FLOAT_C_FUN(round)(65536 * COLOR_G6_MAX * b);
|
const int32_t b_int = (int32_t)MICROPY_FLOAT_C_FUN(round)(65536 * COLOR_G6_MAX * b);
|
||||||
|
|
||||||
check_matching_details(bitmap, bitmap);
|
|
||||||
|
|
||||||
switch (bitmap->bits_per_value) {
|
switch (bitmap->bits_per_value) {
|
||||||
default:
|
default:
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("unsupported bitmap depth"));
|
mp_raise_ValueError(MP_ERROR_TEXT("unsupported bitmap depth"));
|
||||||
|
|
@ -220,8 +218,6 @@ void shared_module_bitmapfilter_mix(
|
||||||
wt[i] = (int32_t)MICROPY_FLOAT_C_FUN(round)(scale * weights[i]);
|
wt[i] = (int32_t)MICROPY_FLOAT_C_FUN(round)(scale * weights[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
check_matching_details(bitmap, bitmap);
|
|
||||||
|
|
||||||
switch (bitmap->bits_per_value) {
|
switch (bitmap->bits_per_value) {
|
||||||
default:
|
default:
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("unsupported bitmap depth"));
|
mp_raise_ValueError(MP_ERROR_TEXT("unsupported bitmap depth"));
|
||||||
|
|
@ -368,3 +364,64 @@ void shared_module_bitmapfilter_false_color(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void shared_module_bitmapfilter_blend_precompute(mp_obj_t fun, uint8_t lookup[4096]) {
|
||||||
|
uint8_t *ptr = lookup;
|
||||||
|
for (int i = 0; i < 64; i++) {
|
||||||
|
mp_obj_t fi = mp_obj_new_float(i * (1 / MICROPY_FLOAT_CONST(63.)));
|
||||||
|
for (int j = 0; j < 64; j++) {
|
||||||
|
mp_obj_t fj = mp_obj_new_float(j * (1 / MICROPY_FLOAT_CONST(63.)));
|
||||||
|
mp_float_t res = mp_obj_get_float(mp_call_function_2(fun, fi, fj));
|
||||||
|
*ptr++ = res < 0 ? 0 : res > 1 ? 1 : (uint8_t)MICROPY_FLOAT_C_FUN(round)(63 * res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FIVE_TO_SIX(x) ({ int tmp = (x); (tmp << 1) | (tmp & 1); })
|
||||||
|
#define SIX_TO_FIVE(x) ((x) >> 1)
|
||||||
|
|
||||||
|
void shared_module_bitmapfilter_blend(
|
||||||
|
displayio_bitmap_t *bitmap,
|
||||||
|
displayio_bitmap_t *src1,
|
||||||
|
displayio_bitmap_t *src2,
|
||||||
|
displayio_bitmap_t *mask,
|
||||||
|
const uint8_t lookup[4096]) {
|
||||||
|
|
||||||
|
check_matching_details(bitmap, src1);
|
||||||
|
check_matching_details(bitmap, src2);
|
||||||
|
|
||||||
|
switch (bitmap->bits_per_value) {
|
||||||
|
default:
|
||||||
|
mp_raise_ValueError(MP_ERROR_TEXT("unsupported bitmap depth"));
|
||||||
|
case 16: {
|
||||||
|
for (int y = 0, yy = bitmap->height; y < yy; y++) {
|
||||||
|
uint16_t *dest_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(bitmap, y);
|
||||||
|
uint16_t *src1_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(src1, y);
|
||||||
|
uint16_t *src2_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(src2, y);
|
||||||
|
for (int x = 0, xx = bitmap->width; x < xx; x++) {
|
||||||
|
int pixel1 = IMAGE_GET_RGB565_PIXEL_FAST(src1_ptr, x);
|
||||||
|
if (mask && common_hal_displayio_bitmap_get_pixel(mask, x, y)) {
|
||||||
|
IMAGE_PUT_RGB565_PIXEL_FAST(dest_ptr, x, pixel1);
|
||||||
|
continue; // Short circuit.
|
||||||
|
}
|
||||||
|
int pixel2 = IMAGE_GET_RGB565_PIXEL_FAST(src2_ptr, x);
|
||||||
|
|
||||||
|
int r1 = FIVE_TO_SIX(COLOR_RGB565_TO_R5(pixel1));
|
||||||
|
int r2 = FIVE_TO_SIX(COLOR_RGB565_TO_R5(pixel2));
|
||||||
|
int r = SIX_TO_FIVE(lookup[r1 * 64 + r2]);
|
||||||
|
|
||||||
|
int g1 = COLOR_RGB565_TO_G6(pixel1);
|
||||||
|
int g2 = COLOR_RGB565_TO_G6(pixel2);
|
||||||
|
int g = lookup[g1 * 64 + g2];
|
||||||
|
|
||||||
|
int b1 = FIVE_TO_SIX(COLOR_RGB565_TO_B5(pixel1));
|
||||||
|
int b2 = FIVE_TO_SIX(COLOR_RGB565_TO_B5(pixel2));
|
||||||
|
int b = SIX_TO_FIVE(lookup[b1 * 64 + b2]);
|
||||||
|
|
||||||
|
int pixel = COLOR_R5_G6_B5_TO_RGB565(r, g, b);
|
||||||
|
IMAGE_PUT_RGB565_PIXEL_FAST(dest_ptr, x, pixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -507,6 +507,7 @@ void epaperdisplay_epaperdisplay_collect_ptrs(epaperdisplay_epaperdisplay_obj_t
|
||||||
displayio_display_bus_collect_ptrs(&self->bus);
|
displayio_display_bus_collect_ptrs(&self->bus);
|
||||||
gc_collect_ptr((void *)self->start_sequence);
|
gc_collect_ptr((void *)self->start_sequence);
|
||||||
gc_collect_ptr((void *)self->stop_sequence);
|
gc_collect_ptr((void *)self->stop_sequence);
|
||||||
|
gc_collect_ptr((void *)self->refresh_sequence);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t maybe_refresh_epaperdisplay(void) {
|
size_t maybe_refresh_epaperdisplay(void) {
|
||||||
|
|
|
||||||
|
|
@ -62,8 +62,12 @@ STATIC bool open_file(const char *name, file_arg *active_file) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
FATFS *fs = filesystem_circuitpy();
|
fs_user_mount_t *fs_mount = filesystem_circuitpy();
|
||||||
FRESULT result = f_open(fs, active_file, name, FA_READ);
|
if (fs_mount == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
FATFS *fatfs = &fs_mount->fatfs;
|
||||||
|
FRESULT result = f_open(fatfs, active_file, name, FA_READ);
|
||||||
return result == FR_OK;
|
return result == FR_OK;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@
|
||||||
|
|
||||||
// This implementation largely follows the structure of adafruit_sdcard.py
|
// This implementation largely follows the structure of adafruit_sdcard.py
|
||||||
|
|
||||||
|
#include "extmod/vfs.h"
|
||||||
|
|
||||||
#include "shared-bindings/busio/SPI.h"
|
#include "shared-bindings/busio/SPI.h"
|
||||||
#include "shared-bindings/digitalio/DigitalInOut.h"
|
#include "shared-bindings/digitalio/DigitalInOut.h"
|
||||||
#include "shared-bindings/sdcardio/SDCard.h"
|
#include "shared-bindings/sdcardio/SDCard.h"
|
||||||
|
|
@ -358,23 +360,24 @@ STATIC int readinto(sdcardio_sdcard_obj_t *self, void *buf, size_t size) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC int readblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf) {
|
mp_uint_t sdcardio_sdcard_readblocks(mp_obj_t self_in, uint8_t *buf, uint32_t start_block, uint32_t nblocks) {
|
||||||
uint32_t nblocks = buf->len / 512;
|
sdcardio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
if (!lock_and_configure_bus(self)) {
|
||||||
|
return MP_EAGAIN;
|
||||||
|
}
|
||||||
|
int r = 0;
|
||||||
|
size_t buflen = 512 * nblocks;
|
||||||
if (nblocks == 1) {
|
if (nblocks == 1) {
|
||||||
// Use CMD17 to read a single block
|
// Use CMD17 to read a single block
|
||||||
return block_cmd(self, 17, start_block, buf->buf, buf->len, true, true);
|
r = block_cmd(self, 17, start_block, buf, buflen, true, true);
|
||||||
} else {
|
} else {
|
||||||
// Use CMD18 to read multiple blocks
|
// Use CMD18 to read multiple blocks
|
||||||
int r = block_cmd(self, 18, start_block, NULL, 0, true, true);
|
r = block_cmd(self, 18, start_block, NULL, 0, true, true);
|
||||||
if (r < 0) {
|
uint8_t *ptr = buf;
|
||||||
return r;
|
while (nblocks-- && r >= 0) {
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t *ptr = buf->buf;
|
|
||||||
while (nblocks--) {
|
|
||||||
r = readinto(self, ptr, 512);
|
r = readinto(self, ptr, 512);
|
||||||
if (r < 0) {
|
if (r != 0) {
|
||||||
return r;
|
break;
|
||||||
}
|
}
|
||||||
ptr += 512;
|
ptr += 512;
|
||||||
}
|
}
|
||||||
|
|
@ -387,12 +390,13 @@ STATIC int readblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buff
|
||||||
uint8_t single_byte;
|
uint8_t single_byte;
|
||||||
common_hal_busio_spi_read(self->bus, &single_byte, 1, 0xff);
|
common_hal_busio_spi_read(self->bus, &single_byte, 1, 0xff);
|
||||||
if (single_byte & 0x80) {
|
if (single_byte & 0x80) {
|
||||||
return r;
|
break;
|
||||||
}
|
}
|
||||||
r = single_byte;
|
r = single_byte;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
extraclock_and_unlock_bus(self);
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int common_hal_sdcardio_sdcard_readblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf) {
|
int common_hal_sdcardio_sdcard_readblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf) {
|
||||||
|
|
@ -401,10 +405,7 @@ int common_hal_sdcardio_sdcard_readblocks(sdcardio_sdcard_obj_t *self, uint32_t
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("Buffer length must be a multiple of 512"));
|
mp_raise_ValueError(MP_ERROR_TEXT("Buffer length must be a multiple of 512"));
|
||||||
}
|
}
|
||||||
|
|
||||||
lock_and_configure_bus(self);
|
return sdcardio_sdcard_readblocks(MP_OBJ_FROM_PTR(self), buf->buf, start_block, buf->len / 512);
|
||||||
int r = readblocks(self, start_block, buf);
|
|
||||||
extraclock_and_unlock_bus(self);
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC int _write(sdcardio_sdcard_obj_t *self, uint8_t token, void *buf, size_t size) {
|
STATIC int _write(sdcardio_sdcard_obj_t *self, uint8_t token, void *buf, size_t size) {
|
||||||
|
|
@ -452,17 +453,20 @@ STATIC int _write(sdcardio_sdcard_obj_t *self, uint8_t token, void *buf, size_t
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC int writeblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf) {
|
mp_uint_t sdcardio_sdcard_writeblocks(mp_obj_t self_in, uint8_t *buf, uint32_t start_block, uint32_t nblocks) {
|
||||||
|
sdcardio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
common_hal_sdcardio_check_for_deinit(self);
|
common_hal_sdcardio_check_for_deinit(self);
|
||||||
uint32_t nblocks = buf->len / 512;
|
|
||||||
|
|
||||||
DEBUG_PRINT("cmd25? %d next_block %d start_block %d\n", self->in_cmd25, self->next_block, start_block);
|
if (!lock_and_configure_bus(self)) {
|
||||||
|
return MP_EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
if (!self->in_cmd25 || start_block != self->next_block) {
|
if (!self->in_cmd25 || start_block != self->next_block) {
|
||||||
DEBUG_PRINT("entering CMD25 at %d\n", (int)start_block);
|
DEBUG_PRINT("entering CMD25 at %d\n", (int)start_block);
|
||||||
// Use CMD25 to write multiple block
|
// Use CMD25 to write multiple block
|
||||||
int r = block_cmd(self, 25, start_block, NULL, 0, true, true);
|
int r = block_cmd(self, 25, start_block, NULL, 0, true, true);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
|
extraclock_and_unlock_bus(self);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
self->in_cmd25 = true;
|
self->in_cmd25 = true;
|
||||||
|
|
@ -470,17 +474,19 @@ STATIC int writeblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buf
|
||||||
|
|
||||||
self->next_block = start_block;
|
self->next_block = start_block;
|
||||||
|
|
||||||
uint8_t *ptr = buf->buf;
|
uint8_t *ptr = buf;
|
||||||
while (nblocks--) {
|
while (nblocks--) {
|
||||||
int r = _write(self, TOKEN_CMD25, ptr, 512);
|
int r = _write(self, TOKEN_CMD25, ptr, 512);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
self->in_cmd25 = false;
|
self->in_cmd25 = false;
|
||||||
|
extraclock_and_unlock_bus(self);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
self->next_block++;
|
self->next_block++;
|
||||||
ptr += 512;
|
ptr += 512;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extraclock_and_unlock_bus(self);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -498,7 +504,29 @@ int common_hal_sdcardio_sdcard_writeblocks(sdcardio_sdcard_obj_t *self, uint32_t
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("Buffer length must be a multiple of 512"));
|
mp_raise_ValueError(MP_ERROR_TEXT("Buffer length must be a multiple of 512"));
|
||||||
}
|
}
|
||||||
lock_and_configure_bus(self);
|
lock_and_configure_bus(self);
|
||||||
int r = writeblocks(self, start_block, buf);
|
int r = sdcardio_sdcard_writeblocks(MP_OBJ_FROM_PTR(self), buf->buf, start_block, buf->len / 512);
|
||||||
extraclock_and_unlock_bus(self);
|
extraclock_and_unlock_bus(self);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool sdcardio_sdcard_ioctl(mp_obj_t self_in, size_t cmd, size_t arg, mp_int_t *out_value) {
|
||||||
|
sdcardio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
*out_value = 0;
|
||||||
|
switch (cmd) {
|
||||||
|
case MP_BLOCKDEV_IOCTL_DEINIT:
|
||||||
|
common_hal_sdcardio_sdcard_sync(self);
|
||||||
|
break; // TODO properly
|
||||||
|
case MP_BLOCKDEV_IOCTL_SYNC:
|
||||||
|
common_hal_sdcardio_sdcard_sync(self);
|
||||||
|
break;
|
||||||
|
case MP_BLOCKDEV_IOCTL_BLOCK_COUNT:
|
||||||
|
*out_value = common_hal_sdcardio_sdcard_get_blockcount(self);
|
||||||
|
break;
|
||||||
|
case MP_BLOCKDEV_IOCTL_BLOCK_SIZE:
|
||||||
|
*out_value = 512;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,11 +44,3 @@ typedef struct {
|
||||||
uint32_t next_block;
|
uint32_t next_block;
|
||||||
bool in_cmd25;
|
bool in_cmd25;
|
||||||
} sdcardio_sdcard_obj_t;
|
} sdcardio_sdcard_obj_t;
|
||||||
|
|
||||||
void common_hal_sdcardio_sdcard_construct(sdcardio_sdcard_obj_t *self, busio_spi_obj_t *spi, const mcu_pin_obj_t *cs, int baudrate);
|
|
||||||
void common_hal_sdcardio_sdcard_deinit(sdcardio_sdcard_obj_t *self);
|
|
||||||
void common_hal_sdcardio_sdcard_check_for_deinit(sdcardio_sdcard_obj_t *self);
|
|
||||||
int common_hal_sdcardio_sdcard_get_blockcount(sdcardio_sdcard_obj_t *self);
|
|
||||||
int common_hal_sdcardio_sdcard_readblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf);
|
|
||||||
int common_hal_sdcardio_sdcard_sync(sdcardio_sdcard_obj_t *self);
|
|
||||||
int common_hal_sdcardio_sdcard_writeblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf);
|
|
||||||
|
|
|
||||||
|
|
@ -177,15 +177,20 @@ void common_hal_storage_mount(mp_obj_t vfs_obj, const char *mount_path, bool rea
|
||||||
args[0] = readonly ? mp_const_true : mp_const_false;
|
args[0] = readonly ? mp_const_true : mp_const_false;
|
||||||
args[1] = mp_const_false; // Don't make the file system automatically when mounting.
|
args[1] = mp_const_false; // Don't make the file system automatically when mounting.
|
||||||
|
|
||||||
// Check that there's no file or directory with the same name as the mount point.
|
// Check that there is a directory with the same name as the mount point.
|
||||||
// But it's ok to mount '/' in any case.
|
// But it's ok to mount '/' in any case.
|
||||||
if (strcmp(vfs->str, "/") != 0) {
|
if (strcmp(vfs->str, "/") != 0) {
|
||||||
nlr_buf_t nlr;
|
nlr_buf_t nlr;
|
||||||
if (nlr_push(&nlr) == 0) {
|
if (nlr_push(&nlr) == 0) {
|
||||||
common_hal_os_stat(mount_path);
|
mp_obj_t mount_point_stat = common_hal_os_stat(mount_path);
|
||||||
nlr_pop();
|
nlr_pop();
|
||||||
// Something with the same name exists.
|
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mount_point_stat);
|
||||||
mp_raise_OSError(MP_EEXIST);
|
if ((MP_OBJ_SMALL_INT_VALUE(t->items[0]) & MP_S_IFDIR) == 0) {
|
||||||
|
mp_raise_RuntimeError(MP_ERROR_TEXT("Mount point directory missing"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Something with the same name doesn't exist.
|
||||||
|
mp_raise_RuntimeError(MP_ERROR_TEXT("Mount point directory missing"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -229,6 +229,7 @@ void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t *
|
||||||
RUN_BACKGROUND_TASKS;
|
RUN_BACKGROUND_TASKS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!tud_suspended()) {
|
||||||
if (!tud_hid_ready()) {
|
if (!tud_hid_ready()) {
|
||||||
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("USB busy"));
|
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("USB busy"));
|
||||||
}
|
}
|
||||||
|
|
@ -236,6 +237,9 @@ void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t *
|
||||||
if (!tud_hid_report(report_id, report, len)) {
|
if (!tud_hid_report(report_id, report, len)) {
|
||||||
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("USB error"));
|
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("USB error"));
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
tud_remote_wakeup();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t common_hal_usb_hid_device_get_last_received_report(usb_hid_device_obj_t *self, uint8_t report_id) {
|
mp_obj_t common_hal_usb_hid_device_get_last_received_report(usb_hid_device_obj_t *self, uint8_t report_id) {
|
||||||
|
|
|
||||||
|
|
@ -602,7 +602,7 @@ raw_repl_reset:
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret = parse_compile_execute(&line, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF | EXEC_FLAG_SOURCE_IS_VSTR, NULL);
|
int ret = parse_compile_execute(&line, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF | EXEC_FLAG_SOURCE_IS_VSTR, NULL);
|
||||||
if (ret & PYEXEC_FORCED_EXIT) {
|
if (ret & (PYEXEC_FORCED_EXIT | PYEXEC_RELOAD)) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -739,7 +739,7 @@ friendly_repl_reset:
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = parse_compile_execute(&line, parse_input_kind, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL | EXEC_FLAG_SOURCE_IS_VSTR, NULL);
|
ret = parse_compile_execute(&line, parse_input_kind, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL | EXEC_FLAG_SOURCE_IS_VSTR, NULL);
|
||||||
if (ret & PYEXEC_FORCED_EXIT) {
|
if (ret & (PYEXEC_FORCED_EXIT | PYEXEC_RELOAD)) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,7 @@
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MICROPY_INCLUDED_SUPERVISOR_FILESYSTEM_H
|
#pragma once
|
||||||
#define MICROPY_INCLUDED_SUPERVISOR_FILESYSTEM_H
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
|
@ -45,6 +44,16 @@ void filesystem_set_concurrent_write_protection(fs_user_mount_t *vfs, bool concu
|
||||||
bool filesystem_is_writable_by_python(fs_user_mount_t *vfs);
|
bool filesystem_is_writable_by_python(fs_user_mount_t *vfs);
|
||||||
bool filesystem_is_writable_by_usb(fs_user_mount_t *vfs);
|
bool filesystem_is_writable_by_usb(fs_user_mount_t *vfs);
|
||||||
|
|
||||||
FATFS *filesystem_circuitpy(void);
|
fs_user_mount_t *filesystem_circuitpy(void);
|
||||||
|
fs_user_mount_t *filesystem_for_path(const char *path_in, const char **path_under_mount);
|
||||||
|
bool filesystem_native_fatfs(fs_user_mount_t *fs_mount);
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_SUPERVISOR_FILESYSTEM_H
|
// We have two levels of locking. filesystem_* calls grab a shared blockdev lock to allow
|
||||||
|
// CircuitPython's fatfs code edit the blocks. blockdev_* class grab a lock to mutate blocks
|
||||||
|
// directly, excluding any filesystem_* locks.
|
||||||
|
|
||||||
|
bool filesystem_lock(fs_user_mount_t *fs_mount);
|
||||||
|
void filesystem_unlock(fs_user_mount_t *fs_mount);
|
||||||
|
|
||||||
|
bool blockdev_lock(fs_user_mount_t *fs_mount);
|
||||||
|
void blockdev_unlock(fs_user_mount_t *fs_mount);
|
||||||
|
|
|
||||||
|
|
@ -126,13 +126,21 @@ void background_callback_reset() {
|
||||||
background_callback_t *cb = (background_callback_t *)callback_head;
|
background_callback_t *cb = (background_callback_t *)callback_head;
|
||||||
while (cb) {
|
while (cb) {
|
||||||
background_callback_t *next = cb->next;
|
background_callback_t *next = cb->next;
|
||||||
if (gc_ptr_on_heap((void *)cb)) {
|
|
||||||
*previous_next = cb;
|
|
||||||
previous_next = &cb->next;
|
|
||||||
cb->next = NULL;
|
cb->next = NULL;
|
||||||
new_tail = cb;
|
// Unlink any callbacks that are allocated on the python heap or if they
|
||||||
|
// reference data on the python heap. The python heap will be disappear
|
||||||
|
// soon after this.
|
||||||
|
if (gc_ptr_on_heap((void *)cb) || gc_ptr_on_heap(cb->data)) {
|
||||||
|
cb->prev = NULL; // Used to indicate a callback isn't queued.
|
||||||
} else {
|
} else {
|
||||||
memset(cb, 0, sizeof(*cb));
|
// Set .next of the previous callback.
|
||||||
|
*previous_next = cb;
|
||||||
|
// Set our .next for the next callback.
|
||||||
|
previous_next = &cb->next;
|
||||||
|
// Set our prev to the last callback.
|
||||||
|
cb->prev = new_tail;
|
||||||
|
// Now we're the tail of the list.
|
||||||
|
new_tail = cb;
|
||||||
}
|
}
|
||||||
cb = next;
|
cb = next;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,7 @@ STATIC uint64_t truncate_time(uint64_t input_time, DWORD *fattime) {
|
||||||
|
|
||||||
// Used by read and write.
|
// Used by read and write.
|
||||||
STATIC FIL active_file;
|
STATIC FIL active_file;
|
||||||
|
STATIC fs_user_mount_t *active_mount;
|
||||||
STATIC uint8_t _process_read(const uint8_t *raw_buf, size_t command_len) {
|
STATIC uint8_t _process_read(const uint8_t *raw_buf, size_t command_len) {
|
||||||
struct read_command *command = (struct read_command *)raw_buf;
|
struct read_command *command = (struct read_command *)raw_buf;
|
||||||
size_t header_size = sizeof(struct read_command);
|
size_t header_size = sizeof(struct read_command);
|
||||||
|
|
@ -170,11 +171,19 @@ STATIC uint8_t _process_read(const uint8_t *raw_buf, size_t command_len) {
|
||||||
return THIS_COMMAND;
|
return THIS_COMMAND;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *path = (char *)((uint8_t *)command) + header_size;
|
char *full_path = (char *)((uint8_t *)command) + header_size;
|
||||||
path[command->path_length] = '\0';
|
full_path[command->path_length] = '\0';
|
||||||
|
|
||||||
FATFS *fs = filesystem_circuitpy();
|
const char *mount_path;
|
||||||
FRESULT result = f_open(fs, &active_file, path, FA_READ);
|
active_mount = filesystem_for_path(full_path, &mount_path);
|
||||||
|
if (active_mount == NULL || !filesystem_native_fatfs(active_mount)) {
|
||||||
|
response.status = STATUS_ERROR;
|
||||||
|
common_hal_bleio_packet_buffer_write(&_transfer_packet_buffer, (const uint8_t *)&response, response_size, NULL, 0);
|
||||||
|
return ANY_COMMAND;
|
||||||
|
}
|
||||||
|
|
||||||
|
FATFS *fs = &active_mount->fatfs;
|
||||||
|
FRESULT result = f_open(fs, &active_file, mount_path, FA_READ);
|
||||||
if (result != FR_OK) {
|
if (result != FR_OK) {
|
||||||
response.status = STATUS_ERROR;
|
response.status = STATUS_ERROR;
|
||||||
common_hal_bleio_packet_buffer_write(&_transfer_packet_buffer, (const uint8_t *)&response, response_size, NULL, 0);
|
common_hal_bleio_packet_buffer_write(&_transfer_packet_buffer, (const uint8_t *)&response, response_size, NULL, 0);
|
||||||
|
|
@ -250,22 +259,6 @@ STATIC uint8_t _process_read_pacing(const uint8_t *raw_buf, size_t command_len)
|
||||||
STATIC size_t total_write_length;
|
STATIC size_t total_write_length;
|
||||||
STATIC uint64_t _truncated_time;
|
STATIC uint64_t _truncated_time;
|
||||||
|
|
||||||
// Returns true if usb is active and replies with an error if so. If not, it grabs
|
|
||||||
// the USB mass storage lock and returns false. Make sure to release the lock with
|
|
||||||
// usb_msc_unlock() when the transaction is complete.
|
|
||||||
STATIC bool _usb_active(void *response, size_t response_size) {
|
|
||||||
// Check to see if USB has already been mounted. If not, then we "eject" from USB until we're done.
|
|
||||||
#if CIRCUITPY_USB && CIRCUITPY_USB_MSC
|
|
||||||
if (storage_usb_enabled() && !usb_msc_lock()) {
|
|
||||||
// Status is always the second byte of the response.
|
|
||||||
((uint8_t *)response)[1] = STATUS_ERROR_READONLY;
|
|
||||||
common_hal_bleio_packet_buffer_write(&_transfer_packet_buffer, (const uint8_t *)response, response_size, NULL, 0);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC uint8_t _process_write(const uint8_t *raw_buf, size_t command_len) {
|
STATIC uint8_t _process_write(const uint8_t *raw_buf, size_t command_len) {
|
||||||
struct write_command *command = (struct write_command *)raw_buf;
|
struct write_command *command = (struct write_command *)raw_buf;
|
||||||
size_t header_size = sizeof(struct write_command);
|
size_t header_size = sizeof(struct write_command);
|
||||||
|
|
@ -284,23 +277,31 @@ STATIC uint8_t _process_write(const uint8_t *raw_buf, size_t command_len) {
|
||||||
}
|
}
|
||||||
total_write_length = command->total_length;
|
total_write_length = command->total_length;
|
||||||
|
|
||||||
char *path = (char *)command->path;
|
char *full_path = (char *)command->path;
|
||||||
path[command->path_length] = '\0';
|
full_path[command->path_length] = '\0';
|
||||||
if (_usb_active(&response, sizeof(struct write_pacing))) {
|
|
||||||
|
const char *mount_path;
|
||||||
|
active_mount = filesystem_for_path(full_path, &mount_path);
|
||||||
|
if (active_mount == NULL || !filesystem_native_fatfs(active_mount)) {
|
||||||
|
response.status = STATUS_ERROR;
|
||||||
|
common_hal_bleio_packet_buffer_write(&_transfer_packet_buffer, (const uint8_t *)&response, sizeof(struct write_pacing), NULL, 0);
|
||||||
|
return ANY_COMMAND;
|
||||||
|
}
|
||||||
|
if (!filesystem_lock(active_mount)) {
|
||||||
|
response.status = STATUS_ERROR_READONLY;
|
||||||
|
common_hal_bleio_packet_buffer_write(&_transfer_packet_buffer, (const uint8_t *)&response, sizeof(struct write_pacing), NULL, 0);
|
||||||
return ANY_COMMAND;
|
return ANY_COMMAND;
|
||||||
}
|
}
|
||||||
|
|
||||||
FATFS *fs = filesystem_circuitpy();
|
FATFS *fs = &active_mount->fatfs;
|
||||||
DWORD fattime;
|
DWORD fattime;
|
||||||
_truncated_time = truncate_time(command->modification_time, &fattime);
|
_truncated_time = truncate_time(command->modification_time, &fattime);
|
||||||
override_fattime(fattime);
|
override_fattime(fattime);
|
||||||
FRESULT result = f_open(fs, &active_file, path, FA_WRITE | FA_OPEN_ALWAYS);
|
FRESULT result = f_open(fs, &active_file, mount_path, FA_WRITE | FA_OPEN_ALWAYS);
|
||||||
if (result != FR_OK) {
|
if (result != FR_OK) {
|
||||||
response.status = STATUS_ERROR;
|
response.status = STATUS_ERROR;
|
||||||
common_hal_bleio_packet_buffer_write(&_transfer_packet_buffer, (const uint8_t *)&response, sizeof(struct write_pacing), NULL, 0);
|
common_hal_bleio_packet_buffer_write(&_transfer_packet_buffer, (const uint8_t *)&response, sizeof(struct write_pacing), NULL, 0);
|
||||||
#if CIRCUITPY_USB_MSC
|
filesystem_unlock(active_mount);
|
||||||
usb_msc_unlock();
|
|
||||||
#endif
|
|
||||||
override_fattime(0);
|
override_fattime(0);
|
||||||
return ANY_COMMAND;
|
return ANY_COMMAND;
|
||||||
}
|
}
|
||||||
|
|
@ -315,9 +316,7 @@ STATIC uint8_t _process_write(const uint8_t *raw_buf, size_t command_len) {
|
||||||
f_truncate(&active_file);
|
f_truncate(&active_file);
|
||||||
f_close(&active_file);
|
f_close(&active_file);
|
||||||
override_fattime(0);
|
override_fattime(0);
|
||||||
#if CIRCUITPY_USB_MSC
|
filesystem_unlock(active_mount);
|
||||||
usb_msc_unlock();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
response.offset = offset;
|
response.offset = offset;
|
||||||
response.free_space = chunk_size;
|
response.free_space = chunk_size;
|
||||||
|
|
@ -342,9 +341,7 @@ STATIC uint8_t _process_write_data(const uint8_t *raw_buf, size_t command_len) {
|
||||||
// TODO: throw away any more packets of path.
|
// TODO: throw away any more packets of path.
|
||||||
response.status = STATUS_ERROR;
|
response.status = STATUS_ERROR;
|
||||||
common_hal_bleio_packet_buffer_write(&_transfer_packet_buffer, (const uint8_t *)&response, sizeof(struct write_pacing), NULL, 0);
|
common_hal_bleio_packet_buffer_write(&_transfer_packet_buffer, (const uint8_t *)&response, sizeof(struct write_pacing), NULL, 0);
|
||||||
#if CIRCUITPY_USB_MSC
|
filesystem_unlock(active_mount);
|
||||||
usb_msc_unlock();
|
|
||||||
#endif
|
|
||||||
override_fattime(0);
|
override_fattime(0);
|
||||||
return ANY_COMMAND;
|
return ANY_COMMAND;
|
||||||
}
|
}
|
||||||
|
|
@ -360,9 +357,7 @@ STATIC uint8_t _process_write_data(const uint8_t *raw_buf, size_t command_len) {
|
||||||
// TODO: throw away any more packets of path.
|
// TODO: throw away any more packets of path.
|
||||||
response.status = STATUS_ERROR;
|
response.status = STATUS_ERROR;
|
||||||
common_hal_bleio_packet_buffer_write(&_transfer_packet_buffer, (const uint8_t *)&response, sizeof(struct write_pacing), NULL, 0);
|
common_hal_bleio_packet_buffer_write(&_transfer_packet_buffer, (const uint8_t *)&response, sizeof(struct write_pacing), NULL, 0);
|
||||||
#if CIRCUITPY_USB_MSC
|
filesystem_unlock(active_mount);
|
||||||
usb_msc_unlock();
|
|
||||||
#endif
|
|
||||||
override_fattime(0);
|
override_fattime(0);
|
||||||
return ANY_COMMAND;
|
return ANY_COMMAND;
|
||||||
}
|
}
|
||||||
|
|
@ -377,9 +372,7 @@ STATIC uint8_t _process_write_data(const uint8_t *raw_buf, size_t command_len) {
|
||||||
f_truncate(&active_file);
|
f_truncate(&active_file);
|
||||||
f_close(&active_file);
|
f_close(&active_file);
|
||||||
override_fattime(0);
|
override_fattime(0);
|
||||||
#if CIRCUITPY_USB_MSC
|
filesystem_unlock(active_mount);
|
||||||
usb_msc_unlock();
|
|
||||||
#endif
|
|
||||||
// Don't reload until everything is written out of the packet buffer.
|
// Don't reload until everything is written out of the packet buffer.
|
||||||
common_hal_bleio_packet_buffer_flush(&_transfer_packet_buffer);
|
common_hal_bleio_packet_buffer_flush(&_transfer_packet_buffer);
|
||||||
return ANY_COMMAND;
|
return ANY_COMMAND;
|
||||||
|
|
@ -399,29 +392,19 @@ STATIC uint8_t _process_delete(const uint8_t *raw_buf, size_t command_len) {
|
||||||
common_hal_bleio_packet_buffer_write(&_transfer_packet_buffer, (const uint8_t *)&response, sizeof(struct delete_status), NULL, 0);
|
common_hal_bleio_packet_buffer_write(&_transfer_packet_buffer, (const uint8_t *)&response, sizeof(struct delete_status), NULL, 0);
|
||||||
return ANY_COMMAND;
|
return ANY_COMMAND;
|
||||||
}
|
}
|
||||||
if (_usb_active(&response, sizeof(struct delete_status))) {
|
|
||||||
return ANY_COMMAND;
|
|
||||||
}
|
|
||||||
// We need to receive another packet to have the full path.
|
// We need to receive another packet to have the full path.
|
||||||
if (command_len < header_size + command->path_length) {
|
if (command_len < header_size + command->path_length) {
|
||||||
return THIS_COMMAND;
|
return THIS_COMMAND;
|
||||||
}
|
}
|
||||||
FATFS *fs = filesystem_circuitpy();
|
|
||||||
char *path = (char *)((uint8_t *)command) + header_size;
|
char *full_path = (char *)((uint8_t *)command) + header_size;
|
||||||
path[command->path_length] = '\0';
|
full_path[command->path_length] = '\0';
|
||||||
FILINFO file;
|
|
||||||
FRESULT result = f_stat(fs, path, &file);
|
FRESULT result = supervisor_workflow_delete_recursive(full_path);
|
||||||
if (result == FR_OK) {
|
|
||||||
if ((file.fattrib & AM_DIR) != 0) {
|
if (result == FR_WRITE_PROTECTED) {
|
||||||
result = supervisor_workflow_delete_directory_contents(fs, path);
|
response.status = STATUS_ERROR_READONLY;
|
||||||
}
|
}
|
||||||
if (result == FR_OK) {
|
|
||||||
result = f_unlink(fs, path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#if CIRCUITPY_USB_MSC
|
|
||||||
usb_msc_unlock();
|
|
||||||
#endif
|
|
||||||
if (result != FR_OK) {
|
if (result != FR_OK) {
|
||||||
response.status = STATUS_ERROR;
|
response.status = STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
@ -456,25 +439,16 @@ STATIC uint8_t _process_mkdir(const uint8_t *raw_buf, size_t command_len) {
|
||||||
common_hal_bleio_packet_buffer_write(&_transfer_packet_buffer, (const uint8_t *)&response, sizeof(struct mkdir_status), NULL, 0);
|
common_hal_bleio_packet_buffer_write(&_transfer_packet_buffer, (const uint8_t *)&response, sizeof(struct mkdir_status), NULL, 0);
|
||||||
return ANY_COMMAND;
|
return ANY_COMMAND;
|
||||||
}
|
}
|
||||||
if (_usb_active(&response, sizeof(struct mkdir_status))) {
|
|
||||||
return ANY_COMMAND;
|
|
||||||
}
|
|
||||||
// We need to receive another packet to have the full path.
|
// We need to receive another packet to have the full path.
|
||||||
if (command_len < header_size + command->path_length) {
|
if (command_len < header_size + command->path_length) {
|
||||||
return THIS_COMMAND;
|
return THIS_COMMAND;
|
||||||
}
|
}
|
||||||
FATFS *fs = filesystem_circuitpy();
|
char *full_path = (char *)command->path;
|
||||||
char *path = (char *)command->path;
|
_terminate_path(full_path, command->path_length);
|
||||||
_terminate_path(path, command->path_length);
|
|
||||||
|
|
||||||
DWORD fattime;
|
DWORD fattime;
|
||||||
response.truncated_time = truncate_time(command->modification_time, &fattime);
|
response.truncated_time = truncate_time(command->modification_time, &fattime);
|
||||||
override_fattime(fattime);
|
FRESULT result = supervisor_workflow_mkdir(fattime, full_path);
|
||||||
FRESULT result = supervisor_workflow_mkdir_parents(fs, path);
|
|
||||||
override_fattime(0);
|
|
||||||
#if CIRCUITPY_USB_MSC
|
|
||||||
usb_msc_unlock();
|
|
||||||
#endif
|
|
||||||
if (result != FR_OK) {
|
if (result != FR_OK) {
|
||||||
response.status = STATUS_ERROR;
|
response.status = STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
@ -520,12 +494,21 @@ STATIC uint8_t _process_listdir(uint8_t *raw_buf, size_t command_len) {
|
||||||
return THIS_COMMAND;
|
return THIS_COMMAND;
|
||||||
}
|
}
|
||||||
|
|
||||||
FATFS *fs = filesystem_circuitpy();
|
char *full_path = (char *)&command->path;
|
||||||
char *path = (char *)&command->path;
|
_terminate_path(full_path, command->path_length);
|
||||||
_terminate_path(path, command->path_length);
|
|
||||||
// mp_printf(&mp_plat_print, "list %s\n", path);
|
const char *mount_path;
|
||||||
|
active_mount = filesystem_for_path(full_path, &mount_path);
|
||||||
|
if (active_mount == NULL || !filesystem_native_fatfs(active_mount)) {
|
||||||
|
entry->command = LISTDIR_ENTRY;
|
||||||
|
entry->status = STATUS_ERROR_NO_FILE;
|
||||||
|
send_listdir_entry_header(entry, max_packet_size);
|
||||||
|
return ANY_COMMAND;
|
||||||
|
}
|
||||||
|
FATFS *fs = &active_mount->fatfs;
|
||||||
|
|
||||||
FF_DIR dir;
|
FF_DIR dir;
|
||||||
FRESULT res = f_opendir(fs, &dir, path);
|
FRESULT res = f_opendir(fs, &dir, mount_path);
|
||||||
|
|
||||||
entry->command = LISTDIR_ENTRY;
|
entry->command = LISTDIR_ENTRY;
|
||||||
entry->status = STATUS_OK;
|
entry->status = STATUS_OK;
|
||||||
|
|
@ -601,27 +584,21 @@ STATIC uint8_t _process_move(const uint8_t *raw_buf, size_t command_len) {
|
||||||
common_hal_bleio_packet_buffer_write(&_transfer_packet_buffer, (const uint8_t *)&response, sizeof(struct move_status), NULL, 0);
|
common_hal_bleio_packet_buffer_write(&_transfer_packet_buffer, (const uint8_t *)&response, sizeof(struct move_status), NULL, 0);
|
||||||
return ANY_COMMAND;
|
return ANY_COMMAND;
|
||||||
}
|
}
|
||||||
if (_usb_active(&response, sizeof(struct move_status))) {
|
|
||||||
return ANY_COMMAND;
|
|
||||||
}
|
|
||||||
// We need to receive another packet to have the full path.
|
// We need to receive another packet to have the full path.
|
||||||
if (command_len < header_size + total_path_length) {
|
if (command_len < header_size + total_path_length) {
|
||||||
return THIS_COMMAND;
|
return THIS_COMMAND;
|
||||||
}
|
}
|
||||||
FATFS *fs = filesystem_circuitpy();
|
|
||||||
char *old_path = (char *)command->paths;
|
char *old_path = (char *)command->paths;
|
||||||
old_path[command->old_path_length] = '\0';
|
old_path[command->old_path_length] = '\0';
|
||||||
|
|
||||||
char *new_path = old_path + command->old_path_length + 1;
|
char *new_path = old_path + command->old_path_length + 1;
|
||||||
new_path[command->new_path_length] = '\0';
|
new_path[command->new_path_length] = '\0';
|
||||||
|
|
||||||
// mp_printf(&mp_plat_print, "move %s to %s\n", old_path, new_path);
|
FRESULT result = supervisor_workflow_move(old_path, new_path);
|
||||||
|
if (result == FR_WRITE_PROTECTED) {
|
||||||
FRESULT result = f_rename(fs, old_path, new_path);
|
response.status = STATUS_ERROR_READONLY;
|
||||||
#if CIRCUITPY_USB_MSC
|
} else if (result != FR_OK) {
|
||||||
usb_msc_unlock();
|
|
||||||
#endif
|
|
||||||
if (result != FR_OK) {
|
|
||||||
response.status = STATUS_ERROR;
|
response.status = STATUS_ERROR;
|
||||||
}
|
}
|
||||||
common_hal_bleio_packet_buffer_write(&_transfer_packet_buffer, (const uint8_t *)&response, sizeof(struct move_status), NULL, 0);
|
common_hal_bleio_packet_buffer_write(&_transfer_packet_buffer, (const uint8_t *)&response, sizeof(struct move_status), NULL, 0);
|
||||||
|
|
|
||||||
|
|
@ -221,9 +221,56 @@ bool filesystem_present(void) {
|
||||||
return _mp_vfs.len > 0;
|
return _mp_vfs.len > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FATFS *filesystem_circuitpy(void) {
|
fs_user_mount_t *filesystem_circuitpy(void) {
|
||||||
if (!filesystem_present()) {
|
if (!filesystem_present()) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return &_internal_vfs.fatfs;
|
return &_internal_vfs;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs_user_mount_t *filesystem_for_path(const char *path_in, const char **path_under_mount) {
|
||||||
|
mp_vfs_mount_t *vfs = mp_vfs_lookup_path(path_in, path_under_mount);
|
||||||
|
if (vfs == MP_VFS_NONE) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
fs_user_mount_t *fs_mount;
|
||||||
|
*path_under_mount = path_in;
|
||||||
|
if (vfs == MP_VFS_ROOT) {
|
||||||
|
fs_mount = filesystem_circuitpy();
|
||||||
|
} else {
|
||||||
|
fs_mount = MP_OBJ_TO_PTR(vfs->obj);
|
||||||
|
*path_under_mount += strlen(vfs->str);
|
||||||
|
}
|
||||||
|
return fs_mount;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool filesystem_native_fatfs(fs_user_mount_t *fs_mount) {
|
||||||
|
return fs_mount->base.type == &mp_fat_vfs_type && (fs_mount->blockdev.flags & MP_BLOCKDEV_FLAG_NATIVE) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool filesystem_lock(fs_user_mount_t *fs_mount) {
|
||||||
|
if (fs_mount->lock_count == 0 && !blockdev_lock(fs_mount)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
fs_mount->lock_count += 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void filesystem_unlock(fs_user_mount_t *fs_mount) {
|
||||||
|
fs_mount->lock_count -= 1;
|
||||||
|
if (fs_mount->lock_count == 0) {
|
||||||
|
blockdev_unlock(fs_mount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool blockdev_lock(fs_user_mount_t *fs_mount) {
|
||||||
|
if ((fs_mount->blockdev.flags & MP_BLOCKDEV_FLAG_LOCKED) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
fs_mount->blockdev.flags |= MP_BLOCKDEV_FLAG_LOCKED;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void blockdev_unlock(fs_user_mount_t *fs_mount) {
|
||||||
|
fs_mount->blockdev.flags &= ~MP_BLOCKDEV_FLAG_LOCKED;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ static void build_partition(uint8_t *buf, int boot, int type, uint32_t start_blo
|
||||||
buf[15] = num_blocks >> 24;
|
buf[15] = num_blocks >> 24;
|
||||||
}
|
}
|
||||||
|
|
||||||
static mp_uint_t flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks) {
|
static mp_uint_t flash_read_blocks(mp_obj_t self, uint8_t *dest, uint32_t block_num, uint32_t num_blocks) {
|
||||||
if (block_num == 0) {
|
if (block_num == 0) {
|
||||||
// fake the MBR so we can decide on our own partition table
|
// fake the MBR so we can decide on our own partition table
|
||||||
|
|
||||||
|
|
@ -117,7 +117,7 @@ static mp_uint_t flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t n
|
||||||
|
|
||||||
static volatile bool filesystem_dirty = false;
|
static volatile bool filesystem_dirty = false;
|
||||||
|
|
||||||
static mp_uint_t flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) {
|
static mp_uint_t flash_write_blocks(mp_obj_t self, const uint8_t *src, uint32_t block_num, uint32_t num_blocks) {
|
||||||
if (block_num == 0) {
|
if (block_num == 0) {
|
||||||
if (num_blocks > 1) {
|
if (num_blocks > 1) {
|
||||||
return 1; // error
|
return 1; // error
|
||||||
|
|
@ -150,7 +150,7 @@ void PLACE_IN_ITCM(supervisor_flash_flush)(void) {
|
||||||
STATIC mp_obj_t supervisor_flash_obj_readblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) {
|
STATIC mp_obj_t supervisor_flash_obj_readblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) {
|
||||||
mp_buffer_info_t bufinfo;
|
mp_buffer_info_t bufinfo;
|
||||||
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_WRITE);
|
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_WRITE);
|
||||||
mp_uint_t ret = flash_read_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / FILESYSTEM_BLOCK_SIZE);
|
mp_uint_t ret = flash_read_blocks(self, bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / FILESYSTEM_BLOCK_SIZE);
|
||||||
return MP_OBJ_NEW_SMALL_INT(ret);
|
return MP_OBJ_NEW_SMALL_INT(ret);
|
||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(supervisor_flash_obj_readblocks_obj, supervisor_flash_obj_readblocks);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_3(supervisor_flash_obj_readblocks_obj, supervisor_flash_obj_readblocks);
|
||||||
|
|
@ -158,13 +158,15 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(supervisor_flash_obj_readblocks_obj, supervisor
|
||||||
STATIC mp_obj_t supervisor_flash_obj_writeblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) {
|
STATIC mp_obj_t supervisor_flash_obj_writeblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) {
|
||||||
mp_buffer_info_t bufinfo;
|
mp_buffer_info_t bufinfo;
|
||||||
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ);
|
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ);
|
||||||
mp_uint_t ret = flash_write_blocks(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / FILESYSTEM_BLOCK_SIZE);
|
mp_uint_t ret = flash_write_blocks(self, bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / FILESYSTEM_BLOCK_SIZE);
|
||||||
return MP_OBJ_NEW_SMALL_INT(ret);
|
return MP_OBJ_NEW_SMALL_INT(ret);
|
||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(supervisor_flash_obj_writeblocks_obj, supervisor_flash_obj_writeblocks);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_3(supervisor_flash_obj_writeblocks_obj, supervisor_flash_obj_writeblocks);
|
||||||
|
|
||||||
static bool flash_ioctl(size_t cmd, mp_int_t *out_value) {
|
STATIC bool flash_ioctl(mp_obj_t self_in, size_t cmd, size_t arg, mp_int_t *out_value) {
|
||||||
|
if (out_value != NULL) {
|
||||||
*out_value = 0;
|
*out_value = 0;
|
||||||
|
}
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case MP_BLOCKDEV_IOCTL_INIT:
|
case MP_BLOCKDEV_IOCTL_INIT:
|
||||||
supervisor_flash_init();
|
supervisor_flash_init();
|
||||||
|
|
@ -189,8 +191,9 @@ static bool flash_ioctl(size_t cmd, mp_int_t *out_value) {
|
||||||
|
|
||||||
STATIC mp_obj_t supervisor_flash_obj_ioctl(mp_obj_t self, mp_obj_t cmd_in, mp_obj_t arg_in) {
|
STATIC mp_obj_t supervisor_flash_obj_ioctl(mp_obj_t self, mp_obj_t cmd_in, mp_obj_t arg_in) {
|
||||||
mp_int_t cmd = mp_obj_get_int(cmd_in);
|
mp_int_t cmd = mp_obj_get_int(cmd_in);
|
||||||
|
mp_int_t arg = mp_obj_get_int(arg_in);
|
||||||
mp_int_t out_value;
|
mp_int_t out_value;
|
||||||
if (flash_ioctl(cmd, &out_value)) {
|
if (flash_ioctl(self, cmd, arg, &out_value)) {
|
||||||
return MP_OBJ_NEW_SMALL_INT(out_value);
|
return MP_OBJ_NEW_SMALL_INT(out_value);
|
||||||
}
|
}
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue