Compare commits
1 Commits
v1.24-tonb
...
main-tonbe
| Author | SHA1 | Date | |
|---|---|---|---|
| 9fdf5586f5 |
30
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
30
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -11,10 +11,19 @@ body:
|
|||||||
|
|
||||||
* If you have a question \"How Do I ...?\", please post it on [GitHub Discussions](https://github.com/orgs/micropython/discussions/) or [Discord](https://discord.gg/RB8HZSAExQ) instead of here.
|
* If you have a question \"How Do I ...?\", please post it on [GitHub Discussions](https://github.com/orgs/micropython/discussions/) or [Discord](https://discord.gg/RB8HZSAExQ) instead of here.
|
||||||
* For missing or incorrect documentation, or feature requests, then please [choose a different issue type](https://github.com/micropython/micropython/issues/new/choose).
|
* For missing or incorrect documentation, or feature requests, then please [choose a different issue type](https://github.com/micropython/micropython/issues/new/choose).
|
||||||
|
- type: checkboxes
|
||||||
#### Existing issue?
|
id: terms
|
||||||
|
attributes:
|
||||||
* Please search for [existing issues](https://github.com/micropython/micropython/issues) matching this bug before reporting.
|
label: Checks
|
||||||
|
description: |
|
||||||
|
Before submitting your bug report, please go over these check points:
|
||||||
|
options:
|
||||||
|
- label: |
|
||||||
|
I agree to follow the MicroPython [Code of Conduct](https://github.com/micropython/micropython/blob/master/CODEOFCONDUCT.md) to ensure a safe and respectful space for everyone.
|
||||||
|
required: true
|
||||||
|
- label: |
|
||||||
|
I've searched for [existing issues](https://github.com/micropython/micropython/issues) matching this bug, and didn't find any.
|
||||||
|
required: true
|
||||||
- type: input
|
- type: input
|
||||||
id: port-board-hw
|
id: port-board-hw
|
||||||
attributes:
|
attributes:
|
||||||
@@ -24,7 +33,7 @@ body:
|
|||||||
placeholder: |
|
placeholder: |
|
||||||
esp32 port, ESP32-Fantastic board.
|
esp32 port, ESP32-Fantastic board.
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: textarea
|
- type: textarea
|
||||||
id: version
|
id: version
|
||||||
attributes:
|
attributes:
|
||||||
@@ -92,17 +101,6 @@ body:
|
|||||||
description: |
|
description: |
|
||||||
Is there anything else that might help to resolve this issue?
|
Is there anything else that might help to resolve this issue?
|
||||||
value: No, I've provided everything above.
|
value: No, I've provided everything above.
|
||||||
- type: dropdown
|
|
||||||
id: code-of-conduct
|
|
||||||
attributes:
|
|
||||||
label: Code of Conduct
|
|
||||||
description: |
|
|
||||||
Do you agree to follow the MicroPython [Code of Conduct](https://github.com/micropython/micropython/blob/master/CODEOFCONDUCT.md) to ensure a safe and respectful space for everyone?
|
|
||||||
options:
|
|
||||||
- "Yes, I agree"
|
|
||||||
multiple: true
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
value: |
|
value: |
|
||||||
|
|||||||
28
.github/ISSUE_TEMPLATE/documentation.yml
vendored
28
.github/ISSUE_TEMPLATE/documentation.yml
vendored
@@ -9,10 +9,19 @@ body:
|
|||||||
This form is for reporting issues with the documentation or examples provided with MicroPython.
|
This form is for reporting issues with the documentation or examples provided with MicroPython.
|
||||||
|
|
||||||
If you have a general question \"How Do I ...?\", please post it on [GitHub Discussions](https://github.com/orgs/micropython/discussions/) or [Discord](https://discord.gg/RB8HZSAExQ) instead of here.
|
If you have a general question \"How Do I ...?\", please post it on [GitHub Discussions](https://github.com/orgs/micropython/discussions/) or [Discord](https://discord.gg/RB8HZSAExQ) instead of here.
|
||||||
|
- type: checkboxes
|
||||||
#### Existing issue?
|
id: terms
|
||||||
|
attributes:
|
||||||
* Please search for [existing issues](https://github.com/micropython/micropython/issues) before reporting a new one.
|
label: Checks
|
||||||
|
description: |
|
||||||
|
Before submitting your bug report, please go over these check points:
|
||||||
|
options:
|
||||||
|
- label: |
|
||||||
|
I agree to follow the MicroPython [Code of Conduct](https://github.com/micropython/micropython/blob/master/CODEOFCONDUCT.md) to ensure a safe and respectful space for everyone.
|
||||||
|
required: true
|
||||||
|
- label: |
|
||||||
|
I've searched for [existing issues](https://github.com/micropython/micropython/issues) and didn't find any that matched.
|
||||||
|
required: true
|
||||||
- type: input
|
- type: input
|
||||||
id: page
|
id: page
|
||||||
attributes:
|
attributes:
|
||||||
@@ -29,17 +38,6 @@ body:
|
|||||||
Please describe what was missing from the documentation and/or what was incorrect/incomplete.
|
Please describe what was missing from the documentation and/or what was incorrect/incomplete.
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: dropdown
|
|
||||||
id: code-of-conduct
|
|
||||||
attributes:
|
|
||||||
label: Code of Conduct
|
|
||||||
description: |
|
|
||||||
Do you agree to follow the MicroPython [Code of Conduct](https://github.com/micropython/micropython/blob/master/CODEOFCONDUCT.md) to ensure a safe and respectful space for everyone?
|
|
||||||
options:
|
|
||||||
- "Yes, I agree"
|
|
||||||
multiple: true
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
value: |
|
value: |
|
||||||
|
|||||||
43
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
43
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
@@ -15,10 +15,19 @@ body:
|
|||||||
|
|
||||||
* If you have a question \"How Do I ...?\", please post it on GitHub Discussions or Discord instead of here.
|
* If you have a question \"How Do I ...?\", please post it on GitHub Discussions or Discord instead of here.
|
||||||
* Could this feature be implemented as a pure Python library? If so, please open the request on the [micropython-lib repository](https://github.com/micropython/micropython-lib/issues) instead.
|
* Could this feature be implemented as a pure Python library? If so, please open the request on the [micropython-lib repository](https://github.com/micropython/micropython-lib/issues) instead.
|
||||||
|
- type: checkboxes
|
||||||
#### Existing issue?
|
id: terms
|
||||||
|
attributes:
|
||||||
* Please search for [existing issues](https://github.com/micropython/micropython/issues) before opening a new one.
|
label: Checks
|
||||||
|
description: |
|
||||||
|
Before submitting your feature request, please go over these check points:
|
||||||
|
options:
|
||||||
|
- label: |
|
||||||
|
I agree to follow the MicroPython [Code of Conduct](https://github.com/micropython/micropython/blob/master/CODEOFCONDUCT.md) to ensure a safe and respectful space for everyone.
|
||||||
|
required: true
|
||||||
|
- label: |
|
||||||
|
I've searched for [existing issues](https://github.com/micropython/micropython/issues) regarding this feature, and didn't find any.
|
||||||
|
required: true
|
||||||
- type: textarea
|
- type: textarea
|
||||||
id: feature
|
id: feature
|
||||||
attributes:
|
attributes:
|
||||||
@@ -42,32 +51,14 @@ body:
|
|||||||
MicroPython aims to strike a balance between functionality and code size. Can this feature be optionally enabled?
|
MicroPython aims to strike a balance between functionality and code size. Can this feature be optionally enabled?
|
||||||
|
|
||||||
If you believe the usefulness of this feature would outweigh the additional code size, please explain. (It's OK to say you're unsure here, we're happy to discuss this with you.)
|
If you believe the usefulness of this feature would outweigh the additional code size, please explain. (It's OK to say you're unsure here, we're happy to discuss this with you.)
|
||||||
- type: dropdown
|
- type: checkboxes
|
||||||
id: implementation
|
id: implementation
|
||||||
attributes:
|
attributes:
|
||||||
label: Implementation
|
label: Implementation
|
||||||
description: |
|
|
||||||
What is your suggestion for implementing this feature?
|
|
||||||
|
|
||||||
(See also: [How to sponsor](https://github.com/sponsors/micropython#sponsors), [How to submit a Pull Request](https://github.com/micropython/micropython/wiki/ContributorGuidelines).)
|
|
||||||
options:
|
options:
|
||||||
- I hope the MicroPython maintainers or community will implement this feature
|
- label: I intend to implement this feature and would submit a Pull Request if desirable.
|
||||||
- I intend to implement this feature and would submit a Pull Request if desirable
|
- label: I hope the MicroPython maintainers or community will implement this feature.
|
||||||
- I would like to sponsor development of this feature
|
- label: I would like to [Sponsor](https://github.com/sponsors/micropython#sponsors) development of this feature.
|
||||||
multiple: true
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: dropdown
|
|
||||||
id: code-of-conduct
|
|
||||||
attributes:
|
|
||||||
label: Code of Conduct
|
|
||||||
description: |
|
|
||||||
Do you agree to follow the MicroPython [Code of Conduct](https://github.com/micropython/micropython/blob/master/CODEOFCONDUCT.md) to ensure a safe and respectful space for everyone?
|
|
||||||
options:
|
|
||||||
- "Yes, I agree"
|
|
||||||
multiple: true
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
value: |
|
value: |
|
||||||
|
|||||||
31
.github/ISSUE_TEMPLATE/security.yml
vendored
31
.github/ISSUE_TEMPLATE/security.yml
vendored
@@ -9,11 +9,21 @@ body:
|
|||||||
|
|
||||||
1. For issues that are readily exploitable or have high impact, please email contact@micropython.org instead.
|
1. For issues that are readily exploitable or have high impact, please email contact@micropython.org instead.
|
||||||
1. If this is a question about security, please ask it in [Discussions](https://github.com/orgs/micropython/discussions/) or [Discord](https://discord.gg/RB8HZSAExQ) instead.
|
1. If this is a question about security, please ask it in [Discussions](https://github.com/orgs/micropython/discussions/) or [Discord](https://discord.gg/RB8HZSAExQ) instead.
|
||||||
|
- type: checkboxes
|
||||||
#### Existing issue?
|
id: terms
|
||||||
|
attributes:
|
||||||
* Please search for [existing issues](https://github.com/micropython/micropython/issues) before reporting a new one.
|
label: Checks
|
||||||
|
description: |
|
||||||
|
Before submitting your bug report, please go over these check points:
|
||||||
|
options:
|
||||||
|
- label: |
|
||||||
|
I agree to follow the MicroPython [Code of Conduct](https://github.com/micropython/micropython/blob/master/CODEOFCONDUCT.md) to ensure a safe and respectful space for everyone.
|
||||||
|
required: true
|
||||||
|
- label: I wish to report a specific security issue that is **not readily exploitable and does not have high impact** for MicroPython developers or users.
|
||||||
|
required: true
|
||||||
|
- label: |
|
||||||
|
I've searched for [existing issues](https://github.com/micropython/micropython/issues) and didn't find any that matched.
|
||||||
|
required: true
|
||||||
- type: input
|
- type: input
|
||||||
id: port-board-hw
|
id: port-board-hw
|
||||||
attributes:
|
attributes:
|
||||||
@@ -47,14 +57,3 @@ body:
|
|||||||
* How does the attacker exploit this issue?
|
* How does the attacker exploit this issue?
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: dropdown
|
|
||||||
id: code-of-conduct
|
|
||||||
attributes:
|
|
||||||
label: Code of Conduct
|
|
||||||
description: |
|
|
||||||
Do you agree to follow the MicroPython [Code of Conduct](https://github.com/micropython/micropython/blob/master/CODEOFCONDUCT.md) to ensure a safe and respectful space for everyone?
|
|
||||||
options:
|
|
||||||
- "Yes, I agree"
|
|
||||||
multiple: true
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|||||||
33
.github/pull_request_template.md
vendored
33
.github/pull_request_template.md
vendored
@@ -1,33 +0,0 @@
|
|||||||
<!-- Thanks for submitting a Pull Request! We appreciate you spending the
|
|
||||||
time to improve MicroPython. Please provide enough information so that
|
|
||||||
others can review your Pull Request.
|
|
||||||
|
|
||||||
Before submitting, please read:
|
|
||||||
https://github.com/micropython/micropython/blob/master/CODEOFCONDUCT.md
|
|
||||||
https://github.com/micropython/micropython/wiki/ContributorGuidelines
|
|
||||||
|
|
||||||
Please check any CI failures that appear after your Pull Request is opened.
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Summary
|
|
||||||
|
|
||||||
<!-- Explain the reason for making this change. What problem does the pull request
|
|
||||||
solve, or what improvement does it add? Add links if relevant. -->
|
|
||||||
|
|
||||||
|
|
||||||
### Testing
|
|
||||||
|
|
||||||
<!-- Explain what testing you did, and on which boards/ports. If there are
|
|
||||||
boards or ports that you couldn't test, please mention this here as well.
|
|
||||||
|
|
||||||
If you leave this empty then your Pull Request may be closed. -->
|
|
||||||
|
|
||||||
|
|
||||||
### Trade-offs and Alternatives
|
|
||||||
|
|
||||||
<!-- If the Pull Request has some negative impact (i.e. increased code size)
|
|
||||||
then please explain why you think the trade-off improvement is worth it.
|
|
||||||
If you can think of alternative ways to do this, please explain that here too.
|
|
||||||
|
|
||||||
Delete this heading if not relevant (i.e. small fixes) -->
|
|
||||||
|
|
||||||
2
.github/workflows/code_size.yml
vendored
2
.github/workflows/code_size.yml
vendored
@@ -24,7 +24,7 @@ concurrency:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
|
|||||||
2
.github/workflows/code_size_comment.yml
vendored
2
.github/workflows/code_size_comment.yml
vendored
@@ -11,7 +11,7 @@ concurrency:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
comment:
|
comment:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- name: 'Download artifact'
|
- name: 'Download artifact'
|
||||||
id: download-artifact
|
id: download-artifact
|
||||||
|
|||||||
32
.github/workflows/ports_qemu-arm.yml
vendored
Normal file
32
.github/workflows/ports_qemu-arm.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
name: qemu-arm port
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/*.yml'
|
||||||
|
- 'tools/**'
|
||||||
|
- 'py/**'
|
||||||
|
- 'extmod/**'
|
||||||
|
- 'shared/**'
|
||||||
|
- 'lib/**'
|
||||||
|
- 'drivers/**'
|
||||||
|
- 'ports/qemu-arm/**'
|
||||||
|
- 'tests/**'
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build_and_test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Install packages
|
||||||
|
run: source tools/ci.sh && ci_qemu_arm_setup
|
||||||
|
- name: Build and run test suite
|
||||||
|
run: source tools/ci.sh && ci_qemu_arm_build
|
||||||
|
- name: Print failures
|
||||||
|
if: failure()
|
||||||
|
run: grep --before-context=100 --text "FAIL" ports/qemu-arm/build/console.out
|
||||||
44
.github/workflows/ports_qemu.yml
vendored
44
.github/workflows/ports_qemu.yml
vendored
@@ -1,44 +0,0 @@
|
|||||||
name: qemu port
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
pull_request:
|
|
||||||
paths:
|
|
||||||
- '.github/workflows/*.yml'
|
|
||||||
- 'tools/**'
|
|
||||||
- 'py/**'
|
|
||||||
- 'extmod/**'
|
|
||||||
- 'shared/**'
|
|
||||||
- 'lib/**'
|
|
||||||
- 'drivers/**'
|
|
||||||
- 'ports/qemu/**'
|
|
||||||
- 'tests/**'
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build_and_test_arm:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Install packages
|
|
||||||
run: source tools/ci.sh && ci_qemu_setup_arm
|
|
||||||
- name: Build and run test suite
|
|
||||||
run: source tools/ci.sh && ci_qemu_build_arm
|
|
||||||
- name: Print failures
|
|
||||||
if: failure()
|
|
||||||
run: tests/run-tests.py --print-failures
|
|
||||||
|
|
||||||
build_and_test_rv32:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Install packages
|
|
||||||
run: source tools/ci.sh && ci_qemu_setup_rv32
|
|
||||||
- name: Build and run test suite
|
|
||||||
run: source tools/ci.sh && ci_qemu_build_rv32
|
|
||||||
- name: Print failures
|
|
||||||
if: failure()
|
|
||||||
run: tests/run-tests.py --print-failures
|
|
||||||
16
.github/workflows/ports_unix.yml
vendored
16
.github/workflows/ports_unix.yml
vendored
@@ -194,7 +194,7 @@ jobs:
|
|||||||
run: tests/run-tests.py --print-failures
|
run: tests/run-tests.py --print-failures
|
||||||
|
|
||||||
macos:
|
macos:
|
||||||
runs-on: macos-latest
|
runs-on: macos-11.0
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-python@v5
|
- uses: actions/setup-python@v5
|
||||||
@@ -235,17 +235,3 @@ jobs:
|
|||||||
- name: Print failures
|
- name: Print failures
|
||||||
if: failure()
|
if: failure()
|
||||||
run: tests/run-tests.py --print-failures
|
run: tests/run-tests.py --print-failures
|
||||||
|
|
||||||
qemu_riscv64:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Install packages
|
|
||||||
run: source tools/ci.sh && ci_unix_qemu_riscv64_setup
|
|
||||||
- name: Build
|
|
||||||
run: source tools/ci.sh && ci_unix_qemu_riscv64_build
|
|
||||||
- name: Run main test suite
|
|
||||||
run: source tools/ci.sh && ci_unix_qemu_riscv64_run_tests
|
|
||||||
- name: Print failures
|
|
||||||
if: failure()
|
|
||||||
run: tests/run-tests.py --print-failures
|
|
||||||
|
|||||||
17
.github/workflows/ports_windows.yml
vendored
17
.github/workflows/ports_windows.yml
vendored
@@ -42,8 +42,6 @@ jobs:
|
|||||||
configuration: Debug
|
configuration: Debug
|
||||||
- visualstudio: '2019'
|
- visualstudio: '2019'
|
||||||
configuration: Debug
|
configuration: Debug
|
||||||
env:
|
|
||||||
CI_BUILD_CONFIGURATION: ${{ matrix.configuration }}
|
|
||||||
runs-on: ${{ matrix.runner }}
|
runs-on: ${{ matrix.runner }}
|
||||||
steps:
|
steps:
|
||||||
- name: Install Visual Studio 2017
|
- name: Install Visual Studio 2017
|
||||||
@@ -110,6 +108,16 @@ jobs:
|
|||||||
run:
|
run:
|
||||||
shell: msys2 {0}
|
shell: msys2 {0}
|
||||||
steps:
|
steps:
|
||||||
|
- name: Get Python path
|
||||||
|
id: python_path
|
||||||
|
shell: python
|
||||||
|
run: |
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
output = f"python={os.fspath(sys.executable)}"
|
||||||
|
print(output)
|
||||||
|
with open(os.environ["GITHUB_OUTPUT"], "w") as f:
|
||||||
|
f.write(output)
|
||||||
- uses: msys2/setup-msys2@v2
|
- uses: msys2/setup-msys2@v2
|
||||||
with:
|
with:
|
||||||
msystem: ${{ matrix.sys }}
|
msystem: ${{ matrix.sys }}
|
||||||
@@ -118,7 +126,7 @@ jobs:
|
|||||||
make
|
make
|
||||||
mingw-w64-${{ matrix.env }}-gcc
|
mingw-w64-${{ matrix.env }}-gcc
|
||||||
pkg-config
|
pkg-config
|
||||||
mingw-w64-${{ matrix.env }}-python3
|
python3
|
||||||
git
|
git
|
||||||
diffutils
|
diffutils
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@@ -130,7 +138,8 @@ jobs:
|
|||||||
run: make -C ports/windows -j2 VARIANT=${{ matrix.variant }}
|
run: make -C ports/windows -j2 VARIANT=${{ matrix.variant }}
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
id: test
|
id: test
|
||||||
run: make -C ports/windows test_full VARIANT=${{ matrix.variant }}
|
# msys python breaks tests so we need to use "real" windows python
|
||||||
|
run: MICROPY_CPYTHON3=$(cygpath "${{ steps.python_path.outputs.python }}") make -C ports/windows test_full VARIANT=${{ matrix.variant }}
|
||||||
- name: Print failures
|
- name: Print failures
|
||||||
if: failure() && steps.test.conclusion == 'failure'
|
if: failure() && steps.test.conclusion == 'failure'
|
||||||
working-directory: tests
|
working-directory: tests
|
||||||
|
|||||||
14
.github/workflows/ports_zephyr.yml
vendored
14
.github/workflows/ports_zephyr.yml
vendored
@@ -20,15 +20,6 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: jlumbroso/free-disk-space@main
|
|
||||||
with:
|
|
||||||
# Only free up a few things so this step runs quickly.
|
|
||||||
android: false
|
|
||||||
dotnet: true
|
|
||||||
haskell: true
|
|
||||||
large-packages: false
|
|
||||||
docker-images: false
|
|
||||||
swap-storage: false
|
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Install packages
|
- name: Install packages
|
||||||
run: source tools/ci.sh && ci_zephyr_setup
|
run: source tools/ci.sh && ci_zephyr_setup
|
||||||
@@ -36,8 +27,3 @@ jobs:
|
|||||||
run: source tools/ci.sh && ci_zephyr_install
|
run: source tools/ci.sh && ci_zephyr_install
|
||||||
- name: Build
|
- name: Build
|
||||||
run: source tools/ci.sh && ci_zephyr_build
|
run: source tools/ci.sh && ci_zephyr_build
|
||||||
- name: Run main test suite
|
|
||||||
run: source tools/ci.sh && ci_zephyr_run_tests
|
|
||||||
- name: Print failures
|
|
||||||
if: failure()
|
|
||||||
run: tests/run-tests.py --print-failures
|
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -11,9 +11,8 @@ build/
|
|||||||
build-*/
|
build-*/
|
||||||
docs/genrst/
|
docs/genrst/
|
||||||
|
|
||||||
# Test failure outputs and intermediate artefacts
|
# Test failure outputs
|
||||||
tests/results/*
|
tests/results/*
|
||||||
tests/ports/unix/ffi_lib.so
|
|
||||||
|
|
||||||
# Python cache files
|
# Python cache files
|
||||||
__pycache__/
|
__pycache__/
|
||||||
|
|||||||
2
.gitmodules
vendored
2
.gitmodules
vendored
@@ -3,7 +3,7 @@
|
|||||||
url = https://github.com/micropython/axtls.git
|
url = https://github.com/micropython/axtls.git
|
||||||
[submodule "lib/libffi"]
|
[submodule "lib/libffi"]
|
||||||
path = lib/libffi
|
path = lib/libffi
|
||||||
url = https://github.com/libffi/libffi
|
url = https://github.com/atgreen/libffi
|
||||||
[submodule "lib/lwip"]
|
[submodule "lib/lwip"]
|
||||||
path = lib/lwip
|
path = lib/lwip
|
||||||
url = https://github.com/lwip-tcpip/lwip.git
|
url = https://github.com/lwip-tcpip/lwip.git
|
||||||
|
|||||||
2
LICENSE
2
LICENSE
@@ -59,6 +59,7 @@ used during the build process and is not part of the compiled source code.
|
|||||||
/pico-sdk (BSD-3-clause)
|
/pico-sdk (BSD-3-clause)
|
||||||
/re15 (BSD-3-clause)
|
/re15 (BSD-3-clause)
|
||||||
/stm32lib (BSD-3-clause)
|
/stm32lib (BSD-3-clause)
|
||||||
|
/tinytest (BSD-3-clause)
|
||||||
/tinyusb (MIT)
|
/tinyusb (MIT)
|
||||||
/uzlib (Zlib)
|
/uzlib (Zlib)
|
||||||
/wiznet5k (MIT)
|
/wiznet5k (MIT)
|
||||||
@@ -72,7 +73,6 @@ used during the build process and is not part of the compiled source code.
|
|||||||
/ppp_set_auth.* (Apache-2.0)
|
/ppp_set_auth.* (Apache-2.0)
|
||||||
/rp2
|
/rp2
|
||||||
/mutex_extra.c (BSD-3-clause)
|
/mutex_extra.c (BSD-3-clause)
|
||||||
/clocks_extra.c (BSD-3-clause)
|
|
||||||
/stm32
|
/stm32
|
||||||
/usbd*.c (MCD-ST Liberty SW License Agreement V2)
|
/usbd*.c (MCD-ST Liberty SW License Agreement V2)
|
||||||
/stm32_it.* (MIT + BSD-3-clause)
|
/stm32_it.* (MIT + BSD-3-clause)
|
||||||
|
|||||||
10
README.md
10
README.md
@@ -19,7 +19,7 @@ Python 3.5 and some select features from later versions). The following core
|
|||||||
datatypes are provided: `str`(including basic Unicode support), `bytes`,
|
datatypes are provided: `str`(including basic Unicode support), `bytes`,
|
||||||
`bytearray`, `tuple`, `list`, `dict`, `set`, `frozenset`, `array.array`,
|
`bytearray`, `tuple`, `list`, `dict`, `set`, `frozenset`, `array.array`,
|
||||||
`collections.namedtuple`, classes and instances. Builtin modules include
|
`collections.namedtuple`, classes and instances. Builtin modules include
|
||||||
`os`, `sys`, `time`, `re`, and `struct`, etc. Some ports have support for
|
`os`, `sys`, `time`, `re`, and `struct`, etc. Select ports have support for
|
||||||
`_thread` module (multithreading), `socket` and `ssl` for networking, and
|
`_thread` module (multithreading), `socket` and `ssl` for networking, and
|
||||||
`asyncio`. Note that only a subset of Python 3 functionality is implemented
|
`asyncio`. Note that only a subset of Python 3 functionality is implemented
|
||||||
for the data types and modules.
|
for the data types and modules.
|
||||||
@@ -35,8 +35,8 @@ DAC, PWM, SPI, I2C, CAN, Bluetooth, and USB.
|
|||||||
Getting started
|
Getting started
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
See the [online documentation](https://docs.micropython.org/) for the API
|
See the [online documentation](https://docs.micropython.org/) for API
|
||||||
reference and information about using MicroPython and information about how
|
references and information about using MicroPython and information about how
|
||||||
it is implemented.
|
it is implemented.
|
||||||
|
|
||||||
We use [GitHub Discussions](https://github.com/micropython/micropython/discussions)
|
We use [GitHub Discussions](https://github.com/micropython/micropython/discussions)
|
||||||
@@ -108,13 +108,13 @@ track of the code size of the core runtime and VM.
|
|||||||
|
|
||||||
In addition, the following ports are provided in this repository:
|
In addition, the following ports are provided in this repository:
|
||||||
- [cc3200](ports/cc3200) -- Texas Instruments CC3200 (including PyCom WiPy).
|
- [cc3200](ports/cc3200) -- Texas Instruments CC3200 (including PyCom WiPy).
|
||||||
- [esp32](ports/esp32) -- Espressif ESP32 SoC (including ESP32S2, ESP32S3, ESP32C3, ESP32C6).
|
- [esp32](ports/esp32) -- Espressif ESP32 SoC (including ESP32S2, ESP32S3, ESP32C3).
|
||||||
- [esp8266](ports/esp8266) -- Espressif ESP8266 SoC.
|
- [esp8266](ports/esp8266) -- Espressif ESP8266 SoC.
|
||||||
- [mimxrt](ports/mimxrt) -- NXP m.iMX RT (including Teensy 4.x).
|
- [mimxrt](ports/mimxrt) -- NXP m.iMX RT (including Teensy 4.x).
|
||||||
- [nrf](ports/nrf) -- Nordic Semiconductor nRF51 and nRF52.
|
- [nrf](ports/nrf) -- Nordic Semiconductor nRF51 and nRF52.
|
||||||
- [pic16bit](ports/pic16bit) -- Microchip PIC 16-bit.
|
- [pic16bit](ports/pic16bit) -- Microchip PIC 16-bit.
|
||||||
- [powerpc](ports/powerpc) -- IBM PowerPC (including Microwatt)
|
- [powerpc](ports/powerpc) -- IBM PowerPC (including Microwatt)
|
||||||
- [qemu](ports/qemu) -- QEMU-based emulated target (for testing)
|
- [qemu-arm](ports/qemu-arm) -- QEMU-based emulated target, for testing)
|
||||||
- [renesas-ra](ports/renesas-ra) -- Renesas RA family.
|
- [renesas-ra](ports/renesas-ra) -- Renesas RA family.
|
||||||
- [rp2](ports/rp2) -- Raspberry Pi RP2040 (including Pico and Pico W).
|
- [rp2](ports/rp2) -- Raspberry Pi RP2040 (including Pico and Pico W).
|
||||||
- [samd](ports/samd) -- Microchip (formerly Atmel) SAMD21 and SAMD51.
|
- [samd](ports/samd) -- Microchip (formerly Atmel) SAMD21 and SAMD51.
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ A MicroPython user C module is a directory with the following files:
|
|||||||
SRC_USERMOD_LIB_C += $(EXAMPLE_MOD_DIR)/utils/algorithm.c
|
SRC_USERMOD_LIB_C += $(EXAMPLE_MOD_DIR)/utils/algorithm.c
|
||||||
|
|
||||||
Similarly, use ``SRC_USERMOD_CXX`` and ``SRC_USERMOD_LIB_CXX`` for C++
|
Similarly, use ``SRC_USERMOD_CXX`` and ``SRC_USERMOD_LIB_CXX`` for C++
|
||||||
source files. If you want to include assembly files use ``SRC_USERMOD_LIB_ASM``.
|
source files.
|
||||||
|
|
||||||
If you have custom compiler options (like ``-I`` to add directories to search
|
If you have custom compiler options (like ``-I`` to add directories to search
|
||||||
for header files), these should be added to ``CFLAGS_USERMOD`` for C code
|
for header files), these should be added to ``CFLAGS_USERMOD`` for C code
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ working with this board it may be useful to get an overview of the microcontroll
|
|||||||
general.rst
|
general.rst
|
||||||
tutorial/index.rst
|
tutorial/index.rst
|
||||||
|
|
||||||
Note that there are several varieties of ESP32 -- ESP32, ESP32C3, ESP32C6, ESP32S2, ESP32S3 --
|
Note that there are several varieties of ESP32 -- ESP32, ESP32C3, ESP32S2, ESP32S3 --
|
||||||
supported by MicroPython, with some differences in functionality between them.
|
supported by MicroPython, with some differences in functionality between them.
|
||||||
|
|
||||||
Installing MicroPython
|
Installing MicroPython
|
||||||
@@ -61,13 +61,13 @@ The :mod:`esp32` module::
|
|||||||
import esp32
|
import esp32
|
||||||
|
|
||||||
esp32.raw_temperature() # read the internal temperature of the MCU, in Fahrenheit
|
esp32.raw_temperature() # read the internal temperature of the MCU, in Fahrenheit
|
||||||
esp32.ULP() # access to the Ultra-Low-Power Co-processor, not on ESP32C3/C6
|
esp32.ULP() # access to the Ultra-Low-Power Co-processor, not on ESP32C3
|
||||||
|
|
||||||
Note that the temperature sensor in the ESP32 will typically read higher than
|
Note that the temperature sensor in the ESP32 will typically read higher than
|
||||||
ambient due to the IC getting warm while it runs. This effect can be minimised
|
ambient due to the IC getting warm while it runs. This effect can be minimised
|
||||||
by reading the temperature sensor immediately after waking up from sleep.
|
by reading the temperature sensor immediately after waking up from sleep.
|
||||||
|
|
||||||
ESP32C3, ESP32C6, ESP32S2, and ESP32S3 also have an internal temperature sensor available.
|
ESP32C3, ESP32S2, and ESP32S3 also have an internal temperature sensor available.
|
||||||
It is implemented a bit differently to the ESP32 and returns the temperature in
|
It is implemented a bit differently to the ESP32 and returns the temperature in
|
||||||
Celsius::
|
Celsius::
|
||||||
|
|
||||||
@@ -89,7 +89,7 @@ The :mod:`network` module::
|
|||||||
wlan.isconnected() # check if the station is connected to an AP
|
wlan.isconnected() # check if the station is connected to an AP
|
||||||
wlan.connect('ssid', 'key') # connect to an AP
|
wlan.connect('ssid', 'key') # connect to an AP
|
||||||
wlan.config('mac') # get the interface's MAC address
|
wlan.config('mac') # get the interface's MAC address
|
||||||
wlan.ipconfig('addr4') # get the interface's IPv4 addresses
|
wlan.ifconfig() # get the interface's IP/netmask/gw/DNS addresses
|
||||||
|
|
||||||
ap = network.WLAN(network.AP_IF) # create access-point interface
|
ap = network.WLAN(network.AP_IF) # create access-point interface
|
||||||
ap.config(ssid='ESP-AP') # set the SSID of the access point
|
ap.config(ssid='ESP-AP') # set the SSID of the access point
|
||||||
@@ -107,7 +107,7 @@ A useful function for connecting to your local WiFi network is::
|
|||||||
wlan.connect('ssid', 'key')
|
wlan.connect('ssid', 'key')
|
||||||
while not wlan.isconnected():
|
while not wlan.isconnected():
|
||||||
pass
|
pass
|
||||||
print('network config:', wlan.ipconfig('addr4'))
|
print('network config:', wlan.ifconfig())
|
||||||
|
|
||||||
Once the network is established the :mod:`socket <socket>` module can be used
|
Once the network is established the :mod:`socket <socket>` module can be used
|
||||||
to create and use TCP/UDP sockets as usual, and the ``requests`` module for
|
to create and use TCP/UDP sockets as usual, and the ``requests`` module for
|
||||||
@@ -130,7 +130,7 @@ To use the wired interfaces one has to specify the pins and mode ::
|
|||||||
|
|
||||||
lan = network.LAN(mdc=PIN_MDC, ...) # Set the pin and mode configuration
|
lan = network.LAN(mdc=PIN_MDC, ...) # Set the pin and mode configuration
|
||||||
lan.active(True) # activate the interface
|
lan.active(True) # activate the interface
|
||||||
lan.ipconfig('addr4') # get the interface's IPv4 addresses
|
lan.ifconfig() # get the interface's IP/netmask/gw/DNS addresses
|
||||||
|
|
||||||
|
|
||||||
The keyword arguments for the constructor defining the PHY type and interface are:
|
The keyword arguments for the constructor defining the PHY type and interface are:
|
||||||
|
|||||||
@@ -32,18 +32,6 @@ the prescaler of the MCPWM0 peripheral.
|
|||||||
mem32[MCPWM0] = 0x55 # change PWM_CLK_PRESCALE
|
mem32[MCPWM0] = 0x55 # change PWM_CLK_PRESCALE
|
||||||
print(hex(mem32[MCPWM0])) # read PWM_CLK_CFG_REG
|
print(hex(mem32[MCPWM0])) # read PWM_CLK_CFG_REG
|
||||||
|
|
||||||
The specific addresses will be different on different ESP32
|
|
||||||
models. For example, ESP32-S3 uses these values:
|
|
||||||
|
|
||||||
.. code-block:: python3
|
|
||||||
|
|
||||||
DR_REG_DPORT_BASE = const(0x600C_0000)
|
|
||||||
DPORT_PERIP_CLK_EN0_REG = const(DR_REG_DPORT_BASE + 0x0018)
|
|
||||||
DPORT_PERIP_RST_EN0_REG = const(DR_REG_DPORT_BASE + 0x0020)
|
|
||||||
DPORT_PWM0_CLK_EN = const(1 << 17)
|
|
||||||
MCPWM0 = const(0x6001_E000 + 0x0004)
|
|
||||||
...
|
|
||||||
|
|
||||||
Note that before a peripheral can be used its clock must be enabled and it must
|
Note that before a peripheral can be used its clock must be enabled and it must
|
||||||
be taken out of reset. In the above example the following registers are used
|
be taken out of reset. In the above example the following registers are used
|
||||||
for this:
|
for this:
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ The :mod:`network` module::
|
|||||||
wlan.isconnected() # check if the station is connected to an AP
|
wlan.isconnected() # check if the station is connected to an AP
|
||||||
wlan.connect('ssid', 'key') # connect to an AP
|
wlan.connect('ssid', 'key') # connect to an AP
|
||||||
wlan.config('mac') # get the interface's MAC address
|
wlan.config('mac') # get the interface's MAC address
|
||||||
wlan.ipconfig('addr4') # get the interface's IPv4 addresses
|
wlan.ifconfig() # get the interface's IP/netmask/gw/DNS addresses
|
||||||
|
|
||||||
ap = network.WLAN(network.AP_IF) # create access-point interface
|
ap = network.WLAN(network.AP_IF) # create access-point interface
|
||||||
ap.active(True) # activate the interface
|
ap.active(True) # activate the interface
|
||||||
@@ -76,7 +76,7 @@ A useful function for connecting to your local WiFi network is::
|
|||||||
wlan.connect('ssid', 'key')
|
wlan.connect('ssid', 'key')
|
||||||
while not wlan.isconnected():
|
while not wlan.isconnected():
|
||||||
pass
|
pass
|
||||||
print('network config:', wlan.ipconfig('addr4'))
|
print('network config:', wlan.ifconfig())
|
||||||
|
|
||||||
Once the network is established the :mod:`socket <socket>` module can be used
|
Once the network is established the :mod:`socket <socket>` module can be used
|
||||||
to create and use TCP/UDP sockets as usual.
|
to create and use TCP/UDP sockets as usual.
|
||||||
|
|||||||
@@ -19,10 +19,10 @@ You can check if the interfaces are active by::
|
|||||||
|
|
||||||
You can also check the network settings of the interface by::
|
You can also check the network settings of the interface by::
|
||||||
|
|
||||||
>>> ap_if.ipconfig('addr4')
|
>>> ap_if.ifconfig()
|
||||||
('192.168.4.1', '255.255.255.0')
|
('192.168.4.1', '255.255.255.0', '192.168.4.1', '8.8.8.8')
|
||||||
|
|
||||||
The returned values are: IP address and netmask.
|
The returned values are: IP address, netmask, gateway, DNS.
|
||||||
|
|
||||||
Configuration of the WiFi
|
Configuration of the WiFi
|
||||||
-------------------------
|
-------------------------
|
||||||
@@ -45,8 +45,8 @@ To check if the connection is established use::
|
|||||||
|
|
||||||
Once established you can check the IP address::
|
Once established you can check the IP address::
|
||||||
|
|
||||||
>>> sta_if.ipconfig('addr4')
|
>>> sta_if.ifconfig()
|
||||||
('192.168.0.2', '255.255.255.0')
|
('192.168.0.2', '255.255.255.0', '192.168.0.1', '8.8.8.8')
|
||||||
|
|
||||||
You can then disable the access-point interface if you no longer need it::
|
You can then disable the access-point interface if you no longer need it::
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ connect to your WiFi network::
|
|||||||
sta_if.connect('<ssid>', '<key>')
|
sta_if.connect('<ssid>', '<key>')
|
||||||
while not sta_if.isconnected():
|
while not sta_if.isconnected():
|
||||||
pass
|
pass
|
||||||
print('network config:', sta_if.ipconfig('addr4'))
|
print('network config:', sta_if.ifconfig())
|
||||||
|
|
||||||
Sockets
|
Sockets
|
||||||
-------
|
-------
|
||||||
|
|||||||
@@ -82,10 +82,6 @@ Functions and types
|
|||||||
In MicroPython, `byteorder` parameter must be positional (this is
|
In MicroPython, `byteorder` parameter must be positional (this is
|
||||||
compatible with CPython).
|
compatible with CPython).
|
||||||
|
|
||||||
.. note:: The optional ``signed`` kwarg from CPython is not supported.
|
|
||||||
MicroPython currently converts negative integers as signed,
|
|
||||||
and positive as unsigned. (:ref:`Details <cpydiff_types_int_to_bytes>`.)
|
|
||||||
|
|
||||||
.. function:: isinstance()
|
.. function:: isinstance()
|
||||||
|
|
||||||
.. function:: issubclass()
|
.. function:: issubclass()
|
||||||
|
|||||||
@@ -238,12 +238,6 @@ The following methods are not part of the core Pin API and only implemented on c
|
|||||||
|
|
||||||
Availability: cc3200 port.
|
Availability: cc3200 port.
|
||||||
|
|
||||||
.. method:: Pin.toggle()
|
|
||||||
|
|
||||||
Toggle output pin from "0" to "1" or vice-versa.
|
|
||||||
|
|
||||||
Availability: mimxrt, samd, rp2 ports.
|
|
||||||
|
|
||||||
Constants
|
Constants
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
|||||||
@@ -152,6 +152,31 @@ Methods
|
|||||||
Send a break condition on the bus. This drives the bus low for a duration
|
Send a break condition on the bus. This drives the bus low for a duration
|
||||||
longer than required for a normal transmission of a character.
|
longer than required for a normal transmission of a character.
|
||||||
|
|
||||||
|
.. method:: UART.irq(trigger, priority=1, handler=None, wake=machine.IDLE)
|
||||||
|
|
||||||
|
Create a callback to be triggered when data is received on the UART.
|
||||||
|
|
||||||
|
- *trigger* can only be ``UART.RX_ANY``
|
||||||
|
- *priority* level of the interrupt. Can take values in the range 1-7.
|
||||||
|
Higher values represent higher priorities.
|
||||||
|
- *handler* an optional function to be called when new characters arrive.
|
||||||
|
- *wake* can only be ``machine.IDLE``.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
The handler will be called whenever any of the following two conditions are met:
|
||||||
|
|
||||||
|
- 8 new characters have been received.
|
||||||
|
- At least 1 new character is waiting in the Rx buffer and the Rx line has been
|
||||||
|
silent for the duration of 1 complete frame.
|
||||||
|
|
||||||
|
This means that when the handler function is called there will be between 1 to 8
|
||||||
|
characters waiting.
|
||||||
|
|
||||||
|
Returns an irq object.
|
||||||
|
|
||||||
|
Availability: WiPy.
|
||||||
|
|
||||||
.. method:: UART.flush()
|
.. method:: UART.flush()
|
||||||
|
|
||||||
Waits until all data has been sent. In case of a timeout, an exception is raised. The timeout
|
Waits until all data has been sent. In case of a timeout, an exception is raised. The timeout
|
||||||
@@ -160,7 +185,7 @@ Methods
|
|||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
For the esp8266 and nrf ports the call returns while the last byte is sent.
|
For the rp2, esp8266 and nrf ports the call returns while the last byte is sent.
|
||||||
If required, a one character wait time has to be added in the calling script.
|
If required, a one character wait time has to be added in the calling script.
|
||||||
|
|
||||||
Availability: rp2, esp32, esp8266, mimxrt, cc3200, stm32, nrf ports, renesas-ra
|
Availability: rp2, esp32, esp8266, mimxrt, cc3200, stm32, nrf ports, renesas-ra
|
||||||
@@ -172,91 +197,17 @@ Methods
|
|||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
For the esp8266 and nrf ports the call may return ``True`` even if the last byte
|
For the rp2, esp8266 and nrf ports the call may return ``True`` even if the last byte
|
||||||
of a transfer is still being sent. If required, a one character wait time has to be
|
of a transfer is still being sent. If required, a one character wait time has to be
|
||||||
added in the calling script.
|
added in the calling script.
|
||||||
|
|
||||||
Availability: rp2, esp32, esp8266, mimxrt, cc3200, stm32, nrf ports, renesas-ra
|
Availability: rp2, esp32, esp8266, mimxrt, cc3200, stm32, nrf ports, renesas-ra
|
||||||
|
|
||||||
.. method:: UART.irq(handler=None, trigger=0, hard=False)
|
|
||||||
|
|
||||||
Configure an interrupt handler to be called when a UART event occurs.
|
|
||||||
|
|
||||||
The arguments are:
|
|
||||||
|
|
||||||
- *handler* is an optional function to be called when the interrupt event
|
|
||||||
triggers. The handler must take exactly one argument which is the
|
|
||||||
``UART`` instance.
|
|
||||||
|
|
||||||
- *trigger* configures the event(s) which can generate an interrupt.
|
|
||||||
Possible values are a mask of one or more of the following:
|
|
||||||
|
|
||||||
- ``UART.IRQ_RXIDLE`` interrupt after receiving at least one character
|
|
||||||
and then the RX line goes idle.
|
|
||||||
- ``UART.IRQ_RX`` interrupt after each received character.
|
|
||||||
- ``UART.IRQ_TXIDLE`` interrupt after or while the last character(s) of
|
|
||||||
a message are or have been sent.
|
|
||||||
- ``UART.IRQ_BREAK`` interrupt when a break state is detected at RX
|
|
||||||
|
|
||||||
- *hard* if true a hardware interrupt is used. This reduces the delay
|
|
||||||
between the pin change and the handler being called. Hard interrupt
|
|
||||||
handlers may not allocate memory; see :ref:`isr_rules`.
|
|
||||||
|
|
||||||
Returns an irq object.
|
|
||||||
|
|
||||||
Due to limitations of the hardware not all trigger events are available on all ports.
|
|
||||||
|
|
||||||
.. table:: Availability of triggers
|
|
||||||
:align: center
|
|
||||||
|
|
||||||
============== ========== ====== ========== =========
|
|
||||||
Port / Trigger IRQ_RXIDLE IRQ_RX IRQ_TXIDLE IRQ_BREAK
|
|
||||||
============== ========== ====== ========== =========
|
|
||||||
CC3200 yes
|
|
||||||
ESP32 yes yes yes
|
|
||||||
MIMXRT yes yes
|
|
||||||
NRF yes yes
|
|
||||||
RENESAS-RA yes yes
|
|
||||||
RP2 yes yes yes
|
|
||||||
SAMD yes yes yes
|
|
||||||
STM32 yes yes
|
|
||||||
============== ========== ====== ========== =========
|
|
||||||
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
- The ESP32 port does not support the option hard=True.
|
|
||||||
|
|
||||||
- The rp2 port's UART.IRQ_TXIDLE is only triggered when the message
|
|
||||||
is longer than 5 characters and the trigger happens when still 5 characters
|
|
||||||
are to be sent.
|
|
||||||
|
|
||||||
- The rp2 port's UART.IRQ_BREAK needs receiving valid characters for triggering
|
|
||||||
again.
|
|
||||||
|
|
||||||
- The SAMD port's UART.IRQ_TXIDLE is triggered while the last character is sent.
|
|
||||||
|
|
||||||
- On STM32F4xx MCU's, using the trigger UART.IRQ_RXIDLE the handler will be called once
|
|
||||||
after the first character and then after the end of the message, when the line is
|
|
||||||
idle.
|
|
||||||
|
|
||||||
|
|
||||||
Availability: cc3200, esp32, mimxrt, nrf, renesas-ra, rp2, samd, stm32.
|
|
||||||
|
|
||||||
Constants
|
Constants
|
||||||
---------
|
---------
|
||||||
|
|
||||||
.. data:: UART.RTS
|
.. data:: UART.RX_ANY
|
||||||
UART.CTS
|
|
||||||
|
|
||||||
Flow control options.
|
IRQ trigger sources
|
||||||
|
|
||||||
Availability: esp32, mimxrt, renesas-ra, rp2, stm32.
|
Availability: WiPy.
|
||||||
|
|
||||||
.. data:: UART.IRQ_RXIDLE
|
|
||||||
UART.IRQ_RX
|
|
||||||
UART.IRQ_TXIDLE
|
|
||||||
UART.IRQ_BREAK
|
|
||||||
|
|
||||||
IRQ trigger sources.
|
|
||||||
|
|
||||||
Availability: renesas-ra, stm32, esp32, rp2040, mimxrt, samd, cc3200.
|
|
||||||
|
|||||||
@@ -215,13 +215,6 @@ Methods
|
|||||||
drivers. Placing a different string at any of these indexes overrides that
|
drivers. Placing a different string at any of these indexes overrides that
|
||||||
string in the built-in driver.
|
string in the built-in driver.
|
||||||
|
|
||||||
.. method:: USBDevice.remote_wakeup(self)
|
|
||||||
|
|
||||||
Wake up host if we are in suspend mode and the REMOTE_WAKEUP feature
|
|
||||||
is enabled by the host. This has to be enabled in the USB attributes,
|
|
||||||
and on the host. Returns ``True`` if remote wakeup was enabled and
|
|
||||||
active and the host was woken up.
|
|
||||||
|
|
||||||
.. method:: USBDevice.submit_xfer(self, ep, buffer /)
|
.. method:: USBDevice.submit_xfer(self, ep, buffer /)
|
||||||
|
|
||||||
Submit a USB transfer on endpoint number ``ep``. ``buffer`` must be
|
Submit a USB transfer on endpoint number ``ep``. ``buffer`` must be
|
||||||
|
|||||||
@@ -127,20 +127,14 @@ Power related functions
|
|||||||
|
|
||||||
.. function:: idle()
|
.. function:: idle()
|
||||||
|
|
||||||
Gates the clock to the CPU, useful to reduce power consumption at any time
|
Gates the clock to the CPU, useful to reduce power consumption at any time during
|
||||||
during short or long periods. Peripherals continue working and execution
|
short or long periods. Peripherals continue working and execution resumes as soon
|
||||||
resumes as soon as any interrupt is triggered, or at most one millisecond
|
as any interrupt is triggered (on many ports this includes system timer
|
||||||
after the CPU was paused.
|
interrupt occurring at regular intervals on the order of millisecond).
|
||||||
|
|
||||||
It is recommended to call this function inside any tight loop that is
|
|
||||||
continuously checking for an external change (i.e. polling). This will reduce
|
|
||||||
power consumption without significantly impacting performance. To reduce
|
|
||||||
power consumption further then see the :func:`lightsleep`,
|
|
||||||
:func:`time.sleep()` and :func:`time.sleep_ms()` functions.
|
|
||||||
|
|
||||||
.. function:: sleep()
|
.. function:: sleep()
|
||||||
|
|
||||||
.. note:: This function is deprecated, use :func:`lightsleep()` instead with no arguments.
|
.. note:: This function is deprecated, use `lightsleep()` instead with no arguments.
|
||||||
|
|
||||||
.. function:: lightsleep([time_ms])
|
.. function:: lightsleep([time_ms])
|
||||||
deepsleep([time_ms])
|
deepsleep([time_ms])
|
||||||
|
|||||||
@@ -125,11 +125,8 @@ Functions
|
|||||||
Return the natural logarithm of the gamma function of ``x``.
|
Return the natural logarithm of the gamma function of ``x``.
|
||||||
|
|
||||||
.. function:: log(x)
|
.. function:: log(x)
|
||||||
log(x, base)
|
|
||||||
|
|
||||||
With one argument, return the natural logarithm of *x*.
|
Return the natural logarithm of ``x``.
|
||||||
|
|
||||||
With two arguments, return the logarithm of *x* to the given *base*.
|
|
||||||
|
|
||||||
.. function:: log10(x)
|
.. function:: log10(x)
|
||||||
|
|
||||||
|
|||||||
@@ -136,14 +136,6 @@ Functions
|
|||||||
the heap may be locked) and scheduling a function to call later will lift
|
the heap may be locked) and scheduling a function to call later will lift
|
||||||
those restrictions.
|
those restrictions.
|
||||||
|
|
||||||
On multi-threaded ports, the scheduled function's behaviour depends on
|
|
||||||
whether the Global Interpreter Lock (GIL) is enabled for the specific port:
|
|
||||||
|
|
||||||
- If GIL is enabled, the function can preempt any thread and run in its
|
|
||||||
context.
|
|
||||||
- If GIL is disabled, the function will only preempt the main thread and run
|
|
||||||
in its context.
|
|
||||||
|
|
||||||
Note: If `schedule()` is called from a preempting IRQ, when memory
|
Note: If `schedule()` is called from a preempting IRQ, when memory
|
||||||
allocation is not allowed and the callback to be passed to `schedule()` is
|
allocation is not allowed and the callback to be passed to `schedule()` is
|
||||||
a bound method, passing this directly will fail. This is because creating a
|
a bound method, passing this directly will fail. This is because creating a
|
||||||
@@ -155,71 +147,3 @@ Functions
|
|||||||
|
|
||||||
There is a finite queue to hold the scheduled functions and `schedule()`
|
There is a finite queue to hold the scheduled functions and `schedule()`
|
||||||
will raise a `RuntimeError` if the queue is full.
|
will raise a `RuntimeError` if the queue is full.
|
||||||
|
|
||||||
Classes
|
|
||||||
-------
|
|
||||||
|
|
||||||
.. class:: RingIO(size)
|
|
||||||
.. class:: RingIO(buffer)
|
|
||||||
:noindex:
|
|
||||||
|
|
||||||
Provides a fixed-size ringbuffer for bytes with a stream interface. Can be
|
|
||||||
considered like a fifo queue variant of `io.BytesIO`.
|
|
||||||
|
|
||||||
When created with integer size a suitable buffer will be allocated.
|
|
||||||
Alternatively a `bytearray` or similar buffer protocol object can be provided
|
|
||||||
to the constructor for in-place use.
|
|
||||||
|
|
||||||
The classic ringbuffer algorithm is used which allows for any size buffer
|
|
||||||
to be used however one byte will be consumed for tracking. If initialised
|
|
||||||
with an integer size this will be accounted for, for example ``RingIO(16)``
|
|
||||||
will allocate a 17 byte buffer internally so it can hold 16 bytes of data.
|
|
||||||
When passing in a pre-allocated buffer however one byte less than its
|
|
||||||
original length will be available for storage, eg. ``RingIO(bytearray(16))``
|
|
||||||
will only hold 15 bytes of data.
|
|
||||||
|
|
||||||
A RingIO instance can be IRQ / thread safe when used to pass data in a single
|
|
||||||
direction eg. when written to in an IRQ and read from in a non-IRQ function
|
|
||||||
(or vice versa). This does not hold if you try to eg. write to a single instance
|
|
||||||
from both IRQ and non-IRQ code, this would often cause data corruption.
|
|
||||||
|
|
||||||
.. method:: RingIO.any()
|
|
||||||
|
|
||||||
Returns an integer counting the number of characters that can be read.
|
|
||||||
|
|
||||||
.. method:: RingIO.read([nbytes])
|
|
||||||
|
|
||||||
Read available characters. This is a non-blocking function. If ``nbytes``
|
|
||||||
is specified then read at most that many bytes, otherwise read as much
|
|
||||||
data as possible.
|
|
||||||
|
|
||||||
Return value: a bytes object containing the bytes read. Will be
|
|
||||||
zero-length bytes object if no data is available.
|
|
||||||
|
|
||||||
.. method:: RingIO.readline([nbytes])
|
|
||||||
|
|
||||||
Read a line, ending in a newline character or return if one exists in
|
|
||||||
the buffer, else return available bytes in buffer. If ``nbytes`` is
|
|
||||||
specified then read at most that many bytes.
|
|
||||||
|
|
||||||
Return value: a bytes object containing the line read.
|
|
||||||
|
|
||||||
.. method:: RingIO.readinto(buf[, nbytes])
|
|
||||||
|
|
||||||
Read available bytes into the provided ``buf``. If ``nbytes`` is
|
|
||||||
specified then read at most that many bytes. Otherwise, read at
|
|
||||||
most ``len(buf)`` bytes.
|
|
||||||
|
|
||||||
Return value: Integer count of the number of bytes read into ``buf``.
|
|
||||||
|
|
||||||
.. method:: RingIO.write(buf)
|
|
||||||
|
|
||||||
Non-blocking write of bytes from ``buf`` into the ringbuffer, limited
|
|
||||||
by the available space in the ringbuffer.
|
|
||||||
|
|
||||||
Return value: Integer count of bytes written.
|
|
||||||
|
|
||||||
.. method:: RingIO.close()
|
|
||||||
|
|
||||||
No-op provided as part of standard `stream` interface. Has no effect
|
|
||||||
on data in the ringbuffer.
|
|
||||||
|
|||||||
@@ -43,8 +43,7 @@ Constructors
|
|||||||
- *pin* is a machine.Pin instance.
|
- *pin* is a machine.Pin instance.
|
||||||
- *n* is the number of LEDs in the strip.
|
- *n* is the number of LEDs in the strip.
|
||||||
- *bpp* is 3 for RGB LEDs, and 4 for RGBW LEDs.
|
- *bpp* is 3 for RGB LEDs, and 4 for RGBW LEDs.
|
||||||
- *timing* is 0 for 400KHz, and 1 for 800kHz LEDs (most are 800kHz). You
|
- *timing* is 0 for 400KHz, and 1 for 800kHz LEDs (most are 800kHz).
|
||||||
may also supply a timing tuple as accepted by `machine.bitstream()`.
|
|
||||||
|
|
||||||
Pixel access methods
|
Pixel access methods
|
||||||
--------------------
|
--------------------
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ Example usage::
|
|||||||
|
|
||||||
import network
|
import network
|
||||||
nic = network.LAN(0)
|
nic = network.LAN(0)
|
||||||
print(nic.ipconfig("addr4"))
|
print(nic.ifconfig())
|
||||||
|
|
||||||
# now use socket as usual
|
# now use socket as usual
|
||||||
...
|
...
|
||||||
|
|||||||
@@ -1,98 +0,0 @@
|
|||||||
.. currentmodule:: network
|
|
||||||
.. _network.PPP:
|
|
||||||
|
|
||||||
class PPP -- create network connections over serial PPP
|
|
||||||
=======================================================
|
|
||||||
|
|
||||||
This class allows you to create a network connection over a serial port using
|
|
||||||
the PPP protocol. It is only available on selected ports and boards.
|
|
||||||
|
|
||||||
Example usage::
|
|
||||||
|
|
||||||
import network
|
|
||||||
|
|
||||||
ppp = network.PPP(uart)
|
|
||||||
ppp.connect()
|
|
||||||
|
|
||||||
while not ppp.isconnected():
|
|
||||||
pass
|
|
||||||
|
|
||||||
print(ppp.ipconfig("addr4"))
|
|
||||||
|
|
||||||
# use the socket module as usual, etc
|
|
||||||
|
|
||||||
ppp.disconnect()
|
|
||||||
|
|
||||||
Constructors
|
|
||||||
------------
|
|
||||||
|
|
||||||
.. class:: PPP(stream)
|
|
||||||
|
|
||||||
Create a PPP driver object.
|
|
||||||
|
|
||||||
Arguments are:
|
|
||||||
|
|
||||||
- *stream* is any object that supports the stream protocol, but is most commonly a
|
|
||||||
:class:`machine.UART` instance. This stream object must have an ``irq()`` method
|
|
||||||
and an ``IRQ_RXIDLE`` constant, for use by `PPP.connect`.
|
|
||||||
|
|
||||||
Methods
|
|
||||||
-------
|
|
||||||
|
|
||||||
.. method:: PPP.connect(security=SEC_NONE, user=None, key=None)
|
|
||||||
|
|
||||||
Initiate a PPP connection with the given parameters:
|
|
||||||
|
|
||||||
- *security* is the type of security, either ``PPP.SEC_NONE``, ``PPP.SEC_PAP``,
|
|
||||||
or ``PPP.SEC_CHAP``.
|
|
||||||
- *user* is an optional user name to use with the security mode.
|
|
||||||
- *key* is an optional password to use with the security mode.
|
|
||||||
|
|
||||||
When this method is called the underlying stream has its interrupt configured to call
|
|
||||||
`PPP.poll` via ``stream.irq(ppp.poll, stream.IRQ_RXIDLE)``. This makes sure the
|
|
||||||
stream is polled, and data passed up the PPP stack, wheverver data becomes available
|
|
||||||
on the stream.
|
|
||||||
|
|
||||||
The connection proceeds asynchronously, in the background.
|
|
||||||
|
|
||||||
.. method:: PPP.disconnect()
|
|
||||||
|
|
||||||
Terminate the connection. This must be called to cleanly close the PPP connection.
|
|
||||||
|
|
||||||
.. method:: PPP.isconnected()
|
|
||||||
|
|
||||||
Returns ``True`` if the PPP link is connected and up.
|
|
||||||
Returns ``False`` otherwise.
|
|
||||||
|
|
||||||
.. method:: PPP.status()
|
|
||||||
|
|
||||||
Returns the PPP status.
|
|
||||||
|
|
||||||
.. method:: PPP.config(config_parameters)
|
|
||||||
|
|
||||||
Sets or gets parameters of the PPP interface. There are currently no parameter that
|
|
||||||
can be set or retrieved.
|
|
||||||
|
|
||||||
.. method:: PPP.ipconfig('param')
|
|
||||||
PPP.ipconfig(param=value, ...)
|
|
||||||
|
|
||||||
See `AbstractNIC.ipconfig`.
|
|
||||||
|
|
||||||
.. method:: PPP.ifconfig([(ip, subnet, gateway, dns)])
|
|
||||||
|
|
||||||
See `AbstractNIC.ifconfig`.
|
|
||||||
|
|
||||||
.. method:: PPP.poll()
|
|
||||||
|
|
||||||
Poll the underlying stream for data, and pass it up the PPP stack.
|
|
||||||
This is called automatically if the stream is a UART with a RXIDLE interrupt,
|
|
||||||
so it's not usually necessary to call it manually.
|
|
||||||
|
|
||||||
Constants
|
|
||||||
---------
|
|
||||||
|
|
||||||
.. data:: PPP.SEC_NONE
|
|
||||||
PPP.SEC_PAP
|
|
||||||
PPP.SEC_CHAP
|
|
||||||
|
|
||||||
The type of connection security.
|
|
||||||
@@ -13,7 +13,7 @@ Example usage::
|
|||||||
|
|
||||||
import network
|
import network
|
||||||
nic = network.WIZNET5K(pyb.SPI(1), pyb.Pin.board.X5, pyb.Pin.board.X4)
|
nic = network.WIZNET5K(pyb.SPI(1), pyb.Pin.board.X5, pyb.Pin.board.X4)
|
||||||
print(nic.ipconfig("addr4"))
|
print(nic.ifconfig())
|
||||||
|
|
||||||
# now use socket as usual
|
# now use socket as usual
|
||||||
...
|
...
|
||||||
@@ -51,7 +51,20 @@ Constructors
|
|||||||
Methods
|
Methods
|
||||||
-------
|
-------
|
||||||
|
|
||||||
This class implements most methods from `AbstractNIC <AbstractNIC>`, which are documented there. Additional methods are:
|
.. method:: WIZNET5K.isconnected()
|
||||||
|
|
||||||
|
Returns ``True`` if the physical Ethernet link is connected and up.
|
||||||
|
Returns ``False`` otherwise.
|
||||||
|
|
||||||
|
.. method:: WIZNET5K.ifconfig([(ip, subnet, gateway, dns)])
|
||||||
|
|
||||||
|
Get/set IP address, subnet mask, gateway and DNS.
|
||||||
|
|
||||||
|
When called with no arguments, this method returns a 4-tuple with the above information.
|
||||||
|
|
||||||
|
To set the above values, pass a 4-tuple with the required information. For example::
|
||||||
|
|
||||||
|
nic.ifconfig(('192.168.0.4', '255.255.255.0', '192.168.0.1', '8.8.8.8'))
|
||||||
|
|
||||||
.. method:: WIZNET5K.regs()
|
.. method:: WIZNET5K.regs()
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ Methods
|
|||||||
|
|
||||||
Get or set general network interface parameters. These methods allow to work
|
Get or set general network interface parameters. These methods allow to work
|
||||||
with additional parameters beyond standard IP configuration (as dealt with by
|
with additional parameters beyond standard IP configuration (as dealt with by
|
||||||
`AbstractNIC.ipconfig()`). These include network-specific and hardware-specific
|
`WLAN.ifconfig()`). These include network-specific and hardware-specific
|
||||||
parameters. For setting parameters, keyword argument syntax should be used,
|
parameters. For setting parameters, keyword argument syntax should be used,
|
||||||
multiple parameters can be set at once. For querying, parameters name should
|
multiple parameters can be set at once. For querying, parameters name should
|
||||||
be quoted as a string, and only one parameter can be queries at time::
|
be quoted as a string, and only one parameter can be queries at time::
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ This class provides a driver for the WiFi network processor in the WiPy. Example
|
|||||||
wlan.connect('your-ssid', auth=(WLAN.WPA2, 'your-key'))
|
wlan.connect('your-ssid', auth=(WLAN.WPA2, 'your-key'))
|
||||||
while not wlan.isconnected():
|
while not wlan.isconnected():
|
||||||
time.sleep_ms(50)
|
time.sleep_ms(50)
|
||||||
print(wlan.ipconfig("addr4"))
|
print(wlan.ifconfig())
|
||||||
|
|
||||||
# now use socket as usual
|
# now use socket as usual
|
||||||
...
|
...
|
||||||
@@ -96,10 +96,16 @@ Methods
|
|||||||
In case of STA mode, returns ``True`` if connected to a WiFi access point and has a valid IP address.
|
In case of STA mode, returns ``True`` if connected to a WiFi access point and has a valid IP address.
|
||||||
In AP mode returns ``True`` when a station is connected, ``False`` otherwise.
|
In AP mode returns ``True`` when a station is connected, ``False`` otherwise.
|
||||||
|
|
||||||
.. method:: WLANWiPy.ipconfig('param')
|
.. method:: WLANWiPy.ifconfig(if_id=0, config=['dhcp' or configtuple])
|
||||||
WLANWiPy.ipconfig(param=value, ...)
|
|
||||||
|
|
||||||
See :meth:`AbstractNIC.ipconfig <AbstractNIC.ipconfig>`. Supported parameters are: ``dhcp4``, ``addr4``, ``gw4``.
|
With no parameters given returns a 4-tuple of *(ip, subnet_mask, gateway, DNS_server)*.
|
||||||
|
|
||||||
|
if ``'dhcp'`` is passed as a parameter then the DHCP client is enabled and the IP params
|
||||||
|
are negotiated with the AP.
|
||||||
|
|
||||||
|
If the 4-tuple config is given then a static IP is configured. For instance::
|
||||||
|
|
||||||
|
wlan.ifconfig(config=('192.168.0.4', '255.255.255.0', '192.168.0.1', '8.8.8.8'))
|
||||||
|
|
||||||
.. method:: WLANWiPy.mode([mode])
|
.. method:: WLANWiPy.mode([mode])
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ For example::
|
|||||||
print("Waiting for connection...")
|
print("Waiting for connection...")
|
||||||
while not nic.isconnected():
|
while not nic.isconnected():
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
print(nic.ipconfig("addr4"))
|
print(nic.ifconfig())
|
||||||
|
|
||||||
# now use socket as usual
|
# now use socket as usual
|
||||||
import socket
|
import socket
|
||||||
@@ -113,48 +113,8 @@ parameter should be `id`.
|
|||||||
connected to the AP. The list contains tuples of the form
|
connected to the AP. The list contains tuples of the form
|
||||||
(MAC, RSSI).
|
(MAC, RSSI).
|
||||||
|
|
||||||
.. method:: AbstractNIC.ipconfig('param')
|
|
||||||
AbstractNIC.ipconfig(param=value, ...)
|
|
||||||
|
|
||||||
Get or set interface-specific IP-configuration interface parameters.
|
|
||||||
Supported parameters are the following (availability of a particular
|
|
||||||
parameter depends on the port and the specific network interface):
|
|
||||||
|
|
||||||
* ``dhcp4`` (``True/False``) obtain an IPv4 address, gateway and dns
|
|
||||||
server via DHCP. This method does not block and wait for an address
|
|
||||||
to be obtained. To check if an address was obtained, use the read-only
|
|
||||||
property ``has_dhcp4``.
|
|
||||||
* ``gw4`` Get/set the IPv4 default-gateway.
|
|
||||||
* ``dhcp6`` (``True/False``) obtain a DNS server via stateless DHCPv6.
|
|
||||||
Obtaining IP Addresses via DHCPv6 is currently not implemented.
|
|
||||||
* ``autoconf6`` (``True/False``) obtain a stateless IPv6 address via
|
|
||||||
the network prefix shared in router advertisements. To check if a
|
|
||||||
stateless address was obtained, use the read-only
|
|
||||||
property ``has_autoconf6``.
|
|
||||||
* ``addr4`` (e.g. ``192.168.0.4/24``) obtain the current IPv4 address
|
|
||||||
and network mask as ``(ip, subnet)``-tuple, regardless of how this
|
|
||||||
address was obtained. This method can be used to set a static IPv4
|
|
||||||
address either as ``(ip, subnet)``-tuple or in CIDR-notation.
|
|
||||||
* ``addr6`` (e.g. ``fe80::1234:5678``) obtain a list of current IPv6
|
|
||||||
addresses as ``(ip, state, preferred_lifetime, valid_lifetime)``-tuple.
|
|
||||||
This include link-local, slaac and static addresses.
|
|
||||||
``preferred_lifetime`` and ``valid_lifetime`` represent the remaining
|
|
||||||
valid and preferred lifetime of each IPv6 address, in seconds.
|
|
||||||
``state`` indicates the current state of the address:
|
|
||||||
|
|
||||||
* ``0x08`` - ``0x0f`` indicates the address is tentative, counting the
|
|
||||||
number of probes sent.
|
|
||||||
* ``0x10`` The address is deprecated (but still valid)
|
|
||||||
* ``0x30`` The address is preferred (and valid)
|
|
||||||
* ``0x40`` The address is duplicated and can not be used.
|
|
||||||
|
|
||||||
This method can be used to set a static IPv6
|
|
||||||
address, by setting this parameter to the address, like ``fe80::1234:5678``.
|
|
||||||
|
|
||||||
.. method:: AbstractNIC.ifconfig([(ip, subnet, gateway, dns)])
|
.. method:: AbstractNIC.ifconfig([(ip, subnet, gateway, dns)])
|
||||||
|
|
||||||
.. note:: This function is deprecated, use `ipconfig()` instead.
|
|
||||||
|
|
||||||
Get/set IP-level network interface parameters: IP address, subnet mask,
|
Get/set IP-level network interface parameters: IP address, subnet mask,
|
||||||
gateway and DNS server. When called with no arguments, this method returns
|
gateway and DNS server. When called with no arguments, this method returns
|
||||||
a 4-tuple with the above information. To set the above values, pass a
|
a 4-tuple with the above information. To set the above values, pass a
|
||||||
@@ -167,7 +127,7 @@ parameter should be `id`.
|
|||||||
|
|
||||||
Get or set general network interface parameters. These methods allow to work
|
Get or set general network interface parameters. These methods allow to work
|
||||||
with additional parameters beyond standard IP configuration (as dealt with by
|
with additional parameters beyond standard IP configuration (as dealt with by
|
||||||
`ipconfig()`). These include network-specific and hardware-specific
|
`ifconfig()`). These include network-specific and hardware-specific
|
||||||
parameters. For setting parameters, the keyword argument
|
parameters. For setting parameters, the keyword argument
|
||||||
syntax should be used, and multiple parameters can be set at once. For
|
syntax should be used, and multiple parameters can be set at once. For
|
||||||
querying, a parameter name should be quoted as a string, and only one
|
querying, a parameter name should be quoted as a string, and only one
|
||||||
@@ -192,7 +152,6 @@ provide a way to control networking interfaces of various kinds.
|
|||||||
network.WLANWiPy.rst
|
network.WLANWiPy.rst
|
||||||
network.WIZNET5K.rst
|
network.WIZNET5K.rst
|
||||||
network.LAN.rst
|
network.LAN.rst
|
||||||
network.PPP.rst
|
|
||||||
|
|
||||||
Network functions
|
Network functions
|
||||||
=================
|
=================
|
||||||
@@ -236,20 +195,6 @@ The following are functions available in the network module.
|
|||||||
|
|
||||||
The default hostname is typically the name of the board.
|
The default hostname is typically the name of the board.
|
||||||
|
|
||||||
.. function:: ipconfig('param')
|
|
||||||
ipconfig(param=value, ...)
|
|
||||||
|
|
||||||
Get or set global IP-configuration parameters.
|
|
||||||
Supported parameters are the following (availability of a particular
|
|
||||||
parameter depends on the port and the specific network interface):
|
|
||||||
|
|
||||||
* ``dns`` Get/set DNS server. This method can support both, IPv4 and
|
|
||||||
IPv6 addresses.
|
|
||||||
* ``prefer`` (``4/6``) Specify which address type to return, if a domain
|
|
||||||
name has both A and AAAA records. Note, that this does not clear the
|
|
||||||
local DNS cache, so that any previously obtained addresses might not
|
|
||||||
change.
|
|
||||||
|
|
||||||
.. function:: phy_mode([mode])
|
.. function:: phy_mode([mode])
|
||||||
|
|
||||||
Get or set the PHY mode.
|
Get or set the PHY mode.
|
||||||
|
|||||||
@@ -27,17 +27,6 @@ Constructors
|
|||||||
Methods
|
Methods
|
||||||
-------
|
-------
|
||||||
|
|
||||||
.. method:: PIO.gpio_base([base])
|
|
||||||
|
|
||||||
Query and optionally set the current GPIO base for this PIO instance.
|
|
||||||
|
|
||||||
If an argument is given then it must be a pin (or integer corresponding to a pin
|
|
||||||
number), restricted to either GPIO0 or GPIO16. The GPIO base will then be set to
|
|
||||||
that pin. Setting the GPIO base must be done before any programs are added or state
|
|
||||||
machines created.
|
|
||||||
|
|
||||||
Returns the current GPIO base pin.
|
|
||||||
|
|
||||||
.. method:: PIO.add_program(program)
|
.. method:: PIO.add_program(program)
|
||||||
|
|
||||||
Add the *program* to the instruction memory of this PIO instance.
|
Add the *program* to the instruction memory of this PIO instance.
|
||||||
|
|||||||
@@ -438,10 +438,6 @@ The i.MXRT MCU supports battery backup of the RTC. By connecting a battery of
|
|||||||
current drawn from the battery is ~20µA, which is rather high. A CR2032 coin
|
current drawn from the battery is ~20µA, which is rather high. A CR2032 coin
|
||||||
cell will last for about one year.
|
cell will last for about one year.
|
||||||
|
|
||||||
Note: In v1.23.0 the support for subseconds was removed. When reading the RTC, 0 will
|
|
||||||
be returned as value for subsecond, When setting the RTC time, the subsecond
|
|
||||||
field is ignored. The RTC itself does not provide a microsecond value.
|
|
||||||
|
|
||||||
SD card
|
SD card
|
||||||
-------
|
-------
|
||||||
|
|
||||||
@@ -532,7 +528,7 @@ Ethernet. Example usage::
|
|||||||
lan.active(True)
|
lan.active(True)
|
||||||
|
|
||||||
If there is a DHCP server in the LAN, the IP address is supplied by that server.
|
If there is a DHCP server in the LAN, the IP address is supplied by that server.
|
||||||
Otherwise, the IP address can be set with lan.ipconfig(addr4="..."). The default address
|
Otherwise, the IP address can be set with lan.ifconfig(). The default address
|
||||||
is 192.168.0.1.
|
is 192.168.0.1.
|
||||||
|
|
||||||
Teensy 4.1 does not have an Ethernet jack on the board, but PJRC offers an
|
Teensy 4.1 does not have an Ethernet jack on the board, but PJRC offers an
|
||||||
|
|||||||
@@ -227,12 +227,11 @@ The full list of supported commands are:
|
|||||||
- ``cat <file..>`` to show the contents of a file or files on the device
|
- ``cat <file..>`` to show the contents of a file or files on the device
|
||||||
- ``ls`` to list the current directory
|
- ``ls`` to list the current directory
|
||||||
- ``ls <dirs...>`` to list the given directories
|
- ``ls <dirs...>`` to list the given directories
|
||||||
- ``cp [-rf] <src...> <dest>`` to copy files
|
- ``cp [-r] <src...> <dest>`` to copy files
|
||||||
- ``rm <src...>`` to remove files on the device
|
- ``rm <src...>`` to remove files on the device
|
||||||
- ``mkdir <dirs...>`` to create directories on the device
|
- ``mkdir <dirs...>`` to create directories on the device
|
||||||
- ``rmdir <dirs...>`` to remove directories on the device
|
- ``rmdir <dirs...>`` to remove directories on the device
|
||||||
- ``touch <file..>`` to create the files (if they don't already exist)
|
- ``touch <file..>`` to create the files (if they don't already exist)
|
||||||
- ``sha256sum <file..>`` to calculate the SHA256 sum of files
|
|
||||||
|
|
||||||
The ``cp`` command uses a convention where a leading ``:`` represents a remote
|
The ``cp`` command uses a convention where a leading ``:`` represents a remote
|
||||||
path. Without a leading ``:`` means a local path. This is based on the
|
path. Without a leading ``:`` means a local path. This is based on the
|
||||||
@@ -257,11 +256,6 @@ The full list of supported commands are:
|
|||||||
This will copy the file to the device then enter the REPL. The ``+`` prevents
|
This will copy the file to the device then enter the REPL. The ``+`` prevents
|
||||||
``"repl"`` being interpreted as a path.
|
``"repl"`` being interpreted as a path.
|
||||||
|
|
||||||
The ``cp`` command supports the ``-r`` option to make a recursive copy. By
|
|
||||||
default ``cp`` will skip copying files to the remote device if the SHA256 hash
|
|
||||||
of the source and destination file matches. To force a copy regardless of the
|
|
||||||
hash use the ``-f`` option.
|
|
||||||
|
|
||||||
**Note:** For convenience, all of the filesystem sub-commands are also
|
**Note:** For convenience, all of the filesystem sub-commands are also
|
||||||
:ref:`aliased as regular commands <mpremote_shortcuts>`, i.e. you can write
|
:ref:`aliased as regular commands <mpremote_shortcuts>`, i.e. you can write
|
||||||
``mpremote cp ...`` instead of ``mpremote fs cp ...``.
|
``mpremote cp ...`` instead of ``mpremote fs cp ...``.
|
||||||
@@ -475,9 +469,9 @@ An example ``config.py`` might look like:
|
|||||||
for ap in wl.scan():
|
for ap in wl.scan():
|
||||||
print(ap)
|
print(ap)
|
||||||
""",], # Print out nearby WiFi networks.
|
""",], # Print out nearby WiFi networks.
|
||||||
"wl_ipconfig": [
|
"wl_ifconfig": [
|
||||||
"exec",
|
"exec",
|
||||||
"import network; sta_if = network.WLAN(network.STA_IF); print(sta_if.ipconfig('addr4'))",
|
"import network; sta_if = network.WLAN(network.STA_IF); print(sta_if.ifconfig())",
|
||||||
""",], # Print ip address of station interface.
|
""",], # Print ip address of station interface.
|
||||||
"test": ["mount", ".", "exec", "import test"], # Mount current directory and run test.py.
|
"test": ["mount", ".", "exec", "import test"], # Mount current directory and run test.py.
|
||||||
"demo": ["run", "path/to/demo.py"], # Execute demo.py on the device.
|
"demo": ["run", "path/to/demo.py"], # Execute demo.py on the device.
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ If importing an .mpy file fails then try the following:
|
|||||||
sys_mpy = sys.implementation._mpy
|
sys_mpy = sys.implementation._mpy
|
||||||
arch = [None, 'x86', 'x64',
|
arch = [None, 'x86', 'x64',
|
||||||
'armv6', 'armv6m', 'armv7m', 'armv7em', 'armv7emsp', 'armv7emdp',
|
'armv6', 'armv6m', 'armv7m', 'armv7em', 'armv7emsp', 'armv7emdp',
|
||||||
'xtensa', 'xtensawin', 'rv32imc'][sys_mpy >> 10]
|
'xtensa', 'xtensawin'][sys_mpy >> 10]
|
||||||
print('mpy version:', sys_mpy & 0xff)
|
print('mpy version:', sys_mpy & 0xff)
|
||||||
print('mpy sub-version:', sys_mpy >> 8 & 3)
|
print('mpy sub-version:', sys_mpy >> 8 & 3)
|
||||||
print('mpy flags:', end='')
|
print('mpy flags:', end='')
|
||||||
|
|||||||
@@ -120,8 +120,9 @@ Some more examples::
|
|||||||
# Same, but using . instead.
|
# Same, but using . instead.
|
||||||
$ pyboard.py --device /dev/ttyACM0 -f cp :main.py .
|
$ pyboard.py --device /dev/ttyACM0 -f cp :main.py .
|
||||||
|
|
||||||
# Copy three files to the device, keeping their names.
|
# Copy three files to the device, keeping their names
|
||||||
$ pyboard.py --device /dev/ttyACM0 -f cp main.py app.py foo.py :
|
# and paths (note: `lib` must exist on the device)
|
||||||
|
$ pyboard.py --device /dev/ttyACM0 -f cp main.py app.py lib/foo.py :
|
||||||
|
|
||||||
# Remove a file from the device.
|
# Remove a file from the device.
|
||||||
$ pyboard.py --device /dev/ttyACM0 -f rm util.py
|
$ pyboard.py --device /dev/ttyACM0 -f rm util.py
|
||||||
|
|||||||
@@ -31,25 +31,12 @@ The MicroPython REPL is accessed via the USB serial port. Tab-completion is usef
|
|||||||
find out what methods an object has. Paste mode (ctrl-E) is useful to paste a
|
find out what methods an object has. Paste mode (ctrl-E) is useful to paste a
|
||||||
large slab of Python code into the REPL.
|
large slab of Python code into the REPL.
|
||||||
|
|
||||||
The :mod:`machine` module:
|
The :mod:`machine` module::
|
||||||
|
|
||||||
machine.freq() allows to change the MCU frequency and control the peripheral
|
|
||||||
frequency for UART and SPI. Usage::
|
|
||||||
|
|
||||||
machine.freq(MCU_frequency[, peripheral_frequency=48_000_000])
|
|
||||||
|
|
||||||
The MCU frequency can be set in a range from less than 48 MHz to about 250MHz.
|
|
||||||
The default at boot time is 125 MHz. The peripheral frequency must be either
|
|
||||||
48 MHz or identical to the MCU frequency, with 48 MHz as the default.
|
|
||||||
If the peripheral frequency is changed, any already existing instance of
|
|
||||||
UART and SPI will change it's baud rate and may have to be re-configured::
|
|
||||||
|
|
||||||
import machine
|
import machine
|
||||||
|
|
||||||
machine.freq() # get the current frequency of the CPU
|
machine.freq() # get the current frequency of the CPU
|
||||||
machine.freq(240000000) # set the CPU frequency to 240 MHz and keep
|
machine.freq(240000000) # set the CPU frequency to 240 MHz
|
||||||
# the UART frequency at 48MHz
|
|
||||||
machine.freq(125000000, 125000000) # set the CPU and UART frequency to 125 MHz
|
|
||||||
|
|
||||||
The :mod:`rp2` module::
|
The :mod:`rp2` module::
|
||||||
|
|
||||||
@@ -200,14 +187,6 @@ Use the :ref:`machine.ADC <machine.ADC>` class::
|
|||||||
adc = ADC(Pin(26)) # create ADC object on ADC pin
|
adc = ADC(Pin(26)) # create ADC object on ADC pin
|
||||||
adc.read_u16() # read value, 0-65535 across voltage range 0.0v - 3.3v
|
adc.read_u16() # read value, 0-65535 across voltage range 0.0v - 3.3v
|
||||||
|
|
||||||
The argument of the constructor ADC specifies either a Pin by number, name of as
|
|
||||||
Pin object, or a channel number in the range 0 - 3 or ADC.CORE_TEMP for the
|
|
||||||
internal temperature sensor. If a pin is specified,
|
|
||||||
the pin is initialized in high-Z mode. If a channel number is used, the pin
|
|
||||||
is not initialized and configuring is left to the user code. After hard reset,
|
|
||||||
RP2040 pins operate in current sink mode at about 60µA. If the pin is not
|
|
||||||
otherwise configured, that may lead to wrong ADC readings.
|
|
||||||
|
|
||||||
Software SPI bus
|
Software SPI bus
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
|||||||
@@ -65,8 +65,6 @@ Use the :mod:`time <time>` module::
|
|||||||
start = time.ticks_ms() # get millisecond counter
|
start = time.ticks_ms() # get millisecond counter
|
||||||
delta = time.ticks_diff(time.ticks_ms(), start) # compute time difference
|
delta = time.ticks_diff(time.ticks_ms(), start) # compute time difference
|
||||||
|
|
||||||
Note that :func:`time.sleep_us()` delays by busy waiting. During that time, other tasks are
|
|
||||||
not scheduled.
|
|
||||||
|
|
||||||
Clock and time
|
Clock and time
|
||||||
--------------
|
--------------
|
||||||
|
|||||||
@@ -184,18 +184,18 @@ WLAN (WiFi)
|
|||||||
|
|
||||||
See :ref:`network.WLAN <network.WLAN>` and :mod:`machine`. ::
|
See :ref:`network.WLAN <network.WLAN>` and :mod:`machine`. ::
|
||||||
|
|
||||||
import machine, network
|
import machine
|
||||||
from network import WLAN
|
from network import WLAN
|
||||||
|
|
||||||
# configure the WLAN subsystem in station mode (the default is AP)
|
# configure the WLAN subsystem in station mode (the default is AP)
|
||||||
wlan = WLAN(mode=WLAN.STA)
|
wlan = WLAN(mode=WLAN.STA)
|
||||||
# go for fixed IP settings
|
# go for fixed IP settings
|
||||||
network.ipconfig(dns='8.8.8.8')
|
wlan.ifconfig(config=('192.168.0.107', '255.255.255.0', '192.168.0.1', '8.8.8.8'))
|
||||||
wlan.ipconfig(addr4='192.168.0.107/24', gw4='192.168.0.1')
|
|
||||||
wlan.scan() # scan for available networks
|
wlan.scan() # scan for available networks
|
||||||
wlan.connect(ssid='mynetwork', auth=(WLAN.WPA2, 'mynetworkkey'))
|
wlan.connect(ssid='mynetwork', auth=(WLAN.WPA2, 'mynetworkkey'))
|
||||||
while not wlan.isconnected():
|
while not wlan.isconnected():
|
||||||
pass
|
pass
|
||||||
|
print(wlan.ifconfig())
|
||||||
# enable wake on WLAN
|
# enable wake on WLAN
|
||||||
wlan.irq(trigger=WLAN.ANY_EVENT, wake=machine.SLEEP)
|
wlan.irq(trigger=WLAN.ANY_EVENT, wake=machine.SLEEP)
|
||||||
# go to sleep
|
# go to sleep
|
||||||
|
|||||||
@@ -50,15 +50,14 @@ Assigning a static IP address when booting
|
|||||||
If you want your WiPy to connect to your home router after boot-up, and with a fixed
|
If you want your WiPy to connect to your home router after boot-up, and with a fixed
|
||||||
IP address so that you can access it via telnet or FTP, use the following script as /flash/boot.py::
|
IP address so that you can access it via telnet or FTP, use the following script as /flash/boot.py::
|
||||||
|
|
||||||
import machine, network
|
import machine
|
||||||
from network import WLAN
|
from network import WLAN
|
||||||
wlan = WLAN() # get current object, without changing the mode
|
wlan = WLAN() # get current object, without changing the mode
|
||||||
|
|
||||||
if machine.reset_cause() != machine.SOFT_RESET:
|
if machine.reset_cause() != machine.SOFT_RESET:
|
||||||
wlan.init(WLAN.STA)
|
wlan.init(WLAN.STA)
|
||||||
# configuration below MUST match your home router settings!!
|
# configuration below MUST match your home router settings!!
|
||||||
network.ipconfig(dns='8.8.8.8')
|
wlan.ifconfig(config=('192.168.178.107', '255.255.255.0', '192.168.178.1', '8.8.8.8'))
|
||||||
wlan.ipconfig(addr4='192.168.0.107/24', gw4='192.168.0.1')
|
|
||||||
|
|
||||||
if not wlan.isconnected():
|
if not wlan.isconnected():
|
||||||
# change the line below to match your network ssid, security and password
|
# change the line below to match your network ssid, security and password
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ Use the :ref:`machine.Pin <machine.Pin>` class::
|
|||||||
|
|
||||||
from machine import Pin
|
from machine import Pin
|
||||||
|
|
||||||
pin = Pin(("gpiob", 21), Pin.IN) # create input pin on GPIO port B
|
pin = Pin(("GPIO_1", 21), Pin.IN) # create input pin on GPIO1
|
||||||
print(pin) # print pin port and number
|
print(pin) # print pin port and number
|
||||||
|
|
||||||
pin.init(Pin.OUT, Pin.PULL_UP, value=1) # reinitialize pin
|
pin.init(Pin.OUT, Pin.PULL_UP, value=1) # reinitialize pin
|
||||||
@@ -47,14 +47,14 @@ Use the :ref:`machine.Pin <machine.Pin>` class::
|
|||||||
pin.on() # set pin to high
|
pin.on() # set pin to high
|
||||||
pin.off() # set pin to low
|
pin.off() # set pin to low
|
||||||
|
|
||||||
pin = Pin(("gpiob", 21), Pin.IN) # create input pin on GPIO port B
|
pin = Pin(("GPIO_1", 21), Pin.IN) # create input pin on GPIO1
|
||||||
|
|
||||||
pin = Pin(("gpiob", 21), Pin.OUT, value=1) # set pin high on creation
|
pin = Pin(("GPIO_1", 21), Pin.OUT, value=1) # set pin high on creation
|
||||||
|
|
||||||
pin = Pin(("gpiob", 21), Pin.IN, Pin.PULL_UP) # enable internal pull-up resistor
|
pin = Pin(("GPIO_1", 21), Pin.IN, Pin.PULL_UP) # enable internal pull-up resistor
|
||||||
|
|
||||||
switch = Pin(("gpioc", 6), Pin.IN) # create input pin for a switch
|
switch = Pin(("GPIO_2", 6), Pin.IN) # create input pin for a switch
|
||||||
switch.irq(lambda t: print("SW2 changed")) # enable an interrupt when switch state is changed
|
switch.irq(lambda t: print("SW2 changed")) # enable an interrupt when switch state is changed
|
||||||
|
|
||||||
Hardware I2C bus
|
Hardware I2C bus
|
||||||
----------------
|
----------------
|
||||||
@@ -63,7 +63,7 @@ Hardware I2C is accessed via the :ref:`machine.I2C <machine.I2C>` class::
|
|||||||
|
|
||||||
from machine import I2C
|
from machine import I2C
|
||||||
|
|
||||||
i2c = I2C("i2c0") # construct an i2c bus
|
i2c = I2C("I2C_0") # construct an i2c bus
|
||||||
print(i2c) # print device name
|
print(i2c) # print device name
|
||||||
|
|
||||||
i2c.scan() # scan the device for available I2C slaves
|
i2c.scan() # scan the device for available I2C slaves
|
||||||
@@ -84,11 +84,11 @@ Hardware SPI is accessed via the :ref:`machine.SPI <machine.SPI>` class::
|
|||||||
|
|
||||||
from machine import SPI
|
from machine import SPI
|
||||||
|
|
||||||
spi = SPI("spi0") # construct a spi bus with default configuration
|
spi = SPI("SPI_0") # construct a spi bus with default configuration
|
||||||
spi.init(baudrate=100000, polarity=0, phase=0, bits=8, firstbit=SPI.MSB) # set configuration
|
spi.init(baudrate=100000, polarity=0, phase=0, bits=8, firstbit=SPI.MSB) # set configuration
|
||||||
|
|
||||||
# equivalently, construct spi bus and set configuration at the same time
|
# equivalently, construct spi bus and set configuration at the same time
|
||||||
spi = SPI("spi0", baudrate=100000, polarity=0, phase=0, bits=8, firstbit=SPI.MSB)
|
spi = SPI("SPI_0", baudrate=100000, polarity=0, phase=0, bits=8, firstbit=SPI.MSB)
|
||||||
print(spi) # print device name and bus configuration
|
print(spi) # print device name and bus configuration
|
||||||
|
|
||||||
spi.read(4) # read 4 bytes on MISO
|
spi.read(4) # read 4 bytes on MISO
|
||||||
@@ -146,7 +146,7 @@ Use the :ref:`zsensor.Sensor <zsensor.Sensor>` class to access sensor data::
|
|||||||
import zsensor
|
import zsensor
|
||||||
from zsensor import Sensor
|
from zsensor import Sensor
|
||||||
|
|
||||||
accel = Sensor("fxos8700") # create sensor object for the accelerometer
|
accel = Sensor("FXOX8700") # create sensor object for the accelerometer
|
||||||
|
|
||||||
accel.measure() # obtain a measurement reading from the accelerometer
|
accel.measure() # obtain a measurement reading from the accelerometer
|
||||||
|
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ With your serial program open (PuTTY, screen, picocom, etc) you may see a
|
|||||||
blank screen with a flashing cursor. Press Enter (or reset the board) and
|
blank screen with a flashing cursor. Press Enter (or reset the board) and
|
||||||
you should be presented with the following text::
|
you should be presented with the following text::
|
||||||
|
|
||||||
*** Booting Zephyr OS build v3.7.0 ***
|
*** Booting Zephyr OS build zephyr-v3.1.0 ***
|
||||||
MicroPython v1.24.0-preview.179.g5b85b24bd on 2024-08-05; zephyr-frdm_k64f with mk64f12
|
MicroPython v1.19.1-9-g4fd54a475 on 2022-06-17; zephyr-frdm_k64f with mk64f12
|
||||||
Type "help()" for more information.
|
Type "help()" for more information.
|
||||||
>>>
|
>>>
|
||||||
|
|
||||||
|
|||||||
@@ -44,36 +44,28 @@ int mp_soft_spi_ioctl(void *self_in, uint32_t cmd) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t swap_bits(uint8_t byte) {
|
|
||||||
const static uint8_t swap_table[16] = {
|
|
||||||
0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e,
|
|
||||||
0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f
|
|
||||||
};
|
|
||||||
return ((swap_table[byte & 0x0f] << 4) | swap_table[byte >> 4]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mp_soft_spi_transfer(void *self_in, size_t len, const uint8_t *src, uint8_t *dest) {
|
void mp_soft_spi_transfer(void *self_in, size_t len, const uint8_t *src, uint8_t *dest) {
|
||||||
mp_soft_spi_obj_t *self = (mp_soft_spi_obj_t*)self_in;
|
mp_soft_spi_obj_t *self = (mp_soft_spi_obj_t*)self_in;
|
||||||
uint32_t delay_half = self->delay_half;
|
uint32_t delay_half = self->delay_half;
|
||||||
|
|
||||||
|
// only MSB transfer is implemented
|
||||||
|
|
||||||
// If a port defines MICROPY_HW_SOFTSPI_MIN_DELAY, and the configured
|
// If a port defines MICROPY_HW_SOFTSPI_MIN_DELAY, and the configured
|
||||||
// delay_half is equal to this value, then the software SPI implementation
|
// delay_half is equal to this value, then the software SPI implementation
|
||||||
// will run as fast as possible, limited only by CPU speed and GPIO time.
|
// will run as fast as possible, limited only by CPU speed and GPIO time.
|
||||||
#ifdef MICROPY_HW_SOFTSPI_MIN_DELAY
|
#ifdef MICROPY_HW_SOFTSPI_MIN_DELAY
|
||||||
if (delay_half == MICROPY_HW_SOFTSPI_MIN_DELAY) {
|
if (delay_half == MICROPY_HW_SOFTSPI_MIN_DELAY) {
|
||||||
for (size_t i = 0; i < len; ++i) {
|
for (size_t i = 0; i < len; ++i) {
|
||||||
uint8_t data_out = self->firstbit != MICROPY_PY_MACHINE_SPI_MSB ?
|
uint8_t data_out = src[i];
|
||||||
src[i] : swap_bits(src[i]);
|
|
||||||
uint8_t data_in = 0;
|
uint8_t data_in = 0;
|
||||||
for (int j = 0; j < 8; ++j, data_out >>= 1) {
|
for (int j = 0; j < 8; ++j, data_out <<= 1) {
|
||||||
mp_hal_pin_write(self->mosi, data_out & 1);
|
mp_hal_pin_write(self->mosi, (data_out >> 7) & 1);
|
||||||
mp_hal_pin_write(self->sck, 1 - self->polarity);
|
mp_hal_pin_write(self->sck, 1 - self->polarity);
|
||||||
data_in = (data_in << 1) | mp_hal_pin_read(self->miso);
|
data_in = (data_in << 1) | mp_hal_pin_read(self->miso);
|
||||||
mp_hal_pin_write(self->sck, self->polarity);
|
mp_hal_pin_write(self->sck, self->polarity);
|
||||||
}
|
}
|
||||||
if (dest != NULL) {
|
if (dest != NULL) {
|
||||||
dest[i] = self->firstbit == MICROPY_PY_MACHINE_SPI_MSB ?
|
dest[i] = data_in;
|
||||||
data_in : swap_bits(data_in);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -81,11 +73,10 @@ void mp_soft_spi_transfer(void *self_in, size_t len, const uint8_t *src, uint8_t
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (size_t i = 0; i < len; ++i) {
|
for (size_t i = 0; i < len; ++i) {
|
||||||
uint8_t data_out = self->firstbit != MICROPY_PY_MACHINE_SPI_MSB ?
|
uint8_t data_out = src[i];
|
||||||
src[i] : swap_bits(src[i]);
|
|
||||||
uint8_t data_in = 0;
|
uint8_t data_in = 0;
|
||||||
for (int j = 0; j < 8; ++j, data_out >>= 1) {
|
for (int j = 0; j < 8; ++j, data_out <<= 1) {
|
||||||
mp_hal_pin_write(self->mosi, data_out & 1);
|
mp_hal_pin_write(self->mosi, (data_out >> 7) & 1);
|
||||||
if (self->phase == 0) {
|
if (self->phase == 0) {
|
||||||
mp_hal_delay_us_fast(delay_half);
|
mp_hal_delay_us_fast(delay_half);
|
||||||
mp_hal_pin_write(self->sck, 1 - self->polarity);
|
mp_hal_pin_write(self->sck, 1 - self->polarity);
|
||||||
@@ -103,8 +94,7 @@ void mp_soft_spi_transfer(void *self_in, size_t len, const uint8_t *src, uint8_t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dest != NULL) {
|
if (dest != NULL) {
|
||||||
dest[i] = self->firstbit == MICROPY_PY_MACHINE_SPI_MSB ?
|
dest[i] = data_in;
|
||||||
data_in : swap_bits(data_in);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ typedef struct _mp_soft_spi_obj_t {
|
|||||||
uint32_t delay_half; // microsecond delay for half SCK period
|
uint32_t delay_half; // microsecond delay for half SCK period
|
||||||
uint8_t polarity;
|
uint8_t polarity;
|
||||||
uint8_t phase;
|
uint8_t phase;
|
||||||
uint8_t firstbit;
|
|
||||||
mp_hal_pin_obj_t sck;
|
mp_hal_pin_obj_t sck;
|
||||||
mp_hal_pin_obj_t mosi;
|
mp_hal_pin_obj_t mosi;
|
||||||
mp_hal_pin_obj_t miso;
|
mp_hal_pin_obj_t miso;
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ typedef enum {
|
|||||||
|
|
||||||
// AP mode commands.
|
// AP mode commands.
|
||||||
NINA_CMD_START_AP_OPEN = 0x18,
|
NINA_CMD_START_AP_OPEN = 0x18,
|
||||||
NINA_CMD_START_AP_WPA = 0x19,
|
NINA_CMD_START_AP_WEP = 0x19,
|
||||||
|
|
||||||
// AP mode scan commands.
|
// AP mode scan commands.
|
||||||
NINA_CMD_AP_START_SCAN = 0x36,
|
NINA_CMD_AP_START_SCAN = 0x36,
|
||||||
@@ -395,7 +395,7 @@ int nina_start_ap(const char *ssid, uint8_t security, const char *key, uint16_t
|
|||||||
uint8_t status = NINA_STATUS_AP_FAILED;
|
uint8_t status = NINA_STATUS_AP_FAILED;
|
||||||
|
|
||||||
if ((key == NULL && security != NINA_SEC_OPEN) ||
|
if ((key == NULL && security != NINA_SEC_OPEN) ||
|
||||||
(security != NINA_SEC_OPEN && security != NINA_SEC_WPA_PSK)) {
|
(security != NINA_SEC_OPEN && security != NINA_SEC_WEP)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,8 +406,8 @@ int nina_start_ap(const char *ssid, uint8_t security, const char *key, uint16_t
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NINA_SEC_WPA_PSK:
|
case NINA_SEC_WEP:
|
||||||
if (nina_send_command_read_ack(NINA_CMD_START_AP_WPA,
|
if (nina_send_command_read_ack(NINA_CMD_START_AP_WEP,
|
||||||
3, ARG_8BITS, NINA_ARGS(ARG_STR(ssid), ARG_STR(key), ARG_BYTE(channel))) != SPI_ACK) {
|
3, ARG_8BITS, NINA_ARGS(ARG_STR(ssid), ARG_STR(key), ARG_BYTE(channel))) != SPI_ACK) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
# Dynamic Native Modules
|
# Dynamic Native Modules
|
||||||
|
|
||||||
Dynamic Native Modules are .mpy files that contain native machine code from a
|
Dynamic Native Modules are .mpy files that contain native machine code from a
|
||||||
language other than Python. For more info see [the
|
language other than Python. For more info see [the documentation]
|
||||||
documentation](https://docs.micropython.org/en/latest/develop/natmod.html).
|
(https://docs.micropython.org/en/latest/develop/natmod.html).
|
||||||
|
|
||||||
This should not be confused with [User C
|
This should not be confused with [User C Modules]
|
||||||
Modules](https://docs.micropython.org/en/latest/develop/cmodules.html) which are
|
(https://docs.micropython.org/en/latest/develop/cmodules.html) which are a
|
||||||
a mechanism to add additional out-of-tree modules into the firmware build.
|
mechanism to add additional out-of-tree modules into the firmware build.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
const char *stack_top;
|
const char *stack_top;
|
||||||
|
|
||||||
void mp_cstack_check(void) {
|
void mp_stack_check(void) {
|
||||||
// Assumes descending stack on target
|
// Assumes descending stack on target
|
||||||
volatile char dummy;
|
volatile char dummy;
|
||||||
if (stack_top - &dummy >= STACK_LIMIT) {
|
if (stack_top - &dummy >= STACK_LIMIT) {
|
||||||
|
|||||||
@@ -1,52 +1,27 @@
|
|||||||
# Very simple HTTP client example:
|
|
||||||
# - Connects to a server.
|
|
||||||
# - Sends a HTTP request.
|
|
||||||
# - Reads the result.
|
|
||||||
#
|
|
||||||
# This example works in both MicroPython and CPython.
|
|
||||||
#
|
|
||||||
# To implement an HTTP client using less code, use mip to install the requests package:
|
|
||||||
# https://github.com/micropython/micropython-lib/tree/master/python-ecosys/requests
|
|
||||||
|
|
||||||
import socket
|
import socket
|
||||||
|
|
||||||
|
|
||||||
# `addr_family` selects IPv4 vs IPv6: 0 means either, or use
|
def main(use_stream=False):
|
||||||
# socket.AF_INET or socket.AF_INET6 to select a particular one.
|
s = socket.socket()
|
||||||
def main(url, addr_family=0, use_stream=False):
|
|
||||||
# Split the given URL into components.
|
|
||||||
proto, _, host, path = url.split(b"/", 3)
|
|
||||||
assert proto == b"http:"
|
|
||||||
|
|
||||||
# Lookup the server address, for the given family and socket type.
|
ai = socket.getaddrinfo("google.com", 80)
|
||||||
ai = socket.getaddrinfo(host, 80, addr_family, socket.SOCK_STREAM)
|
|
||||||
print("Address infos:", ai)
|
print("Address infos:", ai)
|
||||||
|
addr = ai[0][-1]
|
||||||
|
|
||||||
# Select the first address.
|
|
||||||
ai = ai[0]
|
|
||||||
|
|
||||||
# Create a socket with the server's family, type and proto.
|
|
||||||
s = socket.socket(ai[0], ai[1], ai[2])
|
|
||||||
|
|
||||||
# Connect to the server.
|
|
||||||
addr = ai[-1]
|
|
||||||
print("Connect address:", addr)
|
print("Connect address:", addr)
|
||||||
s.connect(addr)
|
s.connect(addr)
|
||||||
|
|
||||||
# Send request and read response.
|
|
||||||
request = b"GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n" % (path, host)
|
|
||||||
if use_stream:
|
if use_stream:
|
||||||
# MicroPython socket objects support stream (aka file) interface
|
# MicroPython socket objects support stream (aka file) interface
|
||||||
# directly, but the line below is needed for CPython.
|
# directly, but the line below is needed for CPython.
|
||||||
s = s.makefile("rwb", 0)
|
s = s.makefile("rwb", 0)
|
||||||
s.write(request)
|
s.write(b"GET / HTTP/1.0\r\n\r\n")
|
||||||
print(s.read())
|
print(s.read())
|
||||||
else:
|
else:
|
||||||
s.send(request)
|
s.send(b"GET / HTTP/1.0\r\n\r\n")
|
||||||
print(s.recv(4096))
|
print(s.recv(4096))
|
||||||
|
|
||||||
# Close the socket.
|
|
||||||
s.close()
|
s.close()
|
||||||
|
|
||||||
|
|
||||||
main(b"http://www.google.com/")
|
main()
|
||||||
|
|||||||
@@ -1,62 +1,32 @@
|
|||||||
# Very simple HTTPS client example:
|
|
||||||
# - Connects to a server.
|
|
||||||
# - Upgrades the connection to a TLS connection.
|
|
||||||
# - Sends a HTTP request.
|
|
||||||
# - Reads the result.
|
|
||||||
#
|
|
||||||
# This example works in both MicroPython and CPython.
|
|
||||||
#
|
|
||||||
# To implement an HTTPS client using less code, use mip to install the requests package:
|
|
||||||
# https://github.com/micropython/micropython-lib/tree/master/python-ecosys/requests
|
|
||||||
|
|
||||||
import socket
|
import socket
|
||||||
import ssl
|
import ssl
|
||||||
|
|
||||||
|
|
||||||
# `addr_family` selects IPv4 vs IPv6: 0 means either, or use
|
def main(use_stream=True):
|
||||||
# socket.AF_INET or socket.AF_INET6 to select a particular one.
|
s = socket.socket()
|
||||||
def main(url, addr_family=0, use_stream=True):
|
|
||||||
# Split the given URL into components.
|
|
||||||
proto, _, host, path = url.split(b"/", 3)
|
|
||||||
assert proto == b"https:"
|
|
||||||
|
|
||||||
# Lookup the server address, for the given family and socket type.
|
ai = socket.getaddrinfo("google.com", 443)
|
||||||
ai = socket.getaddrinfo(host, 443, addr_family, socket.SOCK_STREAM)
|
|
||||||
print("Address infos:", ai)
|
print("Address infos:", ai)
|
||||||
|
addr = ai[0][-1]
|
||||||
|
|
||||||
# Select the first address.
|
|
||||||
ai = ai[0]
|
|
||||||
|
|
||||||
# Create a socket with the server's family, type and proto.
|
|
||||||
s = socket.socket(ai[0], ai[1], ai[2])
|
|
||||||
|
|
||||||
# Connect to the server.
|
|
||||||
addr = ai[-1]
|
|
||||||
print("Connect address:", addr)
|
print("Connect address:", addr)
|
||||||
s.connect(addr)
|
s.connect(addr)
|
||||||
|
|
||||||
# Upgrade the socket to a TLS connection.
|
s = ssl.wrap_socket(s)
|
||||||
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
|
|
||||||
ctx.check_hostname = False
|
|
||||||
ctx.verify_mode = ssl.CERT_NONE
|
|
||||||
s = ctx.wrap_socket(s)
|
|
||||||
print(s)
|
print(s)
|
||||||
|
|
||||||
# Send request and read response.
|
|
||||||
request = b"GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n" % (path, host)
|
|
||||||
if use_stream:
|
if use_stream:
|
||||||
# Both CPython and MicroPython SSLSocket objects support read() and
|
# Both CPython and MicroPython SSLSocket objects support read() and
|
||||||
# write() methods.
|
# write() methods.
|
||||||
s.write(request)
|
s.write(b"GET / HTTP/1.0\r\n\r\n")
|
||||||
print(s.read(4096))
|
print(s.read(4096))
|
||||||
else:
|
else:
|
||||||
# MicroPython SSLSocket objects implement only stream interface, not
|
# MicroPython SSLSocket objects implement only stream interface, not
|
||||||
# socket interface
|
# socket interface
|
||||||
s.send(request)
|
s.send(b"GET / HTTP/1.0\r\n\r\n")
|
||||||
print(s.recv(4096))
|
print(s.recv(4096))
|
||||||
|
|
||||||
# Close the socket.
|
|
||||||
s.close()
|
s.close()
|
||||||
|
|
||||||
|
|
||||||
main(b"https://www.google.com/")
|
main()
|
||||||
|
|||||||
@@ -37,13 +37,13 @@ def read_nonblocking(poller, sock, n):
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def main(url, addr_family=0):
|
def main(url):
|
||||||
# Split the given URL into components.
|
# Split the given URL into components.
|
||||||
proto, _, host, path = url.split(b"/", 3)
|
proto, _, host, path = url.split(b"/", 3)
|
||||||
assert proto == b"https:"
|
assert proto == b"https:"
|
||||||
|
|
||||||
# Note: this getaddrinfo() call is blocking!
|
# Note: this getaddrinfo() call is blocking!
|
||||||
ai = socket.getaddrinfo(host, 443, addr_family, socket.SOCK_STREAM)[0]
|
ai = socket.getaddrinfo(host, 443)[0]
|
||||||
addr = ai[-1]
|
addr = ai[-1]
|
||||||
print("Connect address:", addr)
|
print("Connect address:", addr)
|
||||||
|
|
||||||
|
|||||||
@@ -68,87 +68,6 @@ MP_DEFINE_CONST_OBJ_TYPE(
|
|||||||
locals_dict, &example_Timer_locals_dict
|
locals_dict, &example_Timer_locals_dict
|
||||||
);
|
);
|
||||||
|
|
||||||
// What follows is a *separate* class definition that demonstrates more
|
|
||||||
// advanced techniques to implement other Python-like features, such as:
|
|
||||||
//
|
|
||||||
// - A custom representation for __repr__ and __str__.
|
|
||||||
// - Custom attribute handling to create a read/write "property".
|
|
||||||
//
|
|
||||||
// It re-uses some of the elements of the basic Timer class. This is allowed
|
|
||||||
// because they both use example_Timer_obj_t as the instance structure.
|
|
||||||
|
|
||||||
// Handles AdvancedTimer.__repr__, AdvancedTimer.__str__.
|
|
||||||
static void example_AdvancedTimer_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
|
||||||
|
|
||||||
// Get the elapsed time. In this case, it's also a demonstration of calling
|
|
||||||
// the equivalent of self.time() in the C API. This is not usually very
|
|
||||||
// efficient, but it can sometimes be useful.
|
|
||||||
mp_uint_t elapsed = mp_obj_get_int(example_Timer_time(self_in));
|
|
||||||
|
|
||||||
// We'll make all representations print at least the class name.
|
|
||||||
mp_printf(print, "%q()", MP_QSTR_AdvancedTimer);
|
|
||||||
|
|
||||||
// Decide what else to print based on print kind.
|
|
||||||
if (kind == PRINT_STR) {
|
|
||||||
// For __str__, let's attempt to make it more readable.
|
|
||||||
mp_printf(print, " # created %d seconds ago", elapsed / 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handles AdvancedTimer.seconds for reading and writing.
|
|
||||||
static void example_AdvancedTimer_attribute_handler(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
|
||||||
|
|
||||||
// In this example, we only want to handle the .seconds attribute in a
|
|
||||||
// special way.
|
|
||||||
if (attr != MP_QSTR_seconds) {
|
|
||||||
// Attribute not found, continue lookup in locals dict. This way,
|
|
||||||
// methods like .time() will be handled normally.
|
|
||||||
dest[1] = MP_OBJ_SENTINEL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get reference to AdvancedTimer instance.
|
|
||||||
example_Timer_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
|
||||||
|
|
||||||
// Check if this is a read operation.
|
|
||||||
if (dest[0] == MP_OBJ_NULL) {
|
|
||||||
// It's read, so "return" elapsed seconds by storing it in dest[0].
|
|
||||||
mp_uint_t elapsed = mp_hal_ticks_ms() - self->start_time;
|
|
||||||
dest[0] = mp_obj_new_int_from_uint(elapsed / 1000);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Check if this is a delete or store operation.
|
|
||||||
else if (dest[0] == MP_OBJ_SENTINEL) {
|
|
||||||
// It's delete or store. Now check which one.
|
|
||||||
if (dest[1] == MP_OBJ_NULL) {
|
|
||||||
// It's delete. But in this example we don't want to allow it
|
|
||||||
// so we just return.
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
// It's write. First, get the value that the user is trying to set.
|
|
||||||
mp_uint_t desired_ms = mp_obj_get_int(dest[1]) * 1000;
|
|
||||||
// Use it to update the start time. This way, the next read will
|
|
||||||
// report the updated time.
|
|
||||||
self->start_time = mp_hal_ticks_ms() - desired_ms;
|
|
||||||
|
|
||||||
// Indicate successful store.
|
|
||||||
dest[0] = MP_OBJ_NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This defines the type(AdvancedTimer) object.
|
|
||||||
MP_DEFINE_CONST_OBJ_TYPE(
|
|
||||||
example_type_AdvancedTimer,
|
|
||||||
MP_QSTR_AdvancedTimer,
|
|
||||||
MP_TYPE_FLAG_NONE,
|
|
||||||
attr, example_AdvancedTimer_attribute_handler,
|
|
||||||
print, example_AdvancedTimer_print,
|
|
||||||
make_new, example_Timer_make_new,
|
|
||||||
locals_dict, &example_Timer_locals_dict
|
|
||||||
);
|
|
||||||
|
|
||||||
// Define all attributes of the module.
|
// Define all attributes of the module.
|
||||||
// Table entries are key/value pairs of the attribute name (a string)
|
// Table entries are key/value pairs of the attribute name (a string)
|
||||||
// and the MicroPython object reference.
|
// and the MicroPython object reference.
|
||||||
@@ -158,7 +77,6 @@ static const mp_rom_map_elem_t example_module_globals_table[] = {
|
|||||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_cexample) },
|
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_cexample) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_add_ints), MP_ROM_PTR(&example_add_ints_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_add_ints), MP_ROM_PTR(&example_add_ints_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&example_type_Timer) },
|
{ MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&example_type_Timer) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_AdvancedTimer), MP_ROM_PTR(&example_type_AdvancedTimer) },
|
|
||||||
};
|
};
|
||||||
static MP_DEFINE_CONST_DICT(example_module_globals, example_module_globals_table);
|
static MP_DEFINE_CONST_DICT(example_module_globals, example_module_globals_table);
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ set(MICROPY_SOURCE_EXTMOD
|
|||||||
${MICROPY_EXTMOD_DIR}/network_cyw43.c
|
${MICROPY_EXTMOD_DIR}/network_cyw43.c
|
||||||
${MICROPY_EXTMOD_DIR}/network_lwip.c
|
${MICROPY_EXTMOD_DIR}/network_lwip.c
|
||||||
${MICROPY_EXTMOD_DIR}/network_ninaw10.c
|
${MICROPY_EXTMOD_DIR}/network_ninaw10.c
|
||||||
${MICROPY_EXTMOD_DIR}/network_ppp_lwip.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/network_wiznet5k.c
|
${MICROPY_EXTMOD_DIR}/network_wiznet5k.c
|
||||||
${MICROPY_EXTMOD_DIR}/os_dupterm.c
|
${MICROPY_EXTMOD_DIR}/os_dupterm.c
|
||||||
${MICROPY_EXTMOD_DIR}/vfs.c
|
${MICROPY_EXTMOD_DIR}/vfs.c
|
||||||
@@ -276,14 +275,11 @@ if(MICROPY_PY_LWIP)
|
|||||||
target_sources(micropy_lib_lwip INTERFACE
|
target_sources(micropy_lib_lwip INTERFACE
|
||||||
${MICROPY_DIR}/shared/netutils/netutils.c
|
${MICROPY_DIR}/shared/netutils/netutils.c
|
||||||
${MICROPY_LIB_LWIP_DIR}/apps/mdns/mdns.c
|
${MICROPY_LIB_LWIP_DIR}/apps/mdns/mdns.c
|
||||||
${MICROPY_LIB_LWIP_DIR}/apps/mdns/mdns_domain.c
|
|
||||||
${MICROPY_LIB_LWIP_DIR}/apps/mdns/mdns_out.c
|
|
||||||
${MICROPY_LIB_LWIP_DIR}/core/def.c
|
${MICROPY_LIB_LWIP_DIR}/core/def.c
|
||||||
${MICROPY_LIB_LWIP_DIR}/core/dns.c
|
${MICROPY_LIB_LWIP_DIR}/core/dns.c
|
||||||
${MICROPY_LIB_LWIP_DIR}/core/inet_chksum.c
|
${MICROPY_LIB_LWIP_DIR}/core/inet_chksum.c
|
||||||
${MICROPY_LIB_LWIP_DIR}/core/init.c
|
${MICROPY_LIB_LWIP_DIR}/core/init.c
|
||||||
${MICROPY_LIB_LWIP_DIR}/core/ip.c
|
${MICROPY_LIB_LWIP_DIR}/core/ip.c
|
||||||
${MICROPY_LIB_LWIP_DIR}/core/ipv4/acd.c
|
|
||||||
${MICROPY_LIB_LWIP_DIR}/core/ipv4/autoip.c
|
${MICROPY_LIB_LWIP_DIR}/core/ipv4/autoip.c
|
||||||
${MICROPY_LIB_LWIP_DIR}/core/ipv4/dhcp.c
|
${MICROPY_LIB_LWIP_DIR}/core/ipv4/dhcp.c
|
||||||
${MICROPY_LIB_LWIP_DIR}/core/ipv4/etharp.c
|
${MICROPY_LIB_LWIP_DIR}/core/ipv4/etharp.c
|
||||||
@@ -314,32 +310,6 @@ if(MICROPY_PY_LWIP)
|
|||||||
${MICROPY_LIB_LWIP_DIR}/core/timeouts.c
|
${MICROPY_LIB_LWIP_DIR}/core/timeouts.c
|
||||||
${MICROPY_LIB_LWIP_DIR}/core/udp.c
|
${MICROPY_LIB_LWIP_DIR}/core/udp.c
|
||||||
${MICROPY_LIB_LWIP_DIR}/netif/ethernet.c
|
${MICROPY_LIB_LWIP_DIR}/netif/ethernet.c
|
||||||
${MICROPY_LIB_LWIP_DIR}/netif/ppp/auth.c
|
|
||||||
${MICROPY_LIB_LWIP_DIR}/netif/ppp/ccp.c
|
|
||||||
${MICROPY_LIB_LWIP_DIR}/netif/ppp/chap-md5.c
|
|
||||||
${MICROPY_LIB_LWIP_DIR}/netif/ppp/chap_ms.c
|
|
||||||
${MICROPY_LIB_LWIP_DIR}/netif/ppp/chap-new.c
|
|
||||||
${MICROPY_LIB_LWIP_DIR}/netif/ppp/demand.c
|
|
||||||
${MICROPY_LIB_LWIP_DIR}/netif/ppp/eap.c
|
|
||||||
${MICROPY_LIB_LWIP_DIR}/netif/ppp/ecp.c
|
|
||||||
${MICROPY_LIB_LWIP_DIR}/netif/ppp/eui64.c
|
|
||||||
${MICROPY_LIB_LWIP_DIR}/netif/ppp/fsm.c
|
|
||||||
${MICROPY_LIB_LWIP_DIR}/netif/ppp/ipcp.c
|
|
||||||
${MICROPY_LIB_LWIP_DIR}/netif/ppp/ipv6cp.c
|
|
||||||
${MICROPY_LIB_LWIP_DIR}/netif/ppp/lcp.c
|
|
||||||
${MICROPY_LIB_LWIP_DIR}/netif/ppp/magic.c
|
|
||||||
${MICROPY_LIB_LWIP_DIR}/netif/ppp/mppe.c
|
|
||||||
${MICROPY_LIB_LWIP_DIR}/netif/ppp/multilink.c
|
|
||||||
${MICROPY_LIB_LWIP_DIR}/netif/ppp/polarssl/md5.c
|
|
||||||
${MICROPY_LIB_LWIP_DIR}/netif/ppp/pppapi.c
|
|
||||||
${MICROPY_LIB_LWIP_DIR}/netif/ppp/ppp.c
|
|
||||||
${MICROPY_LIB_LWIP_DIR}/netif/ppp/pppcrypt.c
|
|
||||||
${MICROPY_LIB_LWIP_DIR}/netif/ppp/pppoe.c
|
|
||||||
${MICROPY_LIB_LWIP_DIR}/netif/ppp/pppol2tp.c
|
|
||||||
${MICROPY_LIB_LWIP_DIR}/netif/ppp/pppos.c
|
|
||||||
${MICROPY_LIB_LWIP_DIR}/netif/ppp/upap.c
|
|
||||||
${MICROPY_LIB_LWIP_DIR}/netif/ppp/utils.c
|
|
||||||
${MICROPY_LIB_LWIP_DIR}/netif/ppp/vj.c
|
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND MICROPY_INC_CORE
|
list(APPEND MICROPY_INC_CORE
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ SRC_EXTMOD_C += \
|
|||||||
extmod/modsocket.c \
|
extmod/modsocket.c \
|
||||||
extmod/modtls_axtls.c \
|
extmod/modtls_axtls.c \
|
||||||
extmod/modtls_mbedtls.c \
|
extmod/modtls_mbedtls.c \
|
||||||
extmod/mbedtls/mbedtls_alt.c \
|
|
||||||
extmod/modtime.c \
|
extmod/modtime.c \
|
||||||
extmod/moductypes.c \
|
extmod/moductypes.c \
|
||||||
extmod/modvfs.c \
|
extmod/modvfs.c \
|
||||||
@@ -52,7 +51,6 @@ SRC_EXTMOD_C += \
|
|||||||
extmod/network_esp_hosted.c \
|
extmod/network_esp_hosted.c \
|
||||||
extmod/network_lwip.c \
|
extmod/network_lwip.c \
|
||||||
extmod/network_ninaw10.c \
|
extmod/network_ninaw10.c \
|
||||||
extmod/network_ppp_lwip.c \
|
|
||||||
extmod/network_wiznet5k.c \
|
extmod/network_wiznet5k.c \
|
||||||
extmod/os_dupterm.c \
|
extmod/os_dupterm.c \
|
||||||
extmod/vfs.c \
|
extmod/vfs.c \
|
||||||
@@ -169,7 +167,6 @@ SRC_LIB_LIBM_DBL_SQRT_HW_C += lib/libm_dbl/thumb_vfp_sqrt.c
|
|||||||
|
|
||||||
# Too many warnings in libm_dbl, disable for now.
|
# Too many warnings in libm_dbl, disable for now.
|
||||||
$(BUILD)/lib/libm_dbl/%.o: CFLAGS += -Wno-double-promotion -Wno-float-conversion
|
$(BUILD)/lib/libm_dbl/%.o: CFLAGS += -Wno-double-promotion -Wno-float-conversion
|
||||||
$(BUILD)/lib/libm_dbl/__rem_pio2_large.o: CFLAGS += -Wno-maybe-uninitialized
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# VFS FAT FS
|
# VFS FAT FS
|
||||||
@@ -243,10 +240,6 @@ MBEDTLS_CONFIG_FILE ?= \"mbedtls/mbedtls_config_port.h\"
|
|||||||
GIT_SUBMODULES += $(MBEDTLS_DIR)
|
GIT_SUBMODULES += $(MBEDTLS_DIR)
|
||||||
CFLAGS_EXTMOD += -DMBEDTLS_CONFIG_FILE=$(MBEDTLS_CONFIG_FILE)
|
CFLAGS_EXTMOD += -DMBEDTLS_CONFIG_FILE=$(MBEDTLS_CONFIG_FILE)
|
||||||
CFLAGS_EXTMOD += -DMICROPY_SSL_MBEDTLS=1 -I$(TOP)/$(MBEDTLS_DIR)/include
|
CFLAGS_EXTMOD += -DMICROPY_SSL_MBEDTLS=1 -I$(TOP)/$(MBEDTLS_DIR)/include
|
||||||
ifeq ($(MICROPY_PY_SSL_ECDSA_SIGN_ALT),1)
|
|
||||||
CFLAGS_EXTMOD += -DMICROPY_PY_SSL_ECDSA_SIGN_ALT=1
|
|
||||||
LDFLAGS_EXTMOD += -Wl,--wrap=mbedtls_ecdsa_write_signature
|
|
||||||
endif
|
|
||||||
SRC_THIRDPARTY_C += lib/mbedtls_errors/mp_mbedtls_errors.c
|
SRC_THIRDPARTY_C += lib/mbedtls_errors/mp_mbedtls_errors.c
|
||||||
SRC_THIRDPARTY_C += $(addprefix $(MBEDTLS_DIR)/library/,\
|
SRC_THIRDPARTY_C += $(addprefix $(MBEDTLS_DIR)/library/,\
|
||||||
aes.c \
|
aes.c \
|
||||||
@@ -338,8 +331,6 @@ $(BUILD)/$(LWIP_DIR)/core/ipv4/dhcp.o: CFLAGS += -Wno-address
|
|||||||
SRC_THIRDPARTY_C += shared/netutils/netutils.c
|
SRC_THIRDPARTY_C += shared/netutils/netutils.c
|
||||||
SRC_THIRDPARTY_C += $(addprefix $(LWIP_DIR)/,\
|
SRC_THIRDPARTY_C += $(addprefix $(LWIP_DIR)/,\
|
||||||
apps/mdns/mdns.c \
|
apps/mdns/mdns.c \
|
||||||
apps/mdns/mdns_domain.c \
|
|
||||||
apps/mdns/mdns_out.c \
|
|
||||||
core/def.c \
|
core/def.c \
|
||||||
core/dns.c \
|
core/dns.c \
|
||||||
core/inet_chksum.c \
|
core/inet_chksum.c \
|
||||||
@@ -357,7 +348,6 @@ SRC_THIRDPARTY_C += $(addprefix $(LWIP_DIR)/,\
|
|||||||
core/tcp_out.c \
|
core/tcp_out.c \
|
||||||
core/timeouts.c \
|
core/timeouts.c \
|
||||||
core/udp.c \
|
core/udp.c \
|
||||||
core/ipv4/acd.c \
|
|
||||||
core/ipv4/autoip.c \
|
core/ipv4/autoip.c \
|
||||||
core/ipv4/dhcp.c \
|
core/ipv4/dhcp.c \
|
||||||
core/ipv4/etharp.c \
|
core/ipv4/etharp.c \
|
||||||
@@ -376,32 +366,6 @@ SRC_THIRDPARTY_C += $(addprefix $(LWIP_DIR)/,\
|
|||||||
core/ipv6/mld6.c \
|
core/ipv6/mld6.c \
|
||||||
core/ipv6/nd6.c \
|
core/ipv6/nd6.c \
|
||||||
netif/ethernet.c \
|
netif/ethernet.c \
|
||||||
netif/ppp/auth.c \
|
|
||||||
netif/ppp/ccp.c \
|
|
||||||
netif/ppp/chap-md5.c \
|
|
||||||
netif/ppp/chap_ms.c \
|
|
||||||
netif/ppp/chap-new.c \
|
|
||||||
netif/ppp/demand.c \
|
|
||||||
netif/ppp/eap.c \
|
|
||||||
netif/ppp/ecp.c \
|
|
||||||
netif/ppp/eui64.c \
|
|
||||||
netif/ppp/fsm.c \
|
|
||||||
netif/ppp/ipcp.c \
|
|
||||||
netif/ppp/ipv6cp.c \
|
|
||||||
netif/ppp/lcp.c \
|
|
||||||
netif/ppp/magic.c \
|
|
||||||
netif/ppp/mppe.c \
|
|
||||||
netif/ppp/multilink.c \
|
|
||||||
netif/ppp/polarssl/md5.c \
|
|
||||||
netif/ppp/pppapi.c \
|
|
||||||
netif/ppp/ppp.c \
|
|
||||||
netif/ppp/pppcrypt.c \
|
|
||||||
netif/ppp/pppoe.c \
|
|
||||||
netif/ppp/pppol2tp.c \
|
|
||||||
netif/ppp/pppos.c \
|
|
||||||
netif/ppp/upap.c \
|
|
||||||
netif/ppp/utils.c \
|
|
||||||
netif/ppp/vj.c \
|
|
||||||
)
|
)
|
||||||
ifeq ($(MICROPY_PY_LWIP_LOOPBACK),1)
|
ifeq ($(MICROPY_PY_LWIP_LOOPBACK),1)
|
||||||
CFLAGS_EXTMOD += -DLWIP_NETIF_LOOPBACK=1
|
CFLAGS_EXTMOD += -DLWIP_NETIF_LOOPBACK=1
|
||||||
@@ -562,7 +526,6 @@ ifeq ($(MICROPY_PY_OPENAMP),1)
|
|||||||
OPENAMP_DIR = lib/open-amp
|
OPENAMP_DIR = lib/open-amp
|
||||||
LIBMETAL_DIR = lib/libmetal
|
LIBMETAL_DIR = lib/libmetal
|
||||||
GIT_SUBMODULES += $(LIBMETAL_DIR) $(OPENAMP_DIR)
|
GIT_SUBMODULES += $(LIBMETAL_DIR) $(OPENAMP_DIR)
|
||||||
MICROPY_PY_OPENAMP_MODE ?= 0
|
|
||||||
include $(TOP)/extmod/libmetal/libmetal.mk
|
include $(TOP)/extmod/libmetal/libmetal.mk
|
||||||
|
|
||||||
INC += -I$(TOP)/$(OPENAMP_DIR)
|
INC += -I$(TOP)/$(OPENAMP_DIR)
|
||||||
@@ -572,21 +535,12 @@ ifeq ($(MICROPY_PY_OPENAMP_REMOTEPROC),1)
|
|||||||
CFLAGS += -DMICROPY_PY_OPENAMP_REMOTEPROC=1
|
CFLAGS += -DMICROPY_PY_OPENAMP_REMOTEPROC=1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(MICROPY_PY_OPENAMP_MODE),0)
|
|
||||||
CFLAGS += -DMICROPY_PY_OPENAMP_HOST=1
|
|
||||||
CFLAGS_THIRDPARTY += -DVIRTIO_DRIVER_ONLY
|
|
||||||
else ifeq ($(MICROPY_PY_OPENAMP_MODE),1)
|
|
||||||
CFLAGS += -DMICROPY_PY_OPENAMP_DEVICE=1
|
|
||||||
CFLAGS_THIRDPARTY += -DVIRTIO_DEVICE_ONLY
|
|
||||||
else
|
|
||||||
$(error Invalid Open-AMP mode specified: $(MICROPY_PY_OPENAMP_MODE))
|
|
||||||
endif
|
|
||||||
|
|
||||||
CFLAGS_THIRDPARTY += \
|
CFLAGS_THIRDPARTY += \
|
||||||
-I$(BUILD)/openamp \
|
-I$(BUILD)/openamp \
|
||||||
-I$(TOP)/$(OPENAMP_DIR) \
|
-I$(TOP)/$(OPENAMP_DIR) \
|
||||||
-I$(TOP)/$(OPENAMP_DIR)/lib/include/ \
|
-I$(TOP)/$(OPENAMP_DIR)/lib/include/ \
|
||||||
-DMETAL_INTERNAL \
|
-DMETAL_INTERNAL \
|
||||||
|
-DVIRTIO_DRIVER_ONLY \
|
||||||
-DNO_ATOMIC_64_SUPPORT \
|
-DNO_ATOMIC_64_SUPPORT \
|
||||||
-DRPMSG_BUFFER_SIZE=512 \
|
-DRPMSG_BUFFER_SIZE=512 \
|
||||||
|
|
||||||
|
|||||||
@@ -4,13 +4,13 @@
|
|||||||
# This replicates the basic functionality of the pre-processor, including adding a "micropython"
|
# This replicates the basic functionality of the pre-processor, including adding a "micropython"
|
||||||
# platform that is almost identical to the built-in "generic" platform with a few small changes
|
# platform that is almost identical to the built-in "generic" platform with a few small changes
|
||||||
# provided by the files in extmod/libmetal.
|
# provided by the files in extmod/libmetal.
|
||||||
$(BUILD)/openamp: | $(BUILD)
|
$(BUILD)/openamp: $(BUILD)
|
||||||
$(MKDIR) -p $@
|
$(MKDIR) -p $@
|
||||||
|
|
||||||
$(BUILD)/openamp/metal: | $(BUILD)/openamp
|
$(BUILD)/openamp/metal: $(BUILD)/openamp
|
||||||
$(MKDIR) -p $@
|
$(MKDIR) -p $@
|
||||||
|
|
||||||
$(BUILD)/openamp/metal/config.h: $(TOP)/$(LIBMETAL_DIR)/lib/config.h | $(BUILD)/openamp/metal
|
$(BUILD)/openamp/metal/config.h: $(BUILD)/openamp/metal $(TOP)/$(LIBMETAL_DIR)/lib/config.h
|
||||||
@$(ECHO) "GEN $@"
|
@$(ECHO) "GEN $@"
|
||||||
@for file in $(TOP)/$(LIBMETAL_DIR)/lib/*.c $(TOP)/$(LIBMETAL_DIR)/lib/*.h; do $(SED) -e "s/@PROJECT_SYSTEM@/micropython/g" -e "s/@PROJECT_PROCESSOR@/arm/g" $$file > $(BUILD)/openamp/metal/$$(basename $$file); done
|
@for file in $(TOP)/$(LIBMETAL_DIR)/lib/*.c $(TOP)/$(LIBMETAL_DIR)/lib/*.h; do $(SED) -e "s/@PROJECT_SYSTEM@/micropython/g" -e "s/@PROJECT_PROCESSOR@/arm/g" $$file > $(BUILD)/openamp/metal/$$(basename $$file); done
|
||||||
$(MKDIR) -p $(BUILD)/openamp/metal/processor/arm
|
$(MKDIR) -p $(BUILD)/openamp/metal/processor/arm
|
||||||
@@ -33,6 +33,7 @@ SRC_LIBMETAL_C := $(addprefix $(BUILD)/openamp/metal/,\
|
|||||||
shmem.c \
|
shmem.c \
|
||||||
softirq.c \
|
softirq.c \
|
||||||
version.c \
|
version.c \
|
||||||
|
device.c \
|
||||||
system/micropython/condition.c \
|
system/micropython/condition.c \
|
||||||
system/micropython/device.c \
|
system/micropython/device.c \
|
||||||
system/micropython/io.c \
|
system/micropython/io.c \
|
||||||
|
|||||||
@@ -33,6 +33,12 @@
|
|||||||
|
|
||||||
#include "extmod/modmachine.h"
|
#include "extmod/modmachine.h"
|
||||||
|
|
||||||
|
// if a port didn't define MSB/LSB constants then provide them
|
||||||
|
#ifndef MICROPY_PY_MACHINE_SPI_MSB
|
||||||
|
#define MICROPY_PY_MACHINE_SPI_MSB (0)
|
||||||
|
#define MICROPY_PY_MACHINE_SPI_LSB (1)
|
||||||
|
#endif
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
// MicroPython bindings for generic machine.SPI
|
// MicroPython bindings for generic machine.SPI
|
||||||
|
|
||||||
@@ -148,9 +154,9 @@ static uint32_t baudrate_to_delay_half(uint32_t baudrate) {
|
|||||||
|
|
||||||
static void mp_machine_soft_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
static void mp_machine_soft_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||||
mp_machine_soft_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_machine_soft_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
mp_printf(print, "SoftSPI(baudrate=%u, polarity=%u, phase=%u, firstbit=%u,"
|
mp_printf(print, "SoftSPI(baudrate=%u, polarity=%u, phase=%u,"
|
||||||
" sck=" MP_HAL_PIN_FMT ", mosi=" MP_HAL_PIN_FMT ", miso=" MP_HAL_PIN_FMT ")",
|
" sck=" MP_HAL_PIN_FMT ", mosi=" MP_HAL_PIN_FMT ", miso=" MP_HAL_PIN_FMT ")",
|
||||||
baudrate_from_delay_half(self->spi.delay_half), self->spi.polarity, self->spi.phase, self->spi.firstbit,
|
baudrate_from_delay_half(self->spi.delay_half), self->spi.polarity, self->spi.phase,
|
||||||
mp_hal_pin_name(self->spi.sck), mp_hal_pin_name(self->spi.mosi), mp_hal_pin_name(self->spi.miso));
|
mp_hal_pin_name(self->spi.sck), mp_hal_pin_name(self->spi.mosi), mp_hal_pin_name(self->spi.miso));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +185,9 @@ static mp_obj_t mp_machine_soft_spi_make_new(const mp_obj_type_t *type, size_t n
|
|||||||
if (args[ARG_bits].u_int != 8) {
|
if (args[ARG_bits].u_int != 8) {
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("bits must be 8"));
|
mp_raise_ValueError(MP_ERROR_TEXT("bits must be 8"));
|
||||||
}
|
}
|
||||||
self->spi.firstbit = args[ARG_firstbit].u_int;
|
if (args[ARG_firstbit].u_int != MICROPY_PY_MACHINE_SPI_MSB) {
|
||||||
|
mp_raise_ValueError(MP_ERROR_TEXT("firstbit must be MSB"));
|
||||||
|
}
|
||||||
if (args[ARG_sck].u_obj == MP_OBJ_NULL
|
if (args[ARG_sck].u_obj == MP_OBJ_NULL
|
||||||
|| args[ARG_mosi].u_obj == MP_OBJ_NULL
|
|| args[ARG_mosi].u_obj == MP_OBJ_NULL
|
||||||
|| args[ARG_miso].u_obj == MP_OBJ_NULL) {
|
|| args[ARG_miso].u_obj == MP_OBJ_NULL) {
|
||||||
@@ -198,12 +206,11 @@ static mp_obj_t mp_machine_soft_spi_make_new(const mp_obj_type_t *type, size_t n
|
|||||||
static void mp_machine_soft_spi_init(mp_obj_base_t *self_in, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
static void mp_machine_soft_spi_init(mp_obj_base_t *self_in, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||||
mp_machine_soft_spi_obj_t *self = (mp_machine_soft_spi_obj_t *)self_in;
|
mp_machine_soft_spi_obj_t *self = (mp_machine_soft_spi_obj_t *)self_in;
|
||||||
|
|
||||||
enum { ARG_baudrate, ARG_polarity, ARG_phase, ARG_firstbit, ARG_sck, ARG_mosi, ARG_miso };
|
enum { ARG_baudrate, ARG_polarity, ARG_phase, ARG_sck, ARG_mosi, ARG_miso };
|
||||||
static const mp_arg_t allowed_args[] = {
|
static const mp_arg_t allowed_args[] = {
|
||||||
{ MP_QSTR_baudrate, MP_ARG_INT, {.u_int = -1} },
|
{ MP_QSTR_baudrate, MP_ARG_INT, {.u_int = -1} },
|
||||||
{ MP_QSTR_polarity, MP_ARG_INT, {.u_int = -1} },
|
{ MP_QSTR_polarity, MP_ARG_INT, {.u_int = -1} },
|
||||||
{ MP_QSTR_phase, MP_ARG_INT, {.u_int = -1} },
|
{ MP_QSTR_phase, MP_ARG_INT, {.u_int = -1} },
|
||||||
{ MP_QSTR_firstbit, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
|
|
||||||
{ MP_QSTR_sck, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
{ MP_QSTR_sck, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||||
{ MP_QSTR_mosi, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
{ MP_QSTR_mosi, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||||
{ MP_QSTR_miso, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
{ MP_QSTR_miso, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||||
@@ -220,9 +227,6 @@ static void mp_machine_soft_spi_init(mp_obj_base_t *self_in, size_t n_args, cons
|
|||||||
if (args[ARG_phase].u_int != -1) {
|
if (args[ARG_phase].u_int != -1) {
|
||||||
self->spi.phase = args[ARG_phase].u_int;
|
self->spi.phase = args[ARG_phase].u_int;
|
||||||
}
|
}
|
||||||
if (args[ARG_firstbit].u_int != -1) {
|
|
||||||
self->spi.firstbit = args[ARG_firstbit].u_int;
|
|
||||||
}
|
|
||||||
if (args[ARG_sck].u_obj != MP_OBJ_NULL) {
|
if (args[ARG_sck].u_obj != MP_OBJ_NULL) {
|
||||||
self->spi.sck = mp_hal_get_pin_obj(args[ARG_sck].u_obj);
|
self->spi.sck = mp_hal_get_pin_obj(args[ARG_sck].u_obj);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,11 +157,6 @@ static mp_obj_t usb_device_active(size_t n_args, const mp_obj_t *args) {
|
|||||||
}
|
}
|
||||||
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(usb_device_active_obj, 1, 2, usb_device_active);
|
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(usb_device_active_obj, 1, 2, usb_device_active);
|
||||||
|
|
||||||
static mp_obj_t usb_remote_wakeup(mp_obj_t self) {
|
|
||||||
return mp_obj_new_bool(tud_remote_wakeup());
|
|
||||||
}
|
|
||||||
static MP_DEFINE_CONST_FUN_OBJ_1(usb_remote_wakeup_obj, usb_remote_wakeup);
|
|
||||||
|
|
||||||
static mp_obj_t usb_device_stall(size_t n_args, const mp_obj_t *args) {
|
static mp_obj_t usb_device_stall(size_t n_args, const mp_obj_t *args) {
|
||||||
mp_obj_usb_device_t *self = (mp_obj_usb_device_t *)MP_OBJ_TO_PTR(args[0]);
|
mp_obj_usb_device_t *self = (mp_obj_usb_device_t *)MP_OBJ_TO_PTR(args[0]);
|
||||||
int epnum = mp_obj_get_int(args[1]);
|
int epnum = mp_obj_get_int(args[1]);
|
||||||
@@ -277,7 +272,6 @@ static const mp_rom_map_elem_t usb_device_locals_dict_table[] = {
|
|||||||
{ MP_ROM_QSTR(MP_QSTR_submit_xfer), MP_ROM_PTR(&usb_device_submit_xfer_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_submit_xfer), MP_ROM_PTR(&usb_device_submit_xfer_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_active), MP_ROM_PTR(&usb_device_active_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_active), MP_ROM_PTR(&usb_device_active_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_stall), MP_ROM_PTR(&usb_device_stall_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_stall), MP_ROM_PTR(&usb_device_stall_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_remote_wakeup), MP_ROM_PTR(&usb_remote_wakeup_obj) },
|
|
||||||
|
|
||||||
// Built-in driver constants
|
// Built-in driver constants
|
||||||
{ MP_ROM_QSTR(MP_QSTR_BUILTIN_NONE), MP_ROM_PTR(&mp_type_usb_device_builtin_none) },
|
{ MP_ROM_QSTR(MP_QSTR_BUILTIN_NONE), MP_ROM_PTR(&mp_type_usb_device_builtin_none) },
|
||||||
|
|||||||
@@ -1,88 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*
|
|
||||||
* Copyright The Mbed TLS Contributors
|
|
||||||
* Copyright (c) 2024 Damien P. George
|
|
||||||
*
|
|
||||||
* This file provides default fallback functions for use with alternate
|
|
||||||
* cryptography functions implemented in Python.
|
|
||||||
*/
|
|
||||||
#if MICROPY_PY_SSL_ECDSA_SIGN_ALT
|
|
||||||
#if defined(MBEDTLS_ECP_RESTARTABLE) || defined(MBEDTLS_ECDSA_DETERMINISTIC)
|
|
||||||
#error "MICROPY_PY_SSL_ECDSA_SIGN_ALT cannot be used with MBEDTLS_ECP_RESTARTABLE or MBEDTLS_ECDSA_DETERMINISTIC"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#define MBEDTLS_ALLOW_PRIVATE_ACCESS
|
|
||||||
#include "mbedtls/platform.h"
|
|
||||||
#include "mbedtls/ssl.h"
|
|
||||||
#include "mbedtls/error.h"
|
|
||||||
#include "mbedtls/ecdsa.h"
|
|
||||||
#include "mbedtls/asn1write.h"
|
|
||||||
|
|
||||||
extern int micropy_mbedtls_ecdsa_sign_alt(const mbedtls_mpi *d, const unsigned char *hash, size_t hlen,
|
|
||||||
unsigned char *sig, size_t sig_size, size_t *slen);
|
|
||||||
|
|
||||||
|
|
||||||
// Compute and write signature
|
|
||||||
// See lib/mbedtls/library/ecdsa.c:688
|
|
||||||
//
|
|
||||||
// Note: To avoid duplicating a lot of code, MBEDTLS_ECDSA_SIGN_ALT is not defined,
|
|
||||||
// which allows the default mbedtls_ecdsa_sign to be used as a fallback function.
|
|
||||||
// However, mbedtls_ecdsa_sign cannot be wrapped because it is called internally
|
|
||||||
// within its object file, so we wrap mbedtls_ecdsa_read/write_signature instead.
|
|
||||||
int __wrap_mbedtls_ecdsa_write_signature(mbedtls_ecdsa_context *ctx,
|
|
||||||
mbedtls_md_type_t md_alg,
|
|
||||||
const unsigned char *hash, size_t hlen,
|
|
||||||
unsigned char *sig, size_t sig_size, size_t *slen,
|
|
||||||
int (*f_rng)(void *, unsigned char *, size_t),
|
|
||||||
void *p_rng) {
|
|
||||||
|
|
||||||
(void)md_alg;
|
|
||||||
|
|
||||||
if (f_rng == NULL) {
|
|
||||||
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if curve is supported for ECDSA.
|
|
||||||
if (!mbedtls_ecdsa_can_do(ctx->grp.id) || ctx->grp.N.p == NULL) {
|
|
||||||
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try signing with the alternative function first.
|
|
||||||
int ret = micropy_mbedtls_ecdsa_sign_alt(&ctx->d, hash, hlen, sig, sig_size, slen);
|
|
||||||
|
|
||||||
// Fallback to the default mbedtls implementation if needed.
|
|
||||||
if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED) {
|
|
||||||
mbedtls_mpi r, s;
|
|
||||||
mbedtls_mpi_init(&r);
|
|
||||||
mbedtls_mpi_init(&s);
|
|
||||||
|
|
||||||
size_t len = 0;
|
|
||||||
unsigned char buf[MBEDTLS_ECDSA_MAX_LEN] = { 0 };
|
|
||||||
unsigned char *p = buf + sizeof(buf);
|
|
||||||
|
|
||||||
MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign(&ctx->grp, &r, &s, &ctx->d, hash, hlen, f_rng, p_rng));
|
|
||||||
MBEDTLS_ASN1_CHK_CLEANUP_ADD(len, mbedtls_asn1_write_mpi(&p, buf, &s));
|
|
||||||
MBEDTLS_ASN1_CHK_CLEANUP_ADD(len, mbedtls_asn1_write_mpi(&p, buf, &r));
|
|
||||||
MBEDTLS_ASN1_CHK_CLEANUP_ADD(len, mbedtls_asn1_write_len(&p, buf, len));
|
|
||||||
MBEDTLS_ASN1_CHK_CLEANUP_ADD(len, mbedtls_asn1_write_tag(&p, buf, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
|
|
||||||
|
|
||||||
if (len > sig_size) {
|
|
||||||
ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
|
|
||||||
} else {
|
|
||||||
ret = 0;
|
|
||||||
*slen = len;
|
|
||||||
memcpy(sig, p, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
mbedtls_mpi_free(&r);
|
|
||||||
mbedtls_mpi_free(&s);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -46,7 +46,6 @@
|
|||||||
#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
|
#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
|
||||||
#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
|
#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
|
||||||
#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||||
#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
|
|
||||||
#define MBEDTLS_CAN_ECDH
|
#define MBEDTLS_CAN_ECDH
|
||||||
#define MBEDTLS_PK_CAN_ECDSA_SIGN
|
#define MBEDTLS_PK_CAN_ECDSA_SIGN
|
||||||
#define MBEDTLS_PKCS1_V15
|
#define MBEDTLS_PKCS1_V15
|
||||||
@@ -73,7 +72,6 @@
|
|||||||
#define MBEDTLS_ECP_C
|
#define MBEDTLS_ECP_C
|
||||||
#define MBEDTLS_ENTROPY_C
|
#define MBEDTLS_ENTROPY_C
|
||||||
#define MBEDTLS_ERROR_C
|
#define MBEDTLS_ERROR_C
|
||||||
#define MBEDTLS_GCM_C
|
|
||||||
#define MBEDTLS_MD_C
|
#define MBEDTLS_MD_C
|
||||||
#define MBEDTLS_MD5_C
|
#define MBEDTLS_MD5_C
|
||||||
#define MBEDTLS_OID_C
|
#define MBEDTLS_OID_C
|
||||||
|
|||||||
@@ -53,9 +53,6 @@ typedef struct _mp_obj_task_t {
|
|||||||
typedef struct _mp_obj_task_queue_t {
|
typedef struct _mp_obj_task_queue_t {
|
||||||
mp_obj_base_t base;
|
mp_obj_base_t base;
|
||||||
mp_obj_task_t *heap;
|
mp_obj_task_t *heap;
|
||||||
#if MICROPY_PY_ASYNCIO_TASK_QUEUE_PUSH_CALLBACK
|
|
||||||
mp_obj_t push_callback;
|
|
||||||
#endif
|
|
||||||
} mp_obj_task_queue_t;
|
} mp_obj_task_queue_t;
|
||||||
|
|
||||||
static const mp_obj_type_t task_queue_type;
|
static const mp_obj_type_t task_queue_type;
|
||||||
@@ -89,16 +86,9 @@ static int task_lt(mp_pairheap_t *n1, mp_pairheap_t *n2) {
|
|||||||
|
|
||||||
static mp_obj_t task_queue_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
static mp_obj_t task_queue_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||||
(void)args;
|
(void)args;
|
||||||
mp_arg_check_num(n_args, n_kw, 0, MICROPY_PY_ASYNCIO_TASK_QUEUE_PUSH_CALLBACK ? 1 : 0, false);
|
mp_arg_check_num(n_args, n_kw, 0, 0, false);
|
||||||
mp_obj_task_queue_t *self = mp_obj_malloc(mp_obj_task_queue_t, type);
|
mp_obj_task_queue_t *self = mp_obj_malloc(mp_obj_task_queue_t, type);
|
||||||
self->heap = (mp_obj_task_t *)mp_pairheap_new(task_lt);
|
self->heap = (mp_obj_task_t *)mp_pairheap_new(task_lt);
|
||||||
#if MICROPY_PY_ASYNCIO_TASK_QUEUE_PUSH_CALLBACK
|
|
||||||
if (n_args == 1) {
|
|
||||||
self->push_callback = args[0];
|
|
||||||
} else {
|
|
||||||
self->push_callback = MP_OBJ_NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return MP_OBJ_FROM_PTR(self);
|
return MP_OBJ_FROM_PTR(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,11 +113,6 @@ static mp_obj_t task_queue_push(size_t n_args, const mp_obj_t *args) {
|
|||||||
task->ph_key = args[2];
|
task->ph_key = args[2];
|
||||||
}
|
}
|
||||||
self->heap = (mp_obj_task_t *)mp_pairheap_push(task_lt, TASK_PAIRHEAP(self->heap), TASK_PAIRHEAP(task));
|
self->heap = (mp_obj_task_t *)mp_pairheap_push(task_lt, TASK_PAIRHEAP(self->heap), TASK_PAIRHEAP(task));
|
||||||
#if MICROPY_PY_ASYNCIO_TASK_QUEUE_PUSH_CALLBACK
|
|
||||||
if (self->push_callback != MP_OBJ_NULL) {
|
|
||||||
mp_call_function_1(self->push_callback, MP_OBJ_NEW_SMALL_INT(0));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(task_queue_push_obj, 2, 3, task_queue_push);
|
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(task_queue_push_obj, 2, 3, task_queue_push);
|
||||||
|
|||||||
@@ -89,12 +89,6 @@ void __dbpanic(DB *db) {
|
|||||||
mp_printf(&mp_plat_print, "__dbpanic(%p)\n", db);
|
mp_printf(&mp_plat_print, "__dbpanic(%p)\n", db);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void check_btree_is_open(mp_obj_btree_t *self) {
|
|
||||||
if (!self->db) {
|
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("database closed"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static mp_obj_btree_t *btree_new(DB *db, mp_obj_t stream) {
|
static mp_obj_btree_t *btree_new(DB *db, mp_obj_t stream) {
|
||||||
mp_obj_btree_t *o = mp_obj_malloc(mp_obj_btree_t, (mp_obj_type_t *)&btree_type);
|
mp_obj_btree_t *o = mp_obj_malloc(mp_obj_btree_t, (mp_obj_type_t *)&btree_type);
|
||||||
o->stream = stream;
|
o->stream = stream;
|
||||||
@@ -120,28 +114,19 @@ static void btree_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind
|
|||||||
|
|
||||||
static mp_obj_t btree_flush(mp_obj_t self_in) {
|
static mp_obj_t btree_flush(mp_obj_t self_in) {
|
||||||
mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
check_btree_is_open(self);
|
|
||||||
return MP_OBJ_NEW_SMALL_INT(__bt_sync(self->db, 0));
|
return MP_OBJ_NEW_SMALL_INT(__bt_sync(self->db, 0));
|
||||||
}
|
}
|
||||||
static MP_DEFINE_CONST_FUN_OBJ_1(btree_flush_obj, btree_flush);
|
static MP_DEFINE_CONST_FUN_OBJ_1(btree_flush_obj, btree_flush);
|
||||||
|
|
||||||
static mp_obj_t btree_close(mp_obj_t self_in) {
|
static mp_obj_t btree_close(mp_obj_t self_in) {
|
||||||
mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
int res;
|
return MP_OBJ_NEW_SMALL_INT(__bt_close(self->db));
|
||||||
if (self->db) {
|
|
||||||
res = __bt_close(self->db);
|
|
||||||
self->db = NULL;
|
|
||||||
} else {
|
|
||||||
res = RET_SUCCESS; // Closing an already-closed DB always succeeds.
|
|
||||||
}
|
|
||||||
return MP_OBJ_NEW_SMALL_INT(res);
|
|
||||||
}
|
}
|
||||||
static MP_DEFINE_CONST_FUN_OBJ_1(btree_close_obj, btree_close);
|
static MP_DEFINE_CONST_FUN_OBJ_1(btree_close_obj, btree_close);
|
||||||
|
|
||||||
static mp_obj_t btree_put(size_t n_args, const mp_obj_t *args) {
|
static mp_obj_t btree_put(size_t n_args, const mp_obj_t *args) {
|
||||||
(void)n_args;
|
(void)n_args;
|
||||||
mp_obj_btree_t *self = MP_OBJ_TO_PTR(args[0]);
|
mp_obj_btree_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||||
check_btree_is_open(self);
|
|
||||||
DBT key, val;
|
DBT key, val;
|
||||||
buf_to_dbt(args[1], &key);
|
buf_to_dbt(args[1], &key);
|
||||||
buf_to_dbt(args[2], &val);
|
buf_to_dbt(args[2], &val);
|
||||||
@@ -151,7 +136,6 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_put_obj, 3, 4, btree_put);
|
|||||||
|
|
||||||
static mp_obj_t btree_get(size_t n_args, const mp_obj_t *args) {
|
static mp_obj_t btree_get(size_t n_args, const mp_obj_t *args) {
|
||||||
mp_obj_btree_t *self = MP_OBJ_TO_PTR(args[0]);
|
mp_obj_btree_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||||
check_btree_is_open(self);
|
|
||||||
DBT key, val;
|
DBT key, val;
|
||||||
buf_to_dbt(args[1], &key);
|
buf_to_dbt(args[1], &key);
|
||||||
int res = __bt_get(self->db, &key, &val, 0);
|
int res = __bt_get(self->db, &key, &val, 0);
|
||||||
@@ -169,7 +153,6 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_get_obj, 2, 3, btree_get);
|
|||||||
|
|
||||||
static mp_obj_t btree_seq(size_t n_args, const mp_obj_t *args) {
|
static mp_obj_t btree_seq(size_t n_args, const mp_obj_t *args) {
|
||||||
mp_obj_btree_t *self = MP_OBJ_TO_PTR(args[0]);
|
mp_obj_btree_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||||
check_btree_is_open(self);
|
|
||||||
int flags = MP_OBJ_SMALL_INT_VALUE(args[1]);
|
int flags = MP_OBJ_SMALL_INT_VALUE(args[1]);
|
||||||
DBT key, val;
|
DBT key, val;
|
||||||
if (n_args > 2) {
|
if (n_args > 2) {
|
||||||
@@ -242,7 +225,6 @@ static mp_obj_t btree_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) {
|
|||||||
|
|
||||||
static mp_obj_t btree_iternext(mp_obj_t self_in) {
|
static mp_obj_t btree_iternext(mp_obj_t self_in) {
|
||||||
mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
check_btree_is_open(self);
|
|
||||||
DBT key, val;
|
DBT key, val;
|
||||||
int res;
|
int res;
|
||||||
bool desc = self->flags & FLAG_DESC;
|
bool desc = self->flags & FLAG_DESC;
|
||||||
@@ -299,7 +281,6 @@ static mp_obj_t btree_iternext(mp_obj_t self_in) {
|
|||||||
|
|
||||||
static mp_obj_t btree_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
|
static mp_obj_t btree_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
|
||||||
mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
check_btree_is_open(self);
|
|
||||||
if (value == MP_OBJ_NULL) {
|
if (value == MP_OBJ_NULL) {
|
||||||
// delete
|
// delete
|
||||||
DBT key;
|
DBT key;
|
||||||
@@ -333,7 +314,6 @@ static mp_obj_t btree_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
|
|||||||
|
|
||||||
static mp_obj_t btree_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
static mp_obj_t btree_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||||
mp_obj_btree_t *self = MP_OBJ_TO_PTR(lhs_in);
|
mp_obj_btree_t *self = MP_OBJ_TO_PTR(lhs_in);
|
||||||
check_btree_is_open(self);
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case MP_BINARY_OP_CONTAINS: {
|
case MP_BINARY_OP_CONTAINS: {
|
||||||
DBT key, val;
|
DBT key, val;
|
||||||
|
|||||||
@@ -282,29 +282,23 @@ static mp_obj_t framebuf_make_new(const mp_obj_type_t *type, size_t n_args, size
|
|||||||
mp_raise_ValueError(NULL);
|
mp_raise_ValueError(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t bpp = 1;
|
|
||||||
size_t height_required = height;
|
size_t height_required = height;
|
||||||
size_t width_required = width;
|
size_t bpp = 1;
|
||||||
size_t strides_required = height - 1;
|
|
||||||
|
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case FRAMEBUF_MVLSB:
|
case FRAMEBUF_MVLSB:
|
||||||
height_required = (height + 7) & ~7;
|
height_required = (height + 7) & ~7;
|
||||||
strides_required = height_required - 8;
|
|
||||||
break;
|
break;
|
||||||
case FRAMEBUF_MHLSB:
|
case FRAMEBUF_MHLSB:
|
||||||
case FRAMEBUF_MHMSB:
|
case FRAMEBUF_MHMSB:
|
||||||
stride = (stride + 7) & ~7;
|
stride = (stride + 7) & ~7;
|
||||||
width_required = (width + 7) & ~7;
|
|
||||||
break;
|
break;
|
||||||
case FRAMEBUF_GS2_HMSB:
|
case FRAMEBUF_GS2_HMSB:
|
||||||
stride = (stride + 3) & ~3;
|
stride = (stride + 3) & ~3;
|
||||||
width_required = (width + 3) & ~3;
|
|
||||||
bpp = 2;
|
bpp = 2;
|
||||||
break;
|
break;
|
||||||
case FRAMEBUF_GS4_HMSB:
|
case FRAMEBUF_GS4_HMSB:
|
||||||
stride = (stride + 1) & ~1;
|
stride = (stride + 1) & ~1;
|
||||||
width_required = (width + 1) & ~1;
|
|
||||||
bpp = 4;
|
bpp = 4;
|
||||||
break;
|
break;
|
||||||
case FRAMEBUF_GS8:
|
case FRAMEBUF_GS8:
|
||||||
@@ -320,7 +314,7 @@ static mp_obj_t framebuf_make_new(const mp_obj_type_t *type, size_t n_args, size
|
|||||||
mp_buffer_info_t bufinfo;
|
mp_buffer_info_t bufinfo;
|
||||||
mp_get_buffer_raise(args_in[0], &bufinfo, MP_BUFFER_WRITE);
|
mp_get_buffer_raise(args_in[0], &bufinfo, MP_BUFFER_WRITE);
|
||||||
|
|
||||||
if ((strides_required * stride + (height_required - strides_required) * width_required) * bpp / 8 > bufinfo.len) {
|
if (height_required * stride * bpp / 8 > bufinfo.len) {
|
||||||
mp_raise_ValueError(NULL);
|
mp_raise_ValueError(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -536,10 +530,6 @@ static mp_obj_t framebuf_ellipse(size_t n_args, const mp_obj_t *args_in) {
|
|||||||
} else {
|
} else {
|
||||||
mask |= ELLIPSE_MASK_ALL;
|
mask |= ELLIPSE_MASK_ALL;
|
||||||
}
|
}
|
||||||
if (args[2] == 0 && args[3] == 0) {
|
|
||||||
setpixel_checked(self, args[0], args[1], args[4], mask & ELLIPSE_MASK_ALL);
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
mp_int_t two_asquare = 2 * args[2] * args[2];
|
mp_int_t two_asquare = 2 * args[2] * args[2];
|
||||||
mp_int_t two_bsquare = 2 * args[3] * args[3];
|
mp_int_t two_bsquare = 2 * args[3] * args[3];
|
||||||
mp_int_t x = args[2];
|
mp_int_t x = args[2];
|
||||||
|
|||||||
@@ -127,15 +127,15 @@ sio_fd_t sio_open(u8_t dvnum) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sio_send(u8_t c, sio_fd_t fd) {
|
void sio_send(u8_t c, sio_fd_t fd) {
|
||||||
const mp_stream_p_t *stream_p = mp_get_stream(MP_STATE_VM(lwip_slip_stream));
|
mp_obj_type_t *type = mp_obj_get_type(MP_STATE_VM(lwip_slip_stream));
|
||||||
int error;
|
int error;
|
||||||
stream_p->write(MP_STATE_VM(lwip_slip_stream), &c, 1, &error);
|
type->stream_p->write(MP_STATE_VM(lwip_slip_stream), &c, 1, &error);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32_t sio_tryread(sio_fd_t fd, u8_t *data, u32_t len) {
|
u32_t sio_tryread(sio_fd_t fd, u8_t *data, u32_t len) {
|
||||||
const mp_stream_p_t *stream_p = mp_get_stream(MP_STATE_VM(lwip_slip_stream));
|
mp_obj_type_t *type = mp_obj_get_type(MP_STATE_VM(lwip_slip_stream));
|
||||||
int error;
|
int error;
|
||||||
mp_uint_t out_sz = stream_p->read(MP_STATE_VM(lwip_slip_stream), data, len, &error);
|
mp_uint_t out_sz = type->stream_p->read(MP_STATE_VM(lwip_slip_stream), data, len, &error);
|
||||||
if (out_sz == MP_STREAM_ERROR) {
|
if (out_sz == MP_STREAM_ERROR) {
|
||||||
if (mp_is_nonblocking_error(error)) {
|
if (mp_is_nonblocking_error(error)) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -326,10 +326,6 @@ typedef struct _lwip_socket_obj_t {
|
|||||||
int8_t state;
|
int8_t state;
|
||||||
} lwip_socket_obj_t;
|
} lwip_socket_obj_t;
|
||||||
|
|
||||||
static inline bool socket_is_timedout(lwip_socket_obj_t *socket, mp_uint_t ticks_start) {
|
|
||||||
return socket->timeout != -1 && (mp_uint_t)(mp_hal_ticks_ms() - ticks_start) >= socket->timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void poll_sockets(void) {
|
static inline void poll_sockets(void) {
|
||||||
mp_event_wait_ms(1);
|
mp_event_wait_ms(1);
|
||||||
}
|
}
|
||||||
@@ -373,7 +369,7 @@ mp_obj_t lwip_format_inet_addr(const ip_addr_t *ip, mp_uint_t port) {
|
|||||||
char ipstr[IPADDR_STRLEN_MAX];
|
char ipstr[IPADDR_STRLEN_MAX];
|
||||||
ipaddr_ntoa_r(ip, ipstr, sizeof(ipstr));
|
ipaddr_ntoa_r(ip, ipstr, sizeof(ipstr));
|
||||||
mp_obj_t tuple[2] = {
|
mp_obj_t tuple[2] = {
|
||||||
tuple[0] = mp_obj_new_str_from_cstr(ipstr),
|
tuple[0] = mp_obj_new_str(ipstr, strlen(ipstr)),
|
||||||
tuple[1] = mp_obj_new_int(port),
|
tuple[1] = mp_obj_new_int(port),
|
||||||
};
|
};
|
||||||
return mp_obj_new_tuple(2, tuple);
|
return mp_obj_new_tuple(2, tuple);
|
||||||
@@ -1040,22 +1036,26 @@ static mp_obj_t lwip_socket_accept(mp_obj_t self_in) {
|
|||||||
// accept incoming connection
|
// accept incoming connection
|
||||||
struct tcp_pcb *volatile *incoming_connection = &lwip_socket_incoming_array(socket)[socket->incoming.connection.iget];
|
struct tcp_pcb *volatile *incoming_connection = &lwip_socket_incoming_array(socket)[socket->incoming.connection.iget];
|
||||||
if (*incoming_connection == NULL) {
|
if (*incoming_connection == NULL) {
|
||||||
mp_uint_t ticks_start = mp_hal_ticks_ms();
|
if (socket->timeout == 0) {
|
||||||
for (;;) {
|
|
||||||
MICROPY_PY_LWIP_EXIT
|
MICROPY_PY_LWIP_EXIT
|
||||||
poll_sockets();
|
m_del_obj(lwip_socket_obj_t, socket2);
|
||||||
MICROPY_PY_LWIP_REENTER
|
mp_raise_OSError(MP_EAGAIN);
|
||||||
if (*incoming_connection != NULL) {
|
} else if (socket->timeout != -1) {
|
||||||
break;
|
mp_uint_t retries = socket->timeout / 100;
|
||||||
}
|
while (*incoming_connection == NULL) {
|
||||||
if (socket_is_timedout(socket, ticks_start)) {
|
|
||||||
MICROPY_PY_LWIP_EXIT
|
MICROPY_PY_LWIP_EXIT
|
||||||
m_del_obj(lwip_socket_obj_t, socket2);
|
if (retries-- == 0) {
|
||||||
if (socket->timeout == 0) {
|
m_del_obj(lwip_socket_obj_t, socket2);
|
||||||
mp_raise_OSError(MP_EAGAIN);
|
|
||||||
} else {
|
|
||||||
mp_raise_OSError(MP_ETIMEDOUT);
|
mp_raise_OSError(MP_ETIMEDOUT);
|
||||||
}
|
}
|
||||||
|
mp_hal_delay_ms(100);
|
||||||
|
MICROPY_PY_LWIP_REENTER
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while (*incoming_connection == NULL) {
|
||||||
|
MICROPY_PY_LWIP_EXIT
|
||||||
|
poll_sockets();
|
||||||
|
MICROPY_PY_LWIP_REENTER
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1130,21 +1130,21 @@ static mp_obj_t lwip_socket_connect(mp_obj_t self_in, mp_obj_t addr_in) {
|
|||||||
MICROPY_PY_LWIP_EXIT
|
MICROPY_PY_LWIP_EXIT
|
||||||
|
|
||||||
// And now we wait...
|
// And now we wait...
|
||||||
mp_uint_t ticks_start = mp_hal_ticks_ms();
|
if (socket->timeout != -1) {
|
||||||
for (;;) {
|
for (mp_uint_t retries = socket->timeout / 100; retries--;) {
|
||||||
poll_sockets();
|
mp_hal_delay_ms(100);
|
||||||
if (socket->state != STATE_CONNECTING) {
|
if (socket->state != STATE_CONNECTING) {
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
if (socket_is_timedout(socket, ticks_start)) {
|
|
||||||
if (socket->timeout == 0) {
|
|
||||||
mp_raise_OSError(MP_EINPROGRESS);
|
|
||||||
} else {
|
|
||||||
mp_raise_OSError(MP_ETIMEDOUT);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (socket->state == STATE_CONNECTING) {
|
||||||
|
mp_raise_OSError(MP_EINPROGRESS);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while (socket->state == STATE_CONNECTING) {
|
||||||
|
poll_sockets();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (socket->state == STATE_CONNECTED) {
|
if (socket->state == STATE_CONNECTED) {
|
||||||
err = ERR_OK;
|
err = ERR_OK;
|
||||||
} else {
|
} else {
|
||||||
@@ -1432,7 +1432,7 @@ static mp_obj_t lwip_socket_setsockopt(size_t n_args, const mp_obj_t *args) {
|
|||||||
case IP_DROP_MEMBERSHIP: {
|
case IP_DROP_MEMBERSHIP: {
|
||||||
mp_buffer_info_t bufinfo;
|
mp_buffer_info_t bufinfo;
|
||||||
mp_get_buffer_raise(args[3], &bufinfo, MP_BUFFER_READ);
|
mp_get_buffer_raise(args[3], &bufinfo, MP_BUFFER_READ);
|
||||||
if (bufinfo.len != sizeof(MP_IGMP_IP_ADDR_TYPE) * 2) {
|
if (bufinfo.len != sizeof(ip_addr_t) * 2) {
|
||||||
mp_raise_ValueError(NULL);
|
mp_raise_ValueError(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "py/builtin.h"
|
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
|
|
||||||
#if MICROPY_PY_MACHINE
|
#if MICROPY_PY_MACHINE
|
||||||
@@ -36,10 +35,6 @@
|
|||||||
#include "drivers/dht/dht.h"
|
#include "drivers/dht/dht.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !MICROPY_PY_SYS_EXIT
|
|
||||||
#error MICROPY_PY_MACHINE requires MICROPY_PY_SYS_EXIT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// The port must provide implementations of these low-level machine functions.
|
// The port must provide implementations of these low-level machine functions.
|
||||||
|
|
||||||
static void mp_machine_idle(void);
|
static void mp_machine_idle(void);
|
||||||
@@ -66,6 +61,12 @@ NORETURN static void mp_machine_deepsleep(size_t n_args, const mp_obj_t *args);
|
|||||||
#include MICROPY_PY_MACHINE_INCLUDEFILE
|
#include MICROPY_PY_MACHINE_INCLUDEFILE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static mp_obj_t machine_soft_reset(void) {
|
||||||
|
pyexec_system_exit = PYEXEC_FORCED_EXIT;
|
||||||
|
mp_raise_type(&mp_type_SystemExit);
|
||||||
|
}
|
||||||
|
static MP_DEFINE_CONST_FUN_OBJ_0(machine_soft_reset_obj, machine_soft_reset);
|
||||||
|
|
||||||
#if MICROPY_PY_MACHINE_BOOTLOADER
|
#if MICROPY_PY_MACHINE_BOOTLOADER
|
||||||
NORETURN mp_obj_t machine_bootloader(size_t n_args, const mp_obj_t *args) {
|
NORETURN mp_obj_t machine_bootloader(size_t n_args, const mp_obj_t *args) {
|
||||||
mp_machine_bootloader(n_args, args);
|
mp_machine_bootloader(n_args, args);
|
||||||
@@ -108,7 +109,7 @@ static mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) {
|
|||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_freq_obj, 0, MICROPY_PY_MACHINE_FREQ_NUM_ARGS_MAX, machine_freq);
|
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_freq_obj, 0, 1, machine_freq);
|
||||||
|
|
||||||
static mp_obj_t machine_lightsleep(size_t n_args, const mp_obj_t *args) {
|
static mp_obj_t machine_lightsleep(size_t n_args, const mp_obj_t *args) {
|
||||||
mp_machine_lightsleep(n_args, args);
|
mp_machine_lightsleep(n_args, args);
|
||||||
@@ -156,7 +157,7 @@ static const mp_rom_map_elem_t machine_module_globals_table[] = {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Reset related functions.
|
// Reset related functions.
|
||||||
{ MP_ROM_QSTR(MP_QSTR_soft_reset), MP_ROM_PTR(&mp_sys_exit_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_soft_reset), MP_ROM_PTR(&machine_soft_reset_obj) },
|
||||||
#if MICROPY_PY_MACHINE_BOOTLOADER
|
#if MICROPY_PY_MACHINE_BOOTLOADER
|
||||||
{ MP_ROM_QSTR(MP_QSTR_bootloader), MP_ROM_PTR(&machine_bootloader_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_bootloader), MP_ROM_PTR(&machine_bootloader_obj) },
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_network_country_obj, 0, 1, network_count
|
|||||||
|
|
||||||
mp_obj_t mod_network_hostname(size_t n_args, const mp_obj_t *args) {
|
mp_obj_t mod_network_hostname(size_t n_args, const mp_obj_t *args) {
|
||||||
if (n_args == 0) {
|
if (n_args == 0) {
|
||||||
return mp_obj_new_str_from_cstr(mod_network_hostname_data);
|
return mp_obj_new_str(mod_network_hostname_data, strlen(mod_network_hostname_data));
|
||||||
} else {
|
} else {
|
||||||
size_t len;
|
size_t len;
|
||||||
const char *str = mp_obj_str_get_data(args[0], &len);
|
const char *str = mp_obj_str_get_data(args[0], &len);
|
||||||
@@ -144,22 +144,15 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_network_hostname_obj, 0, 1, mod_n
|
|||||||
#if LWIP_VERSION_MAJOR >= 2
|
#if LWIP_VERSION_MAJOR >= 2
|
||||||
MP_DEFINE_CONST_FUN_OBJ_KW(mod_network_ipconfig_obj, 0, mod_network_ipconfig);
|
MP_DEFINE_CONST_FUN_OBJ_KW(mod_network_ipconfig_obj, 0, mod_network_ipconfig);
|
||||||
#endif
|
#endif
|
||||||
#if MICROPY_PY_NETWORK_NINAW10
|
|
||||||
MP_DEFINE_CONST_FUN_OBJ_KW(mod_network_ipconfig_obj, 0, network_ninaw10_ipconfig);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const mp_rom_map_elem_t mp_module_network_globals_table[] = {
|
static const mp_rom_map_elem_t mp_module_network_globals_table[] = {
|
||||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_network) },
|
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_network) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_country), MP_ROM_PTR(&mod_network_country_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_country), MP_ROM_PTR(&mod_network_country_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_hostname), MP_ROM_PTR(&mod_network_hostname_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_hostname), MP_ROM_PTR(&mod_network_hostname_obj) },
|
||||||
#if LWIP_VERSION_MAJOR >= 2 || MICROPY_PY_NETWORK_NINAW10
|
#if LWIP_VERSION_MAJOR >= 2
|
||||||
{ MP_ROM_QSTR(MP_QSTR_ipconfig), MP_ROM_PTR(&mod_network_ipconfig_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_ipconfig), MP_ROM_PTR(&mod_network_ipconfig_obj) },
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MICROPY_PY_NETWORK_PPP_LWIP
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_PPP), MP_ROM_PTR(&mp_network_ppp_lwip_type) },
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Defined per port in mpconfigport.h
|
// Defined per port in mpconfigport.h
|
||||||
#ifdef MICROPY_PORT_NETWORK_INTERFACES
|
#ifdef MICROPY_PORT_NETWORK_INTERFACES
|
||||||
{ MP_ROM_QSTR(MP_QSTR_route), MP_ROM_PTR(&network_route_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_route), MP_ROM_PTR(&network_route_obj) },
|
||||||
|
|||||||
@@ -72,10 +72,6 @@ mp_obj_t mod_network_hostname(size_t n_args, const mp_obj_t *args);
|
|||||||
|
|
||||||
#include "lwip/init.h"
|
#include "lwip/init.h"
|
||||||
|
|
||||||
#if MICROPY_PY_NETWORK_PPP_LWIP
|
|
||||||
extern const struct _mp_obj_type_t mp_network_ppp_lwip_type;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct netif;
|
struct netif;
|
||||||
void mod_network_lwip_init(void);
|
void mod_network_lwip_init(void);
|
||||||
void mod_network_lwip_poll_wrapper(uint32_t ticks_ms);
|
void mod_network_lwip_poll_wrapper(uint32_t ticks_ms);
|
||||||
@@ -87,10 +83,6 @@ extern int mp_mod_network_prefer_dns_use_ip_version;
|
|||||||
#endif
|
#endif
|
||||||
#elif defined(MICROPY_PORT_NETWORK_INTERFACES)
|
#elif defined(MICROPY_PORT_NETWORK_INTERFACES)
|
||||||
|
|
||||||
#if MICROPY_PY_NETWORK_NINAW10
|
|
||||||
mp_obj_t network_ninaw10_ipconfig(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct _mod_network_socket_obj_t;
|
struct _mod_network_socket_obj_t;
|
||||||
|
|
||||||
typedef struct _mod_network_nic_protocol_t {
|
typedef struct _mod_network_nic_protocol_t {
|
||||||
|
|||||||
@@ -52,20 +52,11 @@
|
|||||||
|
|
||||||
#if MICROPY_PY_OPENAMP_RSC_TABLE_ENABLE
|
#if MICROPY_PY_OPENAMP_RSC_TABLE_ENABLE
|
||||||
#define VIRTIO_DEV_ID 0xFF
|
#define VIRTIO_DEV_ID 0xFF
|
||||||
#if MICROPY_PY_OPENAMP_HOST
|
|
||||||
#define VIRTIO_DEV_ROLE RPMSG_HOST
|
|
||||||
#else
|
|
||||||
#define VIRTIO_DEV_ROLE RPMSG_REMOTE
|
|
||||||
#endif // MICROPY_PY_OPENAMP_HOST
|
|
||||||
#define VIRTIO_DEV_FEATURES (1 << VIRTIO_RPMSG_F_NS)
|
#define VIRTIO_DEV_FEATURES (1 << VIRTIO_RPMSG_F_NS)
|
||||||
|
|
||||||
#define VRING0_ID 0 // VRING0 ID (host to remote) fixed to 0 for linux compatibility
|
#define VRING0_ID 0 // VRING0 ID (host to remote) fixed to 0 for linux compatibility
|
||||||
#define VRING1_ID 1 // VRING1 ID (remote to host) fixed to 1 for linux compatibility
|
#define VRING1_ID 1 // VRING1 ID (remote to host) fixed to 1 for linux compatibility
|
||||||
#if MICROPY_PY_OPENAMP_HOST
|
|
||||||
#define VRING_NOTIFY_ID VRING0_ID
|
#define VRING_NOTIFY_ID VRING0_ID
|
||||||
#else
|
|
||||||
#define VRING_NOTIFY_ID VRING1_ID
|
|
||||||
#endif // MICROPY_PY_OPENAMP_HOST
|
|
||||||
|
|
||||||
#define VRING_COUNT 2
|
#define VRING_COUNT 2
|
||||||
#define VRING_ALIGNMENT 32
|
#define VRING_ALIGNMENT 32
|
||||||
@@ -80,15 +71,13 @@
|
|||||||
#define VRING_BUFF_ADDR (METAL_SHM_ADDR + 0x2000)
|
#define VRING_BUFF_ADDR (METAL_SHM_ADDR + 0x2000)
|
||||||
#define VRING_BUFF_SIZE (METAL_SHM_SIZE - 0x2000)
|
#define VRING_BUFF_SIZE (METAL_SHM_SIZE - 0x2000)
|
||||||
|
|
||||||
#if MICROPY_PY_OPENAMP_HOST
|
|
||||||
static const char openamp_trace_buf[128];
|
static const char openamp_trace_buf[128];
|
||||||
#define MICROPY_PY_OPENAMP_TRACE_BUF ((uint32_t)openamp_trace_buf)
|
#define MICROPY_PY_OPENAMP_TRACE_BUF ((uint32_t)openamp_trace_buf)
|
||||||
#define MICROPY_PY_OPENAMP_TRACE_BUF_LEN sizeof(MICROPY_PY_OPENAMP_TRACE_BUF)
|
#define MICROPY_PY_OPENAMP_TRACE_BUF_LEN sizeof(MICROPY_PY_OPENAMP_TRACE_BUF)
|
||||||
#endif // MICROPY_PY_OPENAMP_HOST
|
|
||||||
|
|
||||||
#endif // MICROPY_PY_OPENAMP_RSC_TABLE_ENABLE
|
#endif // MICROPY_PY_OPENAMP_RSC_TABLE_ENABLE
|
||||||
|
|
||||||
#if MICROPY_PY_OPENAMP_HOST && MICROPY_PY_OPENAMP_REMOTEPROC
|
#if MICROPY_PY_OPENAMP_REMOTEPROC
|
||||||
extern mp_obj_type_t openamp_remoteproc_type;
|
extern mp_obj_type_t openamp_remoteproc_type;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -192,13 +181,13 @@ static mp_obj_t endpoint_send(uint n_args, const mp_obj_t *pos_args, mp_map_t *k
|
|||||||
for (mp_uint_t start = mp_hal_ticks_ms(); ;) {
|
for (mp_uint_t start = mp_hal_ticks_ms(); ;) {
|
||||||
bytes = rpmsg_send_offchannel_raw(&self->ep, src, dest, rbuf.buf, rbuf.len, false);
|
bytes = rpmsg_send_offchannel_raw(&self->ep, src, dest, rbuf.buf, rbuf.len, false);
|
||||||
if (bytes > 0 || timeout == 0) {
|
if (bytes > 0 || timeout == 0) {
|
||||||
mp_event_handle_nowait();
|
MICROPY_EVENT_POLL_HOOK
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (timeout > 0 && (mp_hal_ticks_ms() - start > timeout)) {
|
if (timeout > 0 && (mp_hal_ticks_ms() - start > timeout)) {
|
||||||
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("timeout waiting for a free buffer"));
|
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("timeout waiting for a free buffer"));
|
||||||
}
|
}
|
||||||
mp_event_wait_ms(1);
|
MICROPY_EVENT_POLL_HOOK
|
||||||
}
|
}
|
||||||
return mp_obj_new_int(bytes);
|
return mp_obj_new_int(bytes);
|
||||||
}
|
}
|
||||||
@@ -221,7 +210,7 @@ static mp_obj_t endpoint_make_new(const mp_obj_type_t *type, size_t n_args, size
|
|||||||
enum { ARG_name, ARG_callback, ARG_src, ARG_dest };
|
enum { ARG_name, ARG_callback, ARG_src, ARG_dest };
|
||||||
static const mp_arg_t allowed_args[] = {
|
static const mp_arg_t allowed_args[] = {
|
||||||
{ MP_QSTR_name, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_rom_obj = MP_ROM_NONE } },
|
{ MP_QSTR_name, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_rom_obj = MP_ROM_NONE } },
|
||||||
{ MP_QSTR_callback, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE } },
|
{ MP_QSTR_callback, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_rom_obj = MP_ROM_NONE } },
|
||||||
{ MP_QSTR_src, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = RPMSG_ADDR_ANY } },
|
{ MP_QSTR_src, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = RPMSG_ADDR_ANY } },
|
||||||
{ MP_QSTR_dest, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = RPMSG_ADDR_ANY } },
|
{ MP_QSTR_dest, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = RPMSG_ADDR_ANY } },
|
||||||
};
|
};
|
||||||
@@ -274,15 +263,16 @@ static void openamp_ns_callback(struct rpmsg_device *rdev, const char *name, uin
|
|||||||
// the Name Service (NS) announcement containing the name of the channel.
|
// the Name Service (NS) announcement containing the name of the channel.
|
||||||
virtio_dev_obj_t *virtio_device = metal_container_of(rdev, virtio_dev_obj_t, rvdev);
|
virtio_dev_obj_t *virtio_device = metal_container_of(rdev, virtio_dev_obj_t, rvdev);
|
||||||
if (virtio_device->ns_callback != mp_const_none) {
|
if (virtio_device->ns_callback != mp_const_none) {
|
||||||
mp_call_function_2(virtio_device->ns_callback, mp_obj_new_int(dest), mp_obj_new_str_from_cstr(name));
|
mp_call_function_2(virtio_device->ns_callback, mp_obj_new_int(dest), mp_obj_new_str(name, strlen(name)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MICROPY_PY_OPENAMP_HOST && MICROPY_PY_OPENAMP_RSC_TABLE_ENABLE
|
#if MICROPY_PY_OPENAMP_RSC_TABLE_ENABLE
|
||||||
// The shared resource table must be initialized manually by the host here,
|
// The shared resource table must be initialized manually by the host here,
|
||||||
// because it's not located in the data region, so the startup code doesn't
|
// because it's not located in the data region, so the startup code doesn't
|
||||||
// know about it.
|
// know about it.
|
||||||
static void openamp_rsc_table_init(openamp_rsc_table_t *rsc_table) {
|
static void openamp_rsc_table_init(openamp_rsc_table_t **rsc_table_out) {
|
||||||
|
openamp_rsc_table_t *rsc_table = METAL_RSC_ADDR;
|
||||||
memset(rsc_table, 0, METAL_RSC_SIZE);
|
memset(rsc_table, 0, METAL_RSC_SIZE);
|
||||||
|
|
||||||
rsc_table->version = 1;
|
rsc_table->version = 1;
|
||||||
@@ -309,8 +299,9 @@ static void openamp_rsc_table_init(openamp_rsc_table_t *rsc_table) {
|
|||||||
// Flush resource table.
|
// Flush resource table.
|
||||||
metal_cache_flush((uint32_t *)rsc_table, sizeof(openamp_rsc_table_t));
|
metal_cache_flush((uint32_t *)rsc_table, sizeof(openamp_rsc_table_t));
|
||||||
#endif
|
#endif
|
||||||
|
*rsc_table_out = rsc_table;
|
||||||
}
|
}
|
||||||
#endif // MICROPY_PY_OPENAMP_HOST && MICROPY_PY_OPENAMP_RSC_TABLE_ENABLE
|
#endif // MICROPY_PY_OPENAMP_RSC_TABLE_ENABLE
|
||||||
|
|
||||||
static mp_obj_t openamp_new_service_callback(mp_obj_t ns_callback) {
|
static mp_obj_t openamp_new_service_callback(mp_obj_t ns_callback) {
|
||||||
if (MP_STATE_PORT(virtio_device) == NULL) {
|
if (MP_STATE_PORT(virtio_device) == NULL) {
|
||||||
@@ -351,10 +342,8 @@ void openamp_init(void) {
|
|||||||
metal_init(&metal_params);
|
metal_init(&metal_params);
|
||||||
|
|
||||||
// Initialize the shared resource table.
|
// Initialize the shared resource table.
|
||||||
openamp_rsc_table_t *rsc_table = METAL_RSC_ADDR;
|
openamp_rsc_table_t *rsc_table;
|
||||||
#if MICROPY_PY_OPENAMP_HOST
|
openamp_rsc_table_init(&rsc_table);
|
||||||
openamp_rsc_table_init(rsc_table);
|
|
||||||
#endif // MICROPY_PY_OPENAMP_HOST
|
|
||||||
|
|
||||||
if (metal_register_generic_device(&shm_device) != 0) {
|
if (metal_register_generic_device(&shm_device) != 0) {
|
||||||
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Failed to register metal device"));
|
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Failed to register metal device"));
|
||||||
@@ -379,7 +368,7 @@ void openamp_init(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create virtio device.
|
// Create virtio device.
|
||||||
struct virtio_device *vdev = rproc_virtio_create_vdev(VIRTIO_DEV_ROLE, VIRTIO_DEV_ID,
|
struct virtio_device *vdev = rproc_virtio_create_vdev(RPMSG_HOST, VIRTIO_DEV_ID,
|
||||||
&rsc_table->vdev, rsc_io, NULL, metal_rproc_notify, NULL);
|
&rsc_table->vdev, rsc_io, NULL, metal_rproc_notify, NULL);
|
||||||
if (vdev == NULL) {
|
if (vdev == NULL) {
|
||||||
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Failed to create virtio device"));
|
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Failed to create virtio device"));
|
||||||
@@ -400,8 +389,8 @@ void openamp_init(void) {
|
|||||||
// The remote processor detects that the virtio device is ready by polling
|
// The remote processor detects that the virtio device is ready by polling
|
||||||
// the status field in the resource table.
|
// the status field in the resource table.
|
||||||
rpmsg_virtio_init_shm_pool(&virtio_device->shm_pool, (void *)VRING_BUFF_ADDR, (size_t)VRING_BUFF_SIZE);
|
rpmsg_virtio_init_shm_pool(&virtio_device->shm_pool, (void *)VRING_BUFF_ADDR, (size_t)VRING_BUFF_SIZE);
|
||||||
|
|
||||||
rpmsg_init_vdev(&virtio_device->rvdev, vdev, openamp_ns_callback, shm_io, &virtio_device->shm_pool);
|
rpmsg_init_vdev(&virtio_device->rvdev, vdev, openamp_ns_callback, shm_io, &virtio_device->shm_pool);
|
||||||
|
|
||||||
MP_STATE_PORT(virtio_device) = virtio_device;
|
MP_STATE_PORT(virtio_device) = virtio_device;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -410,7 +399,7 @@ static const mp_rom_map_elem_t globals_dict_table[] = {
|
|||||||
{ MP_ROM_QSTR(MP_QSTR_ENDPOINT_ADDR_ANY), MP_ROM_INT(RPMSG_ADDR_ANY) },
|
{ MP_ROM_QSTR(MP_QSTR_ENDPOINT_ADDR_ANY), MP_ROM_INT(RPMSG_ADDR_ANY) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_new_service_callback), MP_ROM_PTR(&openamp_new_service_callback_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_new_service_callback), MP_ROM_PTR(&openamp_new_service_callback_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_Endpoint), MP_ROM_PTR(&endpoint_type) },
|
{ MP_ROM_QSTR(MP_QSTR_Endpoint), MP_ROM_PTR(&endpoint_type) },
|
||||||
#if MICROPY_PY_OPENAMP_HOST && MICROPY_PY_OPENAMP_REMOTEPROC
|
#if MICROPY_PY_OPENAMP_REMOTEPROC
|
||||||
{ MP_ROM_QSTR(MP_QSTR_RemoteProc), MP_ROM_PTR(&openamp_remoteproc_type) },
|
{ MP_ROM_QSTR(MP_QSTR_RemoteProc), MP_ROM_PTR(&openamp_remoteproc_type) },
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
* OpenAMP's remoteproc class.
|
* OpenAMP's remoteproc class.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if MICROPY_PY_OPENAMP_HOST && MICROPY_PY_OPENAMP_REMOTEPROC
|
#if MICROPY_PY_OPENAMP_REMOTEPROC
|
||||||
|
|
||||||
#include "py/obj.h"
|
#include "py/obj.h"
|
||||||
#include "py/nlr.h"
|
#include "py/nlr.h"
|
||||||
@@ -137,7 +137,7 @@ mp_obj_t openamp_remoteproc_make_new(const mp_obj_type_t *type, size_t n_args, s
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mp_obj_is_int(args[ARG_entry].u_obj)) {
|
if (mp_obj_is_int(args[ARG_entry].u_obj)) {
|
||||||
self->rproc.bootaddr = mp_obj_int_get_truncated(args[ARG_entry].u_obj);
|
self->rproc.bootaddr = mp_obj_get_int(args[ARG_entry].u_obj);
|
||||||
} else {
|
} else {
|
||||||
#if MICROPY_PY_OPENAMP_REMOTEPROC_ELFLD_ENABLE
|
#if MICROPY_PY_OPENAMP_REMOTEPROC_ELFLD_ENABLE
|
||||||
// Load firmware.
|
// Load firmware.
|
||||||
@@ -170,4 +170,4 @@ MP_DEFINE_CONST_OBJ_TYPE(
|
|||||||
locals_dict, &openamp_remoteproc_dict
|
locals_dict, &openamp_remoteproc_dict
|
||||||
);
|
);
|
||||||
|
|
||||||
#endif // MICROPY_PY_OPENAMP_HOST && MICROPY_PY_OPENAMP_REMOTEPROC
|
#endif // MICROPY_PY_OPENAMP_REMOTEPROC
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
* OpenAMP's remoteproc store.
|
* OpenAMP's remoteproc store.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if MICROPY_PY_OPENAMP_HOST && MICROPY_PY_OPENAMP_REMOTEPROC
|
#if MICROPY_PY_OPENAMP_REMOTEPROC
|
||||||
|
|
||||||
#include "py/obj.h"
|
#include "py/obj.h"
|
||||||
#include "py/nlr.h"
|
#include "py/nlr.h"
|
||||||
@@ -70,7 +70,7 @@ void *mp_openamp_remoteproc_store_alloc(void) {
|
|||||||
static int openamp_remoteproc_store_open(void *store, const char *path, const void **image_data) {
|
static int openamp_remoteproc_store_open(void *store, const char *path, const void **image_data) {
|
||||||
metal_log(METAL_LOG_DEBUG, "store_open(): %s\n", path);
|
metal_log(METAL_LOG_DEBUG, "store_open(): %s\n", path);
|
||||||
mp_obj_t args[2] = {
|
mp_obj_t args[2] = {
|
||||||
mp_obj_new_str_from_cstr(path),
|
mp_obj_new_str(path, strlen(path)),
|
||||||
MP_OBJ_NEW_QSTR(MP_QSTR_rb),
|
MP_OBJ_NEW_QSTR(MP_QSTR_rb),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -141,4 +141,4 @@ const struct image_store_ops openamp_remoteproc_store_ops = {
|
|||||||
|
|
||||||
#endif // MICROPY_PY_OPENAMP_REMOTEPROC_STORE_ENABLE
|
#endif // MICROPY_PY_OPENAMP_REMOTEPROC_STORE_ENABLE
|
||||||
|
|
||||||
#endif // MICROPY_PY_OPENAMP_HOST && MICROPY_PY_OPENAMP_REMOTEPROC
|
#endif // MICROPY_PY_OPENAMP_REMOTEPROC
|
||||||
|
|||||||
@@ -153,6 +153,9 @@ static const mp_rom_map_elem_t os_module_globals_table[] = {
|
|||||||
{ MP_ROM_QSTR(MP_QSTR_putenv), MP_ROM_PTR(&mp_os_putenv_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_putenv), MP_ROM_PTR(&mp_os_putenv_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_unsetenv), MP_ROM_PTR(&mp_os_unsetenv_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_unsetenv), MP_ROM_PTR(&mp_os_unsetenv_obj) },
|
||||||
#endif
|
#endif
|
||||||
|
#if MICROPY_PY_OS_SEP
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_sep), MP_ROM_QSTR(MP_QSTR__slash_) },
|
||||||
|
#endif
|
||||||
#if MICROPY_PY_OS_SYNC
|
#if MICROPY_PY_OS_SYNC
|
||||||
{ MP_ROM_QSTR(MP_QSTR_sync), MP_ROM_PTR(&mp_os_sync_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_sync), MP_ROM_PTR(&mp_os_sync_obj) },
|
||||||
#endif
|
#endif
|
||||||
@@ -167,7 +170,6 @@ static const mp_rom_map_elem_t os_module_globals_table[] = {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MICROPY_VFS
|
#if MICROPY_VFS
|
||||||
{ MP_ROM_QSTR(MP_QSTR_sep), MP_ROM_QSTR(MP_QSTR__slash_) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_chdir), MP_ROM_PTR(&mp_vfs_chdir_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_chdir), MP_ROM_PTR(&mp_vfs_chdir_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_getcwd), MP_ROM_PTR(&mp_vfs_getcwd_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_getcwd), MP_ROM_PTR(&mp_vfs_getcwd_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_listdir), MP_ROM_PTR(&mp_vfs_listdir_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_listdir), MP_ROM_PTR(&mp_vfs_listdir_obj) },
|
||||||
|
|||||||
@@ -83,9 +83,6 @@
|
|||||||
#elif defined(__NEWLIB__)
|
#elif defined(__NEWLIB__)
|
||||||
#define MICROPY_PLATFORM_LIBC_LIB "newlib"
|
#define MICROPY_PLATFORM_LIBC_LIB "newlib"
|
||||||
#define MICROPY_PLATFORM_LIBC_VER _NEWLIB_VERSION
|
#define MICROPY_PLATFORM_LIBC_VER _NEWLIB_VERSION
|
||||||
#elif defined(_PICOLIBC__)
|
|
||||||
#define MICROPY_PLATFORM_LIBC_LIB "picolibc"
|
|
||||||
#define MICROPY_PLATFORM_LIBC_VER _PICOLIBC_VERSION
|
|
||||||
#else
|
#else
|
||||||
#define MICROPY_PLATFORM_LIBC_LIB ""
|
#define MICROPY_PLATFORM_LIBC_LIB ""
|
||||||
#define MICROPY_PLATFORM_LIBC_VER ""
|
#define MICROPY_PLATFORM_LIBC_VER ""
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
#include "py/binary.h"
|
#include "py/binary.h"
|
||||||
#include "py/objstr.h"
|
#include "py/objstr.h"
|
||||||
#include "py/cstack.h"
|
#include "py/stackctrl.h"
|
||||||
|
|
||||||
#if MICROPY_PY_BUILTINS_STR_UNICODE
|
#if MICROPY_PY_BUILTINS_STR_UNICODE
|
||||||
#include "py/unicode.h"
|
#include "py/unicode.h"
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
#if MICROPY_PY_RE
|
#if MICROPY_PY_RE
|
||||||
|
|
||||||
#define re1_5_stack_chk() mp_cstack_check()
|
#define re1_5_stack_chk() MP_STACK_CHECK()
|
||||||
|
|
||||||
#include "lib/re1.5/re1.5.h"
|
#include "lib/re1.5/re1.5.h"
|
||||||
|
|
||||||
@@ -194,8 +194,7 @@ static void re_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t
|
|||||||
mp_printf(print, "<re %p>", self);
|
mp_printf(print, "<re %p>", self);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: this function can't be named re_exec because it may clash with system headers, eg on FreeBSD
|
static mp_obj_t re_exec(bool is_anchored, uint n_args, const mp_obj_t *args) {
|
||||||
static mp_obj_t re_exec_helper(bool is_anchored, uint n_args, const mp_obj_t *args) {
|
|
||||||
(void)n_args;
|
(void)n_args;
|
||||||
mp_obj_re_t *self;
|
mp_obj_re_t *self;
|
||||||
if (mp_obj_is_type(args[0], (mp_obj_type_t *)&re_type)) {
|
if (mp_obj_is_type(args[0], (mp_obj_type_t *)&re_type)) {
|
||||||
@@ -224,12 +223,12 @@ static mp_obj_t re_exec_helper(bool is_anchored, uint n_args, const mp_obj_t *ar
|
|||||||
}
|
}
|
||||||
|
|
||||||
static mp_obj_t re_match(size_t n_args, const mp_obj_t *args) {
|
static mp_obj_t re_match(size_t n_args, const mp_obj_t *args) {
|
||||||
return re_exec_helper(true, n_args, args);
|
return re_exec(true, n_args, args);
|
||||||
}
|
}
|
||||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(re_match_obj, 2, 4, re_match);
|
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(re_match_obj, 2, 4, re_match);
|
||||||
|
|
||||||
static mp_obj_t re_search(size_t n_args, const mp_obj_t *args) {
|
static mp_obj_t re_search(size_t n_args, const mp_obj_t *args) {
|
||||||
return re_exec_helper(false, n_args, args);
|
return re_exec(false, n_args, args);
|
||||||
}
|
}
|
||||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(re_search_obj, 2, 4, re_search);
|
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(re_search_obj, 2, 4, re_search);
|
||||||
|
|
||||||
|
|||||||
@@ -53,10 +53,6 @@
|
|||||||
#else
|
#else
|
||||||
#include "mbedtls/version.h"
|
#include "mbedtls/version.h"
|
||||||
#endif
|
#endif
|
||||||
#if MICROPY_PY_SSL_ECDSA_SIGN_ALT
|
|
||||||
#include "mbedtls/ecdsa.h"
|
|
||||||
#include "mbedtls/asn1.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MP_STREAM_POLL_RDWR (MP_STREAM_POLL_RD | MP_STREAM_POLL_WR)
|
#define MP_STREAM_POLL_RDWR (MP_STREAM_POLL_RD | MP_STREAM_POLL_WR)
|
||||||
|
|
||||||
@@ -72,9 +68,6 @@ typedef struct _mp_obj_ssl_context_t {
|
|||||||
int authmode;
|
int authmode;
|
||||||
int *ciphersuites;
|
int *ciphersuites;
|
||||||
mp_obj_t handler;
|
mp_obj_t handler;
|
||||||
#if MICROPY_PY_SSL_ECDSA_SIGN_ALT
|
|
||||||
mp_obj_t ecdsa_sign_callback;
|
|
||||||
#endif
|
|
||||||
} mp_obj_ssl_context_t;
|
} mp_obj_ssl_context_t;
|
||||||
|
|
||||||
// This corresponds to an SSLSocket object.
|
// This corresponds to an SSLSocket object.
|
||||||
@@ -107,23 +100,6 @@ static void mbedtls_debug(void *ctx, int level, const char *file, int line, cons
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Given a string-like object holding PEM or DER formatted ASN.1 data, return a
|
|
||||||
// pointer to its buffer and the correct length for mbedTLS APIs.
|
|
||||||
//
|
|
||||||
// (mbedTLS >= 3.5 rejects DER formatted data with trailing bytes within keylen,
|
|
||||||
// but PEM must include a terminating NUL byte in the keylen...)
|
|
||||||
static const unsigned char *asn1_get_data(mp_obj_t obj, size_t *out_len) {
|
|
||||||
size_t len;
|
|
||||||
const char *str = mp_obj_str_get_data(obj, &len);
|
|
||||||
#if defined(MBEDTLS_PEM_PARSE_C)
|
|
||||||
if (strstr(str, "-----BEGIN ") != NULL) {
|
|
||||||
++len;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
*out_len = len;
|
|
||||||
return (const unsigned char *)str;
|
|
||||||
}
|
|
||||||
|
|
||||||
static NORETURN void mbedtls_raise_error(int err) {
|
static NORETURN void mbedtls_raise_error(int err) {
|
||||||
// Handle special cases.
|
// Handle special cases.
|
||||||
if (err == MBEDTLS_ERR_SSL_ALLOC_FAILED) {
|
if (err == MBEDTLS_ERR_SSL_ALLOC_FAILED) {
|
||||||
@@ -173,13 +149,6 @@ static NORETURN void mbedtls_raise_error(int err) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stores the current SSLContext for use in mbedtls callbacks where the current state is not passed.
|
|
||||||
static inline void store_active_context(mp_obj_ssl_context_t *ssl_context) {
|
|
||||||
#if MICROPY_PY_SSL_MBEDTLS_NEED_ACTIVE_CONTEXT
|
|
||||||
MP_STATE_THREAD(tls_ssl_context) = ssl_context;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ssl_check_async_handshake_failure(mp_obj_ssl_socket_t *sslsock, int *errcode) {
|
static void ssl_check_async_handshake_failure(mp_obj_ssl_socket_t *sslsock, int *errcode) {
|
||||||
if (
|
if (
|
||||||
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
|
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
|
||||||
@@ -255,9 +224,6 @@ static mp_obj_t ssl_context_make_new(const mp_obj_type_t *type_in, size_t n_args
|
|||||||
mbedtls_pk_init(&self->pkey);
|
mbedtls_pk_init(&self->pkey);
|
||||||
self->ciphersuites = NULL;
|
self->ciphersuites = NULL;
|
||||||
self->handler = mp_const_none;
|
self->handler = mp_const_none;
|
||||||
#if MICROPY_PY_SSL_ECDSA_SIGN_ALT
|
|
||||||
self->ecdsa_sign_callback = mp_const_none;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MBEDTLS_DEBUG_C
|
#ifdef MBEDTLS_DEBUG_C
|
||||||
// Debug level (0-4) 1=warning, 2=info, 3=debug, 4=verbose
|
// Debug level (0-4) 1=warning, 2=info, 3=debug, 4=verbose
|
||||||
@@ -305,10 +271,6 @@ static void ssl_context_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
|||||||
dest[0] = MP_OBJ_NEW_SMALL_INT(self->authmode);
|
dest[0] = MP_OBJ_NEW_SMALL_INT(self->authmode);
|
||||||
} else if (attr == MP_QSTR_verify_callback) {
|
} else if (attr == MP_QSTR_verify_callback) {
|
||||||
dest[0] = self->handler;
|
dest[0] = self->handler;
|
||||||
#if MICROPY_PY_SSL_ECDSA_SIGN_ALT
|
|
||||||
} else if (attr == MP_QSTR_ecdsa_sign_callback) {
|
|
||||||
dest[0] = self->ecdsa_sign_callback;
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
// Continue lookup in locals_dict.
|
// Continue lookup in locals_dict.
|
||||||
dest[1] = MP_OBJ_SENTINEL;
|
dest[1] = MP_OBJ_SENTINEL;
|
||||||
@@ -319,11 +281,6 @@ static void ssl_context_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
|||||||
self->authmode = mp_obj_get_int(dest[1]);
|
self->authmode = mp_obj_get_int(dest[1]);
|
||||||
dest[0] = MP_OBJ_NULL;
|
dest[0] = MP_OBJ_NULL;
|
||||||
mbedtls_ssl_conf_authmode(&self->conf, self->authmode);
|
mbedtls_ssl_conf_authmode(&self->conf, self->authmode);
|
||||||
#if MICROPY_PY_SSL_ECDSA_SIGN_ALT
|
|
||||||
} else if (attr == MP_QSTR_ecdsa_sign_callback) {
|
|
||||||
dest[0] = MP_OBJ_NULL;
|
|
||||||
self->ecdsa_sign_callback = dest[1];
|
|
||||||
#endif
|
|
||||||
} else if (attr == MP_QSTR_verify_callback) {
|
} else if (attr == MP_QSTR_verify_callback) {
|
||||||
dest[0] = MP_OBJ_NULL;
|
dest[0] = MP_OBJ_NULL;
|
||||||
self->handler = dest[1];
|
self->handler = dest[1];
|
||||||
@@ -350,7 +307,7 @@ static mp_obj_t ssl_context_get_ciphers(mp_obj_t self_in) {
|
|||||||
mp_obj_t list = mp_obj_new_list(0, NULL);
|
mp_obj_t list = mp_obj_new_list(0, NULL);
|
||||||
for (const int *cipher_list = mbedtls_ssl_list_ciphersuites(); *cipher_list; ++cipher_list) {
|
for (const int *cipher_list = mbedtls_ssl_list_ciphersuites(); *cipher_list; ++cipher_list) {
|
||||||
const char *cipher_name = mbedtls_ssl_get_ciphersuite_name(*cipher_list);
|
const char *cipher_name = mbedtls_ssl_get_ciphersuite_name(*cipher_list);
|
||||||
mp_obj_list_append(list, MP_OBJ_FROM_PTR(mp_obj_new_str_from_cstr(cipher_name)));
|
mp_obj_list_append(list, MP_OBJ_FROM_PTR(mp_obj_new_str(cipher_name, strlen(cipher_name))));
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
@@ -389,20 +346,22 @@ static MP_DEFINE_CONST_FUN_OBJ_2(ssl_context_set_ciphers_obj, ssl_context_set_ci
|
|||||||
|
|
||||||
static void ssl_context_load_key(mp_obj_ssl_context_t *self, mp_obj_t key_obj, mp_obj_t cert_obj) {
|
static void ssl_context_load_key(mp_obj_ssl_context_t *self, mp_obj_t key_obj, mp_obj_t cert_obj) {
|
||||||
size_t key_len;
|
size_t key_len;
|
||||||
const unsigned char *key = asn1_get_data(key_obj, &key_len);
|
const byte *key = (const byte *)mp_obj_str_get_data(key_obj, &key_len);
|
||||||
|
// len should include terminating null
|
||||||
int ret;
|
int ret;
|
||||||
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
|
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
|
||||||
ret = mbedtls_pk_parse_key(&self->pkey, key, key_len, NULL, 0, mbedtls_ctr_drbg_random, &self->ctr_drbg);
|
ret = mbedtls_pk_parse_key(&self->pkey, key, key_len + 1, NULL, 0, mbedtls_ctr_drbg_random, &self->ctr_drbg);
|
||||||
#else
|
#else
|
||||||
ret = mbedtls_pk_parse_key(&self->pkey, key, key_len, NULL, 0);
|
ret = mbedtls_pk_parse_key(&self->pkey, key, key_len + 1, NULL, 0);
|
||||||
#endif
|
#endif
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
mbedtls_raise_error(MBEDTLS_ERR_PK_BAD_INPUT_DATA); // use general error for all key errors
|
mbedtls_raise_error(MBEDTLS_ERR_PK_BAD_INPUT_DATA); // use general error for all key errors
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t cert_len;
|
size_t cert_len;
|
||||||
const unsigned char *cert = asn1_get_data(cert_obj, &cert_len);
|
const byte *cert = (const byte *)mp_obj_str_get_data(cert_obj, &cert_len);
|
||||||
ret = mbedtls_x509_crt_parse(&self->cert, cert, cert_len);
|
// len should include terminating null
|
||||||
|
ret = mbedtls_x509_crt_parse(&self->cert, cert, cert_len + 1);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
mbedtls_raise_error(MBEDTLS_ERR_X509_BAD_INPUT_DATA); // use general error for all cert errors
|
mbedtls_raise_error(MBEDTLS_ERR_X509_BAD_INPUT_DATA); // use general error for all cert errors
|
||||||
}
|
}
|
||||||
@@ -423,8 +382,9 @@ static MP_DEFINE_CONST_FUN_OBJ_3(ssl_context_load_cert_chain_obj, ssl_context_lo
|
|||||||
|
|
||||||
static void ssl_context_load_cadata(mp_obj_ssl_context_t *self, mp_obj_t cadata_obj) {
|
static void ssl_context_load_cadata(mp_obj_ssl_context_t *self, mp_obj_t cadata_obj) {
|
||||||
size_t cacert_len;
|
size_t cacert_len;
|
||||||
const unsigned char *cacert = asn1_get_data(cadata_obj, &cacert_len);
|
const byte *cacert = (const byte *)mp_obj_str_get_data(cadata_obj, &cacert_len);
|
||||||
int ret = mbedtls_x509_crt_parse(&self->cacert, cacert, cacert_len);
|
// len should include terminating null
|
||||||
|
int ret = mbedtls_x509_crt_parse(&self->cacert, cacert, cacert_len + 1);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
mbedtls_raise_error(MBEDTLS_ERR_X509_BAD_INPUT_DATA); // use general error for all cert errors
|
mbedtls_raise_error(MBEDTLS_ERR_X509_BAD_INPUT_DATA); // use general error for all cert errors
|
||||||
}
|
}
|
||||||
@@ -523,9 +483,6 @@ static int _mbedtls_ssl_recv(void *ctx, byte *buf, size_t len) {
|
|||||||
static mp_obj_t ssl_socket_make_new(mp_obj_ssl_context_t *ssl_context, mp_obj_t sock,
|
static mp_obj_t ssl_socket_make_new(mp_obj_ssl_context_t *ssl_context, mp_obj_t sock,
|
||||||
bool server_side, bool do_handshake_on_connect, mp_obj_t server_hostname) {
|
bool server_side, bool do_handshake_on_connect, mp_obj_t server_hostname) {
|
||||||
|
|
||||||
// Store the current SSL context.
|
|
||||||
store_active_context(ssl_context);
|
|
||||||
|
|
||||||
// Verify the socket object has the full stream protocol
|
// Verify the socket object has the full stream protocol
|
||||||
mp_get_stream_raise(sock, MP_STREAM_OP_READ | MP_STREAM_OP_WRITE | MP_STREAM_OP_IOCTL);
|
mp_get_stream_raise(sock, MP_STREAM_OP_READ | MP_STREAM_OP_WRITE | MP_STREAM_OP_IOCTL);
|
||||||
|
|
||||||
@@ -615,8 +572,8 @@ static mp_obj_t mod_ssl_cipher(mp_obj_t o_in) {
|
|||||||
mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(o_in);
|
mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(o_in);
|
||||||
const char *cipher_suite = mbedtls_ssl_get_ciphersuite(&o->ssl);
|
const char *cipher_suite = mbedtls_ssl_get_ciphersuite(&o->ssl);
|
||||||
const char *tls_version = mbedtls_ssl_get_version(&o->ssl);
|
const char *tls_version = mbedtls_ssl_get_version(&o->ssl);
|
||||||
mp_obj_t tuple[2] = {mp_obj_new_str_from_cstr(cipher_suite),
|
mp_obj_t tuple[2] = {mp_obj_new_str(cipher_suite, strlen(cipher_suite)),
|
||||||
mp_obj_new_str_from_cstr(tls_version)};
|
mp_obj_new_str(tls_version, strlen(tls_version))};
|
||||||
|
|
||||||
return mp_obj_new_tuple(2, tuple);
|
return mp_obj_new_tuple(2, tuple);
|
||||||
}
|
}
|
||||||
@@ -631,9 +588,6 @@ static mp_uint_t socket_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errc
|
|||||||
return MP_STREAM_ERROR;
|
return MP_STREAM_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the current SSL context.
|
|
||||||
store_active_context(o->ssl_context);
|
|
||||||
|
|
||||||
int ret = mbedtls_ssl_read(&o->ssl, buf, size);
|
int ret = mbedtls_ssl_read(&o->ssl, buf, size);
|
||||||
if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
|
if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
|
||||||
// end of stream
|
// end of stream
|
||||||
@@ -675,9 +629,6 @@ static mp_uint_t socket_write(mp_obj_t o_in, const void *buf, mp_uint_t size, in
|
|||||||
return MP_STREAM_ERROR;
|
return MP_STREAM_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the current SSL context.
|
|
||||||
store_active_context(o->ssl_context);
|
|
||||||
|
|
||||||
int ret = mbedtls_ssl_write(&o->ssl, buf, size);
|
int ret = mbedtls_ssl_write(&o->ssl, buf, size);
|
||||||
if (ret >= 0) {
|
if (ret >= 0) {
|
||||||
return ret;
|
return ret;
|
||||||
@@ -715,9 +666,6 @@ static mp_uint_t socket_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg, i
|
|||||||
mp_obj_t sock = self->sock;
|
mp_obj_t sock = self->sock;
|
||||||
|
|
||||||
if (request == MP_STREAM_CLOSE) {
|
if (request == MP_STREAM_CLOSE) {
|
||||||
// Clear the SSL context.
|
|
||||||
store_active_context(NULL);
|
|
||||||
|
|
||||||
if (sock == MP_OBJ_NULL) {
|
if (sock == MP_OBJ_NULL) {
|
||||||
// Already closed socket, do nothing.
|
// Already closed socket, do nothing.
|
||||||
return 0;
|
return 0;
|
||||||
@@ -805,57 +753,6 @@ static MP_DEFINE_CONST_OBJ_TYPE(
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
// ssl module.
|
// ssl module.
|
||||||
|
|
||||||
#if MICROPY_PY_SSL_ECDSA_SIGN_ALT
|
|
||||||
int micropy_mbedtls_ecdsa_sign_alt(const mbedtls_mpi *d, const unsigned char *hash, size_t hlen, unsigned char *sig, size_t sig_size, size_t *slen) {
|
|
||||||
uint8_t key[256];
|
|
||||||
|
|
||||||
// Check if the current context has an alternative sign function.
|
|
||||||
mp_obj_ssl_context_t *ssl_ctx = MP_STATE_THREAD(tls_ssl_context);
|
|
||||||
if (ssl_ctx == NULL || ssl_ctx->ecdsa_sign_callback == mp_const_none) {
|
|
||||||
return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t klen = mbedtls_mpi_size(d);
|
|
||||||
if (klen > sizeof(key)) {
|
|
||||||
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert the MPI private key (d) to a binary array
|
|
||||||
if (mbedtls_mpi_write_binary(d, key, klen) != 0) {
|
|
||||||
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
nlr_buf_t nlr;
|
|
||||||
mp_buffer_info_t sig_buf;
|
|
||||||
if (nlr_push(&nlr) == 0) {
|
|
||||||
mp_obj_t ret = mp_call_function_2(ssl_ctx->ecdsa_sign_callback,
|
|
||||||
mp_obj_new_bytearray_by_ref(klen, (void *)key),
|
|
||||||
mp_obj_new_bytearray_by_ref(hlen, (void *)hash));
|
|
||||||
if (ret == mp_const_none) {
|
|
||||||
// key couldn't be used by the alternative implementation.
|
|
||||||
nlr_pop();
|
|
||||||
return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
mp_get_buffer_raise(ret, &sig_buf, MP_BUFFER_READ);
|
|
||||||
nlr_pop();
|
|
||||||
} else {
|
|
||||||
// The alternative implementation failed to sign.
|
|
||||||
mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(nlr.ret_val));
|
|
||||||
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the buffer fits.
|
|
||||||
if (sig_buf.len > sig_size) {
|
|
||||||
return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy ASN.1 signature to buffer.
|
|
||||||
*slen = sig_buf.len;
|
|
||||||
memcpy(sig, sig_buf.buf, sig_buf.len);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const mp_rom_map_elem_t mp_module_tls_globals_table[] = {
|
static const mp_rom_map_elem_t mp_module_tls_globals_table[] = {
|
||||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_tls) },
|
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_tls) },
|
||||||
|
|
||||||
|
|||||||
@@ -143,10 +143,6 @@ static inline mp_uint_t uctypes_struct_scalar_size(int val_type) {
|
|||||||
|
|
||||||
// Get size of aggregate type descriptor
|
// Get size of aggregate type descriptor
|
||||||
static mp_uint_t uctypes_struct_agg_size(mp_obj_tuple_t *t, int layout_type, mp_uint_t *max_field_size) {
|
static mp_uint_t uctypes_struct_agg_size(mp_obj_tuple_t *t, int layout_type, mp_uint_t *max_field_size) {
|
||||||
if (t->len == 0) {
|
|
||||||
syntax_error();
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_uint_t total_size = 0;
|
mp_uint_t total_size = 0;
|
||||||
|
|
||||||
mp_int_t offset_ = MP_OBJ_SMALL_INT_VALUE(t->items[0]);
|
mp_int_t offset_ = MP_OBJ_SMALL_INT_VALUE(t->items[0]);
|
||||||
@@ -154,15 +150,8 @@ static mp_uint_t uctypes_struct_agg_size(mp_obj_tuple_t *t, int layout_type, mp_
|
|||||||
|
|
||||||
switch (agg_type) {
|
switch (agg_type) {
|
||||||
case STRUCT:
|
case STRUCT:
|
||||||
if (t->len != 2) {
|
|
||||||
syntax_error();
|
|
||||||
}
|
|
||||||
return uctypes_struct_size(t->items[1], layout_type, max_field_size);
|
return uctypes_struct_size(t->items[1], layout_type, max_field_size);
|
||||||
case PTR:
|
case PTR:
|
||||||
// Second field ignored, but should still be present for consistency.
|
|
||||||
if (t->len != 2) {
|
|
||||||
syntax_error();
|
|
||||||
}
|
|
||||||
if (sizeof(void *) > *max_field_size) {
|
if (sizeof(void *) > *max_field_size) {
|
||||||
*max_field_size = sizeof(void *);
|
*max_field_size = sizeof(void *);
|
||||||
}
|
}
|
||||||
@@ -178,17 +167,15 @@ static mp_uint_t uctypes_struct_agg_size(mp_obj_tuple_t *t, int layout_type, mp_
|
|||||||
if (item_s > *max_field_size) {
|
if (item_s > *max_field_size) {
|
||||||
*max_field_size = item_s;
|
*max_field_size = item_s;
|
||||||
}
|
}
|
||||||
} else if (t->len == 3) {
|
} else {
|
||||||
// Elements of array are aggregates
|
// Elements of array are aggregates
|
||||||
item_s = uctypes_struct_size(t->items[2], layout_type, max_field_size);
|
item_s = uctypes_struct_size(t->items[2], layout_type, max_field_size);
|
||||||
} else {
|
|
||||||
syntax_error();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return item_s * arr_sz;
|
return item_s * arr_sz;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
syntax_error();
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return total_size;
|
return total_size;
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ static void handle_op(mp_obj_webrepl_t *self) {
|
|||||||
// Handle operations requiring opened file
|
// Handle operations requiring opened file
|
||||||
|
|
||||||
mp_obj_t open_args[2] = {
|
mp_obj_t open_args[2] = {
|
||||||
mp_obj_new_str_from_cstr(self->hdr.fname),
|
mp_obj_new_str(self->hdr.fname, strlen(self->hdr.fname)),
|
||||||
MP_OBJ_NEW_QSTR(MP_QSTR_rb)
|
MP_OBJ_NEW_QSTR(MP_QSTR_rb)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -60,10 +60,6 @@ typedef struct _network_cyw43_obj_t {
|
|||||||
static const network_cyw43_obj_t network_cyw43_wl_sta = { { &mp_network_cyw43_type }, &cyw43_state, CYW43_ITF_STA };
|
static const network_cyw43_obj_t network_cyw43_wl_sta = { { &mp_network_cyw43_type }, &cyw43_state, CYW43_ITF_STA };
|
||||||
static const network_cyw43_obj_t network_cyw43_wl_ap = { { &mp_network_cyw43_type }, &cyw43_state, CYW43_ITF_AP };
|
static const network_cyw43_obj_t network_cyw43_wl_ap = { { &mp_network_cyw43_type }, &cyw43_state, CYW43_ITF_AP };
|
||||||
|
|
||||||
// Avoid race conditions with callbacks by tracking the last up or down request
|
|
||||||
// we have made for each interface.
|
|
||||||
static bool if_active[2];
|
|
||||||
|
|
||||||
static void network_cyw43_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
static void network_cyw43_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||||
network_cyw43_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
network_cyw43_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
struct netif *netif = &self->cyw->netif[self->itf];
|
struct netif *netif = &self->cyw->netif[self->itf];
|
||||||
@@ -126,10 +122,6 @@ static MP_DEFINE_CONST_FUN_OBJ_3(network_cyw43_ioctl_obj, network_cyw43_ioctl);
|
|||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
// network API
|
// network API
|
||||||
|
|
||||||
static uint32_t get_country_code(void) {
|
|
||||||
return CYW43_COUNTRY(mod_network_country_code[0], mod_network_country_code[1], 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static mp_obj_t network_cyw43_deinit(mp_obj_t self_in) {
|
static mp_obj_t network_cyw43_deinit(mp_obj_t self_in) {
|
||||||
network_cyw43_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
network_cyw43_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
cyw43_deinit(self->cyw);
|
cyw43_deinit(self->cyw);
|
||||||
@@ -140,11 +132,10 @@ static MP_DEFINE_CONST_FUN_OBJ_1(network_cyw43_deinit_obj, network_cyw43_deinit)
|
|||||||
static mp_obj_t network_cyw43_active(size_t n_args, const mp_obj_t *args) {
|
static mp_obj_t network_cyw43_active(size_t n_args, const mp_obj_t *args) {
|
||||||
network_cyw43_obj_t *self = MP_OBJ_TO_PTR(args[0]);
|
network_cyw43_obj_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||||
if (n_args == 1) {
|
if (n_args == 1) {
|
||||||
return mp_obj_new_bool(if_active[self->itf]);
|
return mp_obj_new_bool(cyw43_tcpip_link_status(self->cyw, self->itf));
|
||||||
} else {
|
} else {
|
||||||
bool value = mp_obj_is_true(args[1]);
|
uint32_t country = CYW43_COUNTRY(mod_network_country_code[0], mod_network_country_code[1], 0);
|
||||||
cyw43_wifi_set_up(self->cyw, self->itf, value, get_country_code());
|
cyw43_wifi_set_up(self->cyw, self->itf, mp_obj_is_true(args[1]), country);
|
||||||
if_active[self->itf] = value;
|
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -320,17 +311,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(network_cyw43_disconnect_obj, network_cyw43_dis
|
|||||||
|
|
||||||
static mp_obj_t network_cyw43_isconnected(mp_obj_t self_in) {
|
static mp_obj_t network_cyw43_isconnected(mp_obj_t self_in) {
|
||||||
network_cyw43_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
network_cyw43_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
bool result = (cyw43_tcpip_link_status(self->cyw, self->itf) == CYW43_LINK_UP);
|
return mp_obj_new_bool(cyw43_tcpip_link_status(self->cyw, self->itf) == 3);
|
||||||
|
|
||||||
if (result && self->itf == CYW43_ITF_AP) {
|
|
||||||
// For AP we need to not only know if the link is up, but also if any stations
|
|
||||||
// have associated.
|
|
||||||
uint8_t mac_buf[6];
|
|
||||||
int num_stas = 1;
|
|
||||||
cyw43_wifi_ap_get_stas(self->cyw, &num_stas, mac_buf);
|
|
||||||
result = num_stas > 0;
|
|
||||||
}
|
|
||||||
return mp_obj_new_bool(result);
|
|
||||||
}
|
}
|
||||||
static MP_DEFINE_CONST_FUN_OBJ_1(network_cyw43_isconnected_obj, network_cyw43_isconnected);
|
static MP_DEFINE_CONST_FUN_OBJ_1(network_cyw43_isconnected_obj, network_cyw43_isconnected);
|
||||||
|
|
||||||
@@ -370,15 +351,13 @@ static mp_obj_t network_cyw43_status(size_t n_args, const mp_obj_t *args) {
|
|||||||
if (self->itf != CYW43_ITF_AP) {
|
if (self->itf != CYW43_ITF_AP) {
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("AP required"));
|
mp_raise_ValueError(MP_ERROR_TEXT("AP required"));
|
||||||
}
|
}
|
||||||
static const unsigned mac_len = 6;
|
int num_stas;
|
||||||
static const unsigned max_stas = 32;
|
uint8_t macs[32 * 6];
|
||||||
int num_stas = max_stas;
|
|
||||||
uint8_t macs[max_stas * mac_len];
|
|
||||||
cyw43_wifi_ap_get_stas(self->cyw, &num_stas, macs);
|
cyw43_wifi_ap_get_stas(self->cyw, &num_stas, macs);
|
||||||
mp_obj_t list = mp_obj_new_list(num_stas, NULL);
|
mp_obj_t list = mp_obj_new_list(num_stas, NULL);
|
||||||
for (int i = 0; i < num_stas; ++i) {
|
for (int i = 0; i < num_stas; ++i) {
|
||||||
mp_obj_t tuple[1] = {
|
mp_obj_t tuple[1] = {
|
||||||
mp_obj_new_bytes(&macs[i * mac_len], mac_len),
|
mp_obj_new_bytes(&macs[i * 6], 6),
|
||||||
};
|
};
|
||||||
((mp_obj_list_t *)MP_OBJ_TO_PTR(list))->items[i] = mp_obj_new_tuple(1, tuple);
|
((mp_obj_list_t *)MP_OBJ_TO_PTR(list))->items[i] = mp_obj_new_tuple(1, tuple);
|
||||||
}
|
}
|
||||||
@@ -466,10 +445,6 @@ static mp_obj_t network_cyw43_config(size_t n_args, const mp_obj_t *args, mp_map
|
|||||||
mp_raise_TypeError(MP_ERROR_TEXT("can't specify pos and kw args"));
|
mp_raise_TypeError(MP_ERROR_TEXT("can't specify pos and kw args"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// A number of these options only update buffers in memory, and
|
|
||||||
// won't do anything until the interface is cycled down and back up
|
|
||||||
bool cycle_active = false;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < kwargs->alloc; ++i) {
|
for (size_t i = 0; i < kwargs->alloc; ++i) {
|
||||||
if (MP_MAP_SLOT_IS_FILLED(kwargs, i)) {
|
if (MP_MAP_SLOT_IS_FILLED(kwargs, i)) {
|
||||||
mp_map_elem_t *e = &kwargs->table[i];
|
mp_map_elem_t *e = &kwargs->table[i];
|
||||||
@@ -482,7 +457,6 @@ static mp_obj_t network_cyw43_config(size_t n_args, const mp_obj_t *args, mp_map
|
|||||||
}
|
}
|
||||||
case MP_QSTR_channel: {
|
case MP_QSTR_channel: {
|
||||||
cyw43_wifi_ap_set_channel(self->cyw, mp_obj_get_int(e->value));
|
cyw43_wifi_ap_set_channel(self->cyw, mp_obj_get_int(e->value));
|
||||||
cycle_active = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MP_QSTR_ssid:
|
case MP_QSTR_ssid:
|
||||||
@@ -490,7 +464,6 @@ static mp_obj_t network_cyw43_config(size_t n_args, const mp_obj_t *args, mp_map
|
|||||||
size_t len;
|
size_t len;
|
||||||
const char *str = mp_obj_str_get_data(e->value, &len);
|
const char *str = mp_obj_str_get_data(e->value, &len);
|
||||||
cyw43_wifi_ap_set_ssid(self->cyw, len, (const uint8_t *)str);
|
cyw43_wifi_ap_set_ssid(self->cyw, len, (const uint8_t *)str);
|
||||||
cycle_active = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MP_QSTR_monitor: {
|
case MP_QSTR_monitor: {
|
||||||
@@ -510,7 +483,6 @@ static mp_obj_t network_cyw43_config(size_t n_args, const mp_obj_t *args, mp_map
|
|||||||
}
|
}
|
||||||
case MP_QSTR_security: {
|
case MP_QSTR_security: {
|
||||||
cyw43_wifi_ap_set_auth(self->cyw, mp_obj_get_int(e->value));
|
cyw43_wifi_ap_set_auth(self->cyw, mp_obj_get_int(e->value));
|
||||||
cycle_active = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MP_QSTR_key:
|
case MP_QSTR_key:
|
||||||
@@ -518,7 +490,6 @@ static mp_obj_t network_cyw43_config(size_t n_args, const mp_obj_t *args, mp_map
|
|||||||
size_t len;
|
size_t len;
|
||||||
const char *str = mp_obj_str_get_data(e->value, &len);
|
const char *str = mp_obj_str_get_data(e->value, &len);
|
||||||
cyw43_wifi_ap_set_password(self->cyw, len, (const uint8_t *)str);
|
cyw43_wifi_ap_set_password(self->cyw, len, (const uint8_t *)str);
|
||||||
cycle_active = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MP_QSTR_pm: {
|
case MP_QSTR_pm: {
|
||||||
@@ -548,13 +519,6 @@ static mp_obj_t network_cyw43_config(size_t n_args, const mp_obj_t *args, mp_map
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the interface is already active, cycle it down and up
|
|
||||||
if (cycle_active && if_active[self->itf]) {
|
|
||||||
uint32_t country = get_country_code();
|
|
||||||
cyw43_wifi_set_up(self->cyw, self->itf, false, country);
|
|
||||||
cyw43_wifi_set_up(self->cyw, self->itf, true, country);
|
|
||||||
}
|
|
||||||
|
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -230,7 +230,7 @@ static mp_obj_t network_esp_hosted_config(size_t n_args, const mp_obj_t *args, m
|
|||||||
case MP_QSTR_essid: {
|
case MP_QSTR_essid: {
|
||||||
esp_hosted_netinfo_t netinfo;
|
esp_hosted_netinfo_t netinfo;
|
||||||
esp_hosted_wifi_netinfo(&netinfo);
|
esp_hosted_wifi_netinfo(&netinfo);
|
||||||
return mp_obj_new_str_from_cstr(netinfo.ssid);
|
return mp_obj_new_str(netinfo.ssid, strlen(netinfo.ssid));
|
||||||
}
|
}
|
||||||
case MP_QSTR_security: {
|
case MP_QSTR_security: {
|
||||||
esp_hosted_netinfo_t netinfo;
|
esp_hosted_netinfo_t netinfo;
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ mp_obj_t mod_network_ipconfig(size_t n_args, const mp_obj_t *args, mp_map_t *kwa
|
|||||||
case MP_QSTR_dns: {
|
case MP_QSTR_dns: {
|
||||||
char addr_str[IPADDR_STRLEN_MAX];
|
char addr_str[IPADDR_STRLEN_MAX];
|
||||||
ipaddr_ntoa_r(dns_getserver(0), addr_str, sizeof(addr_str));
|
ipaddr_ntoa_r(dns_getserver(0), addr_str, sizeof(addr_str));
|
||||||
return mp_obj_new_str_from_cstr(addr_str);
|
return mp_obj_new_str(addr_str, strlen(addr_str));
|
||||||
}
|
}
|
||||||
case MP_QSTR_prefer: {
|
case MP_QSTR_prefer: {
|
||||||
return MP_OBJ_NEW_SMALL_INT(mp_mod_network_prefer_dns_use_ip_version);
|
return MP_OBJ_NEW_SMALL_INT(mp_mod_network_prefer_dns_use_ip_version);
|
||||||
@@ -219,7 +219,7 @@ mp_obj_t mod_network_nic_ipconfig(struct netif *netif, size_t n_args, const mp_o
|
|||||||
char addr_str[IPADDR_STRLEN_MAX];
|
char addr_str[IPADDR_STRLEN_MAX];
|
||||||
ipaddr_ntoa_r(netif_ip_addr6(netif, i), addr_str, sizeof(addr_str));
|
ipaddr_ntoa_r(netif_ip_addr6(netif, i), addr_str, sizeof(addr_str));
|
||||||
mp_obj_t tuple[4] = {
|
mp_obj_t tuple[4] = {
|
||||||
mp_obj_new_str_from_cstr(addr_str),
|
mp_obj_new_str(addr_str, strlen(addr_str)),
|
||||||
MP_OBJ_NEW_SMALL_INT(netif_ip6_addr_state(netif, i)),
|
MP_OBJ_NEW_SMALL_INT(netif_ip6_addr_state(netif, i)),
|
||||||
MP_OBJ_NEW_SMALL_INT(netif_ip6_addr_pref_life(netif, i)), // preferred
|
MP_OBJ_NEW_SMALL_INT(netif_ip6_addr_pref_life(netif, i)), // preferred
|
||||||
MP_OBJ_NEW_SMALL_INT(netif_ip6_addr_valid_life(netif, i))
|
MP_OBJ_NEW_SMALL_INT(netif_ip6_addr_valid_life(netif, i))
|
||||||
@@ -297,23 +297,20 @@ mp_obj_t mod_network_nic_ipconfig(struct netif *netif, size_t n_args, const mp_o
|
|||||||
char plain_ip[IPADDR_STRLEN_MAX];
|
char plain_ip[IPADDR_STRLEN_MAX];
|
||||||
char *split = strchr(input_str, '/');
|
char *split = strchr(input_str, '/');
|
||||||
const char *addr_str = input_str;
|
const char *addr_str = input_str;
|
||||||
int to_copy = MIN(sizeof(plain_ip) - 1, addr_len);
|
|
||||||
memcpy(plain_ip, addr_str, to_copy);
|
|
||||||
if (split) {
|
if (split) {
|
||||||
|
int to_copy = sizeof(plain_ip) - 1;
|
||||||
if (split - addr_str < to_copy) {
|
if (split - addr_str < to_copy) {
|
||||||
to_copy = split - addr_str;
|
to_copy = split - addr_str;
|
||||||
}
|
}
|
||||||
|
memcpy(plain_ip, addr_str, to_copy);
|
||||||
mp_obj_t prefix_obj = mp_parse_num_integer(split + 1, strlen(split + 1), 10, NULL);
|
mp_obj_t prefix_obj = mp_parse_num_integer(split + 1, strlen(split + 1), 10, NULL);
|
||||||
prefix_bits = mp_obj_get_int(prefix_obj);
|
prefix_bits = mp_obj_get_int(prefix_obj);
|
||||||
if (mp_obj_str_get_qstr(args[0]) == MP_QSTR_addr4) {
|
|
||||||
uint32_t mask = -(1u << (32 - prefix_bits));
|
|
||||||
ip_addr_set_ip4_u32_val(netmask, ((mask & 0xFF) << 24) | ((mask & 0xFF00) << 8) | ((mask >> 8) & 0xFF00) | ((mask >> 24) & 0xFF));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
netmask = netif->netmask;
|
|
||||||
}
|
}
|
||||||
plain_ip[to_copy] = '\0';
|
if (mp_obj_str_get_qstr(args[0]) == MP_QSTR_addr4) {
|
||||||
if (!ipaddr_aton(plain_ip, &ip_addr)) {
|
uint32_t mask = -(1u << (32 - prefix_bits));
|
||||||
|
ip_addr_set_ip4_u32_val(netmask, ((mask & 0xFF) << 24) | ((mask & 0xFF00) << 8) | ((mask >> 8) & 0xFF00) | ((mask >> 24) & 0xFF));
|
||||||
|
}
|
||||||
|
if (!ipaddr_aton(addr_str, &ip_addr)) {
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("invalid arguments"));
|
mp_raise_ValueError(MP_ERROR_TEXT("invalid arguments"));
|
||||||
}
|
}
|
||||||
if ((mp_obj_str_get_qstr(args[0]) == MP_QSTR_addr6) != IP_IS_V6(&ip_addr)
|
if ((mp_obj_str_get_qstr(args[0]) == MP_QSTR_addr6) != IP_IS_V6(&ip_addr)
|
||||||
|
|||||||
@@ -41,7 +41,6 @@
|
|||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
#include "py/misc.h"
|
#include "py/misc.h"
|
||||||
#include "py/mperrno.h"
|
#include "py/mperrno.h"
|
||||||
#include "py/parsenum.h"
|
|
||||||
#include "shared/netutils/netutils.h"
|
#include "shared/netutils/netutils.h"
|
||||||
#include "shared/runtime/softtimer.h"
|
#include "shared/runtime/softtimer.h"
|
||||||
#include "extmod/modnetwork.h"
|
#include "extmod/modnetwork.h"
|
||||||
@@ -76,8 +75,6 @@ typedef struct _nina_obj_t {
|
|||||||
#define SO_NO_CHECK (0x100a)
|
#define SO_NO_CHECK (0x100a)
|
||||||
#define NINAW10_POLL_INTERVAL (100)
|
#define NINAW10_POLL_INTERVAL (100)
|
||||||
|
|
||||||
#define IPADDR_STRLEN_MAX 46
|
|
||||||
|
|
||||||
#define is_nonblocking_error(errno) ((errno) == MP_EAGAIN || (errno) == MP_EWOULDBLOCK || (errno) == MP_EINPROGRESS)
|
#define is_nonblocking_error(errno) ((errno) == MP_EAGAIN || (errno) == MP_EWOULDBLOCK || (errno) == MP_EINPROGRESS)
|
||||||
|
|
||||||
#define debug_printf(...) // mp_printf(&mp_plat_print, __VA_ARGS__)
|
#define debug_printf(...) // mp_printf(&mp_plat_print, __VA_ARGS__)
|
||||||
@@ -90,8 +87,6 @@ static mp_sched_node_t mp_wifi_poll_node;
|
|||||||
static soft_timer_entry_t mp_wifi_poll_timer;
|
static soft_timer_entry_t mp_wifi_poll_timer;
|
||||||
static void network_ninaw10_deinit(void);
|
static void network_ninaw10_deinit(void);
|
||||||
|
|
||||||
static bool network_ninaw10_dhcp_active = false;
|
|
||||||
|
|
||||||
static bool network_ninaw10_poll_list_is_empty(void) {
|
static bool network_ninaw10_poll_list_is_empty(void) {
|
||||||
return MP_STATE_PORT(mp_wifi_poll_list) == NULL ||
|
return MP_STATE_PORT(mp_wifi_poll_list) == NULL ||
|
||||||
MP_STATE_PORT(mp_wifi_poll_list)->len == 0;
|
MP_STATE_PORT(mp_wifi_poll_list)->len == 0;
|
||||||
@@ -204,7 +199,6 @@ static mp_obj_t network_ninaw10_active(size_t n_args, const mp_obj_t *args) {
|
|||||||
mp_raise_msg_varg(&mp_type_OSError,
|
mp_raise_msg_varg(&mp_type_OSError,
|
||||||
MP_ERROR_TEXT("failed to initialize Nina-W10 module, error: %d"), error);
|
MP_ERROR_TEXT("failed to initialize Nina-W10 module, error: %d"), error);
|
||||||
}
|
}
|
||||||
network_ninaw10_dhcp_active = true;
|
|
||||||
// check firmware version
|
// check firmware version
|
||||||
uint8_t semver[NINA_FW_VER_LEN];
|
uint8_t semver[NINA_FW_VER_LEN];
|
||||||
if (nina_fw_version(semver) != 0) {
|
if (nina_fw_version(semver) != 0) {
|
||||||
@@ -266,7 +260,7 @@ static mp_obj_t network_ninaw10_connect(mp_uint_t n_args, const mp_obj_t *pos_ar
|
|||||||
static const mp_arg_t allowed_args[] = {
|
static const mp_arg_t allowed_args[] = {
|
||||||
{ MP_QSTR_ssid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
{ MP_QSTR_ssid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||||
{ MP_QSTR_key, MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
{ MP_QSTR_key, MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||||
{ MP_QSTR_security, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = NINA_SEC_WPA_PSK} },
|
{ MP_QSTR_security, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
|
||||||
{ MP_QSTR_channel, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
|
{ MP_QSTR_channel, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -277,6 +271,7 @@ static mp_obj_t network_ninaw10_connect(mp_uint_t n_args, const mp_obj_t *pos_ar
|
|||||||
|
|
||||||
// get ssid
|
// get ssid
|
||||||
const char *ssid = mp_obj_str_get_str(args[ARG_ssid].u_obj);
|
const char *ssid = mp_obj_str_get_str(args[ARG_ssid].u_obj);
|
||||||
|
|
||||||
if (strlen(ssid) == 0) {
|
if (strlen(ssid) == 0) {
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("SSID can't be empty"));
|
mp_raise_ValueError(MP_ERROR_TEXT("SSID can't be empty"));
|
||||||
}
|
}
|
||||||
@@ -289,6 +284,12 @@ static mp_obj_t network_ninaw10_connect(mp_uint_t n_args, const mp_obj_t *pos_ar
|
|||||||
|
|
||||||
// get security mode
|
// get security mode
|
||||||
mp_uint_t security = args[ARG_security].u_int;
|
mp_uint_t security = args[ARG_security].u_int;
|
||||||
|
if (security == -1 && self->itf == MOD_NETWORK_STA_IF) {
|
||||||
|
security = NINA_SEC_WPA_PSK;
|
||||||
|
} else if (security == -1 && self->itf == MOD_NETWORK_AP_IF) {
|
||||||
|
security = NINA_SEC_WEP;
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure that the key is not empty if a security mode is used.
|
// Ensure that the key is not empty if a security mode is used.
|
||||||
if (security != NINA_SEC_OPEN && strlen(key) == 0) {
|
if (security != NINA_SEC_OPEN && strlen(key) == 0) {
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("key can't be empty"));
|
mp_raise_ValueError(MP_ERROR_TEXT("key can't be empty"));
|
||||||
@@ -319,6 +320,11 @@ static mp_obj_t network_ninaw10_connect(mp_uint_t n_args, const mp_obj_t *pos_ar
|
|||||||
soft_timer_reinsert(&mp_wifi_poll_timer, NINAW10_POLL_INTERVAL);
|
soft_timer_reinsert(&mp_wifi_poll_timer, NINAW10_POLL_INTERVAL);
|
||||||
} else {
|
} else {
|
||||||
mp_uint_t channel = args[ARG_channel].u_int;
|
mp_uint_t channel = args[ARG_channel].u_int;
|
||||||
|
|
||||||
|
if (security != NINA_SEC_OPEN && security != NINA_SEC_WEP) {
|
||||||
|
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("AP mode only supports WEP or OPEN security modes"));
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize WiFi in AP mode.
|
// Initialize WiFi in AP mode.
|
||||||
if (nina_start_ap(ssid, security, key, channel) != 0) {
|
if (nina_start_ap(ssid, security, key, channel) != 0) {
|
||||||
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("failed to start in AP mode"));
|
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("failed to start in AP mode"));
|
||||||
@@ -361,155 +367,11 @@ static mp_obj_t network_ninaw10_ifconfig(size_t n_args, const mp_obj_t *args) {
|
|||||||
netutils_parse_ipv4_addr(items[2], ifconfig.gateway_addr, NETUTILS_BIG);
|
netutils_parse_ipv4_addr(items[2], ifconfig.gateway_addr, NETUTILS_BIG);
|
||||||
netutils_parse_ipv4_addr(items[3], ifconfig.dns_addr, NETUTILS_BIG);
|
netutils_parse_ipv4_addr(items[3], ifconfig.dns_addr, NETUTILS_BIG);
|
||||||
nina_ifconfig(&ifconfig, true);
|
nina_ifconfig(&ifconfig, true);
|
||||||
network_ninaw10_dhcp_active = false;
|
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_ninaw10_ifconfig_obj, 1, 2, network_ninaw10_ifconfig);
|
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_ninaw10_ifconfig_obj, 1, 2, network_ninaw10_ifconfig);
|
||||||
|
|
||||||
mp_obj_t network_ninaw10_ipconfig(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
|
|
||||||
nina_ifconfig_t ifconfig;
|
|
||||||
// get ifconfig info
|
|
||||||
nina_ifconfig(&ifconfig, false);
|
|
||||||
|
|
||||||
if (kwargs->used == 0) {
|
|
||||||
// Get config value
|
|
||||||
if (n_args != 1) {
|
|
||||||
mp_raise_TypeError(MP_ERROR_TEXT("must query one param"));
|
|
||||||
}
|
|
||||||
switch (mp_obj_str_get_qstr(args[0])) {
|
|
||||||
case MP_QSTR_dns: {
|
|
||||||
return netutils_format_ipv4_addr(ifconfig.dns_addr, NETUTILS_BIG);
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("unexpected key"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Set config value(s)
|
|
||||||
if (n_args != 0) {
|
|
||||||
mp_raise_TypeError(MP_ERROR_TEXT("can't specify pos and kw args"));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < kwargs->alloc; ++i) {
|
|
||||||
if (MP_MAP_SLOT_IS_FILLED(kwargs, i)) {
|
|
||||||
mp_map_elem_t *e = &kwargs->table[i];
|
|
||||||
switch (mp_obj_str_get_qstr(e->key)) {
|
|
||||||
case MP_QSTR_dns: {
|
|
||||||
netutils_parse_ipv4_addr(e->value, ifconfig.dns_addr, NETUTILS_BIG);
|
|
||||||
nina_ifconfig(&ifconfig, true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("unexpected key"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
|
|
||||||
static mp_obj_t network_ninaw10_nic_ipconfig(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
|
|
||||||
nina_ifconfig_t ifconfig;
|
|
||||||
// get ifconfig info
|
|
||||||
nina_ifconfig(&ifconfig, false);
|
|
||||||
|
|
||||||
if (kwargs->used == 0) {
|
|
||||||
// Get config value
|
|
||||||
if (n_args != 2) {
|
|
||||||
mp_raise_TypeError(MP_ERROR_TEXT("must query one param"));
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (mp_obj_str_get_qstr(args[1])) {
|
|
||||||
case MP_QSTR_dhcp4: {
|
|
||||||
return mp_obj_new_bool(network_ninaw10_dhcp_active);
|
|
||||||
}
|
|
||||||
case MP_QSTR_has_dhcp4: {
|
|
||||||
uint16_t ip_sum =
|
|
||||||
ifconfig.ip_addr[0] + ifconfig.ip_addr[1] + ifconfig.ip_addr[2] + ifconfig.ip_addr[3];
|
|
||||||
if (network_ninaw10_dhcp_active) {
|
|
||||||
return mp_obj_new_bool(ip_sum != 0);
|
|
||||||
} else {
|
|
||||||
return mp_const_false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case MP_QSTR_addr4: {
|
|
||||||
mp_obj_t tuple[2] = {
|
|
||||||
netutils_format_ipv4_addr(ifconfig.ip_addr, NETUTILS_BIG),
|
|
||||||
netutils_format_ipv4_addr(ifconfig.subnet_addr, NETUTILS_BIG),
|
|
||||||
};
|
|
||||||
return mp_obj_new_tuple(2, tuple);
|
|
||||||
}
|
|
||||||
case MP_QSTR_gw4: {
|
|
||||||
return netutils_format_ipv4_addr(ifconfig.gateway_addr, NETUTILS_BIG);
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("unexpected key"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mp_const_none;
|
|
||||||
} else {
|
|
||||||
// Set config value(s)
|
|
||||||
if (n_args != 1) {
|
|
||||||
mp_raise_TypeError(MP_ERROR_TEXT("can't specify pos and kw args"));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < kwargs->alloc; ++i) {
|
|
||||||
if (MP_MAP_SLOT_IS_FILLED(kwargs, i)) {
|
|
||||||
mp_map_elem_t *e = &kwargs->table[i];
|
|
||||||
switch (mp_obj_str_get_qstr(e->key)) {
|
|
||||||
case MP_QSTR_dhcp4: {
|
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("DHCP control unsupported"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MP_QSTR_addr4: {
|
|
||||||
int prefix_bits = 32;
|
|
||||||
if (e->value != mp_const_none && mp_obj_is_str(e->value)) {
|
|
||||||
size_t addr_len;
|
|
||||||
const char *input_str = mp_obj_str_get_data(e->value, &addr_len);
|
|
||||||
char *split = strchr(input_str, '/');
|
|
||||||
if (split) {
|
|
||||||
mp_obj_t prefix_obj = mp_parse_num_integer(split + 1, strlen(split + 1), 10, NULL);
|
|
||||||
prefix_bits = mp_obj_get_int(prefix_obj);
|
|
||||||
uint32_t mask = -(1u << (32 - prefix_bits));
|
|
||||||
ifconfig.subnet_addr[0] = (mask >> 24) & 0xFF;
|
|
||||||
ifconfig.subnet_addr[1] = (mask >> 16) & 0xFF;
|
|
||||||
ifconfig.subnet_addr[2] = (mask >> 8) & 0xFF;
|
|
||||||
ifconfig.subnet_addr[3] = mask & 0xFF;
|
|
||||||
}
|
|
||||||
netutils_parse_ipv4_addr(e->value, ifconfig.ip_addr, NETUTILS_BIG);
|
|
||||||
} else if (e->value != mp_const_none) {
|
|
||||||
mp_obj_t *items;
|
|
||||||
mp_obj_get_array_fixed_n(e->value, 2, &items);
|
|
||||||
netutils_parse_ipv4_addr(items[0], ifconfig.ip_addr, NETUTILS_BIG);
|
|
||||||
netutils_parse_ipv4_addr(items[1], ifconfig.subnet_addr, NETUTILS_BIG);
|
|
||||||
}
|
|
||||||
nina_ifconfig(&ifconfig, true);
|
|
||||||
network_ninaw10_dhcp_active = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MP_QSTR_gw4: {
|
|
||||||
netutils_parse_ipv4_addr(e->value, ifconfig.gateway_addr, NETUTILS_BIG);
|
|
||||||
nina_ifconfig(&ifconfig, true);
|
|
||||||
network_ninaw10_dhcp_active = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("unexpected key"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
static MP_DEFINE_CONST_FUN_OBJ_KW(network_ninaw10_nic_ipconfig_obj, 1, network_ninaw10_nic_ipconfig);
|
|
||||||
|
|
||||||
static mp_obj_t network_ninaw10_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
|
static mp_obj_t network_ninaw10_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
|
||||||
nina_obj_t *self = MP_OBJ_TO_PTR(args[0]);
|
nina_obj_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||||
(void)self;
|
(void)self;
|
||||||
@@ -524,7 +386,7 @@ static mp_obj_t network_ninaw10_config(size_t n_args, const mp_obj_t *args, mp_m
|
|||||||
case MP_QSTR_ssid: {
|
case MP_QSTR_ssid: {
|
||||||
nina_netinfo_t netinfo;
|
nina_netinfo_t netinfo;
|
||||||
nina_netinfo(&netinfo);
|
nina_netinfo(&netinfo);
|
||||||
return mp_obj_new_str_from_cstr(netinfo.ssid);
|
return mp_obj_new_str(netinfo.ssid, strlen(netinfo.ssid));
|
||||||
}
|
}
|
||||||
case MP_QSTR_security: {
|
case MP_QSTR_security: {
|
||||||
nina_netinfo_t netinfo;
|
nina_netinfo_t netinfo;
|
||||||
@@ -994,7 +856,6 @@ static const mp_rom_map_elem_t nina_locals_dict_table[] = {
|
|||||||
{ MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&network_ninaw10_disconnect_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&network_ninaw10_disconnect_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&network_ninaw10_isconnected_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&network_ninaw10_isconnected_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&network_ninaw10_ifconfig_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&network_ninaw10_ifconfig_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_ipconfig), MP_ROM_PTR(&network_ninaw10_nic_ipconfig_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&network_ninaw10_config_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&network_ninaw10_config_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&network_ninaw10_status_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&network_ninaw10_status_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&network_ninaw10_ioctl_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&network_ninaw10_ioctl_obj) },
|
||||||
|
|||||||
@@ -1,326 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
|
||||||
*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2024 Damien P. George
|
|
||||||
*
|
|
||||||
* 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 "py/runtime.h"
|
|
||||||
#include "py/mphal.h"
|
|
||||||
#include "py/stream.h"
|
|
||||||
#include "extmod/modnetwork.h"
|
|
||||||
|
|
||||||
#if MICROPY_PY_NETWORK_PPP_LWIP
|
|
||||||
|
|
||||||
#include "lwip/dns.h"
|
|
||||||
#include "netif/ppp/ppp.h"
|
|
||||||
#include "netif/ppp/pppapi.h"
|
|
||||||
#include "netif/ppp/pppos.h"
|
|
||||||
|
|
||||||
// Enable this to see the serial data going between the PPP layer.
|
|
||||||
#define PPP_TRACE_IN_OUT (0)
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
STATE_INACTIVE,
|
|
||||||
STATE_ACTIVE,
|
|
||||||
STATE_ERROR,
|
|
||||||
STATE_CONNECTING,
|
|
||||||
STATE_CONNECTED,
|
|
||||||
} network_ppp_state_t;
|
|
||||||
|
|
||||||
typedef struct _network_ppp_obj_t {
|
|
||||||
mp_obj_base_t base;
|
|
||||||
network_ppp_state_t state;
|
|
||||||
int error_code;
|
|
||||||
mp_obj_t stream;
|
|
||||||
ppp_pcb *pcb;
|
|
||||||
struct netif netif;
|
|
||||||
} network_ppp_obj_t;
|
|
||||||
|
|
||||||
const mp_obj_type_t mp_network_ppp_lwip_type;
|
|
||||||
|
|
||||||
static mp_obj_t network_ppp___del__(mp_obj_t self_in);
|
|
||||||
|
|
||||||
static void network_ppp_status_cb(ppp_pcb *pcb, int err_code, void *ctx) {
|
|
||||||
network_ppp_obj_t *self = ctx;
|
|
||||||
switch (err_code) {
|
|
||||||
case PPPERR_NONE:
|
|
||||||
self->state = STATE_CONNECTED;
|
|
||||||
break;
|
|
||||||
case PPPERR_USER:
|
|
||||||
if (self->state >= STATE_ERROR) {
|
|
||||||
// Disable UART IRQ.
|
|
||||||
mp_obj_t dest[3];
|
|
||||||
mp_load_method(self->stream, MP_QSTR_irq, dest);
|
|
||||||
dest[2] = mp_const_none;
|
|
||||||
mp_call_method_n_kw(1, 0, dest);
|
|
||||||
// Indicate that the IRQ is disabled.
|
|
||||||
self->state = STATE_ACTIVE;
|
|
||||||
}
|
|
||||||
// Clean up the PPP PCB.
|
|
||||||
network_ppp___del__(MP_OBJ_FROM_PTR(self));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
self->state = STATE_ERROR;
|
|
||||||
self->error_code = err_code;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static mp_obj_t network_ppp_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
|
||||||
mp_arg_check_num(n_args, n_kw, 1, 1, false);
|
|
||||||
|
|
||||||
mp_obj_t stream = all_args[0];
|
|
||||||
|
|
||||||
mp_get_stream_raise(stream, MP_STREAM_OP_READ | MP_STREAM_OP_WRITE);
|
|
||||||
|
|
||||||
network_ppp_obj_t *self = mp_obj_malloc_with_finaliser(network_ppp_obj_t, type);
|
|
||||||
self->state = STATE_INACTIVE;
|
|
||||||
self->stream = stream;
|
|
||||||
self->pcb = NULL;
|
|
||||||
|
|
||||||
return MP_OBJ_FROM_PTR(self);
|
|
||||||
}
|
|
||||||
|
|
||||||
static mp_obj_t network_ppp___del__(mp_obj_t self_in) {
|
|
||||||
network_ppp_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
|
||||||
if (self->state >= STATE_ACTIVE) {
|
|
||||||
if (self->state >= STATE_ERROR) {
|
|
||||||
// Still connected over the UART stream.
|
|
||||||
// Force the connection to close, with nocarrier=1.
|
|
||||||
self->state = STATE_INACTIVE;
|
|
||||||
ppp_close(self->pcb, 1);
|
|
||||||
}
|
|
||||||
// Free PPP PCB and reset state.
|
|
||||||
self->state = STATE_INACTIVE;
|
|
||||||
ppp_free(self->pcb);
|
|
||||||
self->pcb = NULL;
|
|
||||||
}
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
static MP_DEFINE_CONST_FUN_OBJ_1(network_ppp___del___obj, network_ppp___del__);
|
|
||||||
|
|
||||||
static mp_obj_t network_ppp_poll(size_t n_args, const mp_obj_t *args) {
|
|
||||||
network_ppp_obj_t *self = MP_OBJ_TO_PTR(args[0]);
|
|
||||||
|
|
||||||
if (self->state <= STATE_ERROR) {
|
|
||||||
return MP_OBJ_NEW_SMALL_INT(-MP_EPERM);
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_int_t total_len = 0;
|
|
||||||
for (;;) {
|
|
||||||
uint8_t buf[256];
|
|
||||||
int err;
|
|
||||||
mp_uint_t len = mp_stream_rw(self->stream, buf, sizeof(buf), &err, 0);
|
|
||||||
if (len == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#if PPP_TRACE_IN_OUT
|
|
||||||
mp_printf(&mp_plat_print, "ppp_in(n=%u,data=", len);
|
|
||||||
for (size_t i = 0; i < len; ++i) {
|
|
||||||
mp_printf(&mp_plat_print, "%02x:", buf[i]);
|
|
||||||
}
|
|
||||||
mp_printf(&mp_plat_print, ")\n");
|
|
||||||
#endif
|
|
||||||
pppos_input(self->pcb, (u8_t *)buf, len);
|
|
||||||
total_len += len;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MP_OBJ_NEW_SMALL_INT(total_len);
|
|
||||||
}
|
|
||||||
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_ppp_poll_obj, 1, 2, network_ppp_poll);
|
|
||||||
|
|
||||||
static mp_obj_t network_ppp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
|
|
||||||
if (n_args != 1 && kwargs->used != 0) {
|
|
||||||
mp_raise_TypeError(MP_ERROR_TEXT("either pos or kw args are allowed"));
|
|
||||||
}
|
|
||||||
// network_ppp_obj_t *self = MP_OBJ_TO_PTR(args[0]);
|
|
||||||
|
|
||||||
if (kwargs->used != 0) {
|
|
||||||
for (size_t i = 0; i < kwargs->alloc; i++) {
|
|
||||||
if (mp_map_slot_is_filled(kwargs, i)) {
|
|
||||||
switch (mp_obj_str_get_qstr(kwargs->table[i].key)) {
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n_args != 2) {
|
|
||||||
mp_raise_TypeError(MP_ERROR_TEXT("can query only one param"));
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_obj_t val = mp_const_none;
|
|
||||||
|
|
||||||
switch (mp_obj_str_get_qstr(args[1])) {
|
|
||||||
default:
|
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("unknown config param"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
static MP_DEFINE_CONST_FUN_OBJ_KW(network_ppp_config_obj, 1, network_ppp_config);
|
|
||||||
|
|
||||||
static mp_obj_t network_ppp_status(mp_obj_t self_in) {
|
|
||||||
network_ppp_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
|
||||||
if (self->state == STATE_ERROR) {
|
|
||||||
return MP_OBJ_NEW_SMALL_INT(-self->error_code);
|
|
||||||
} else {
|
|
||||||
return MP_OBJ_NEW_SMALL_INT(self->state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static MP_DEFINE_CONST_FUN_OBJ_1(network_ppp_status_obj, network_ppp_status);
|
|
||||||
|
|
||||||
static u32_t network_ppp_output_callback(ppp_pcb *pcb, const void *data, u32_t len, void *ctx) {
|
|
||||||
network_ppp_obj_t *self = ctx;
|
|
||||||
#if PPP_TRACE_IN_OUT
|
|
||||||
mp_printf(&mp_plat_print, "ppp_out(n=%u,data=", len);
|
|
||||||
for (size_t i = 0; i < len; ++i) {
|
|
||||||
mp_printf(&mp_plat_print, "%02x:", ((const uint8_t *)data)[i]);
|
|
||||||
}
|
|
||||||
mp_printf(&mp_plat_print, ")\n");
|
|
||||||
#endif
|
|
||||||
int err;
|
|
||||||
// The return value from this output callback is the number of bytes written out.
|
|
||||||
// If it's less than the requested number of bytes then lwIP will propagate out an error.
|
|
||||||
return mp_stream_rw(self->stream, (void *)data, len, &err, MP_STREAM_RW_WRITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static mp_obj_t network_ppp_connect(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
|
||||||
enum { ARG_security, ARG_user, ARG_key };
|
|
||||||
static const mp_arg_t allowed_args[] = {
|
|
||||||
{ MP_QSTR_security, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = PPPAUTHTYPE_NONE} },
|
|
||||||
{ MP_QSTR_user, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
|
|
||||||
{ MP_QSTR_key, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
|
|
||||||
};
|
|
||||||
|
|
||||||
mp_arg_val_t parsed_args[MP_ARRAY_SIZE(allowed_args)];
|
|
||||||
mp_arg_parse_all(n_args - 1, args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, parsed_args);
|
|
||||||
|
|
||||||
network_ppp_obj_t *self = MP_OBJ_TO_PTR(args[0]);
|
|
||||||
|
|
||||||
if (self->state == STATE_INACTIVE) {
|
|
||||||
self->pcb = pppos_create(&self->netif, network_ppp_output_callback, network_ppp_status_cb, self);
|
|
||||||
if (self->pcb == NULL) {
|
|
||||||
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("pppos_create failed"));
|
|
||||||
}
|
|
||||||
self->state = STATE_ACTIVE;
|
|
||||||
|
|
||||||
// Enable UART IRQ to call PPP.poll() when incoming data is ready.
|
|
||||||
mp_obj_t dest[4];
|
|
||||||
mp_load_method(self->stream, MP_QSTR_irq, dest);
|
|
||||||
dest[2] = mp_obj_new_bound_meth(MP_OBJ_FROM_PTR(&network_ppp_poll_obj), MP_OBJ_FROM_PTR(self));
|
|
||||||
dest[3] = mp_load_attr(self->stream, MP_QSTR_IRQ_RXIDLE);
|
|
||||||
mp_call_method_n_kw(2, 0, dest);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self->state == STATE_CONNECTING || self->state == STATE_CONNECTED) {
|
|
||||||
mp_raise_OSError(MP_EALREADY);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (parsed_args[ARG_security].u_int) {
|
|
||||||
case PPPAUTHTYPE_NONE:
|
|
||||||
case PPPAUTHTYPE_PAP:
|
|
||||||
case PPPAUTHTYPE_CHAP:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("invalid auth"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parsed_args[ARG_security].u_int != PPPAUTHTYPE_NONE) {
|
|
||||||
const char *user_str = mp_obj_str_get_str(parsed_args[ARG_user].u_obj);
|
|
||||||
const char *key_str = mp_obj_str_get_str(parsed_args[ARG_key].u_obj);
|
|
||||||
ppp_set_auth(self->pcb, parsed_args[ARG_security].u_int, user_str, key_str);
|
|
||||||
}
|
|
||||||
|
|
||||||
netif_set_default(self->pcb->netif);
|
|
||||||
ppp_set_usepeerdns(self->pcb, true);
|
|
||||||
|
|
||||||
if (ppp_connect(self->pcb, 0) != ERR_OK) {
|
|
||||||
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("ppp_connect failed"));
|
|
||||||
}
|
|
||||||
|
|
||||||
self->state = STATE_CONNECTING;
|
|
||||||
|
|
||||||
// Do a poll in case there is data waiting on the input stream.
|
|
||||||
network_ppp_poll(1, args);
|
|
||||||
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
static MP_DEFINE_CONST_FUN_OBJ_KW(network_ppp_connect_obj, 1, network_ppp_connect);
|
|
||||||
|
|
||||||
static mp_obj_t network_ppp_disconnect(mp_obj_t self_in) {
|
|
||||||
network_ppp_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
|
||||||
if (self->state == STATE_CONNECTING || self->state == STATE_CONNECTED) {
|
|
||||||
// Initiate close and wait for PPPERR_USER callback.
|
|
||||||
ppp_close(self->pcb, 0);
|
|
||||||
}
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
static MP_DEFINE_CONST_FUN_OBJ_1(network_ppp_disconnect_obj, network_ppp_disconnect);
|
|
||||||
|
|
||||||
static mp_obj_t network_ppp_isconnected(mp_obj_t self_in) {
|
|
||||||
network_ppp_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
|
||||||
return mp_obj_new_bool(self->state == STATE_CONNECTED);
|
|
||||||
}
|
|
||||||
static MP_DEFINE_CONST_FUN_OBJ_1(network_ppp_isconnected_obj, network_ppp_isconnected);
|
|
||||||
|
|
||||||
static mp_obj_t network_ppp_ifconfig(size_t n_args, const mp_obj_t *args) {
|
|
||||||
network_ppp_obj_t *self = MP_OBJ_TO_PTR(args[0]);
|
|
||||||
return mod_network_nic_ifconfig(&self->netif, n_args - 1, args + 1);
|
|
||||||
}
|
|
||||||
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_ppp_ifconfig_obj, 1, 2, network_ppp_ifconfig);
|
|
||||||
|
|
||||||
static mp_obj_t network_ppp_ipconfig(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
|
|
||||||
network_ppp_obj_t *self = MP_OBJ_TO_PTR(args[0]);
|
|
||||||
return mod_network_nic_ipconfig(&self->netif, n_args - 1, args + 1, kwargs);
|
|
||||||
}
|
|
||||||
static MP_DEFINE_CONST_FUN_OBJ_KW(network_ppp_ipconfig_obj, 1, network_ppp_ipconfig);
|
|
||||||
|
|
||||||
static const mp_rom_map_elem_t network_ppp_locals_dict_table[] = {
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&network_ppp___del___obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&network_ppp_config_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&network_ppp_status_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&network_ppp_connect_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&network_ppp_disconnect_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&network_ppp_isconnected_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&network_ppp_ifconfig_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_ipconfig), MP_ROM_PTR(&network_ppp_ipconfig_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_poll), MP_ROM_PTR(&network_ppp_poll_obj) },
|
|
||||||
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_SEC_NONE), MP_ROM_INT(PPPAUTHTYPE_NONE) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_SEC_PAP), MP_ROM_INT(PPPAUTHTYPE_PAP) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_SEC_CHAP), MP_ROM_INT(PPPAUTHTYPE_CHAP) },
|
|
||||||
};
|
|
||||||
static MP_DEFINE_CONST_DICT(network_ppp_locals_dict, network_ppp_locals_dict_table);
|
|
||||||
|
|
||||||
MP_DEFINE_CONST_OBJ_TYPE(
|
|
||||||
mp_network_ppp_lwip_type,
|
|
||||||
MP_QSTR_PPP,
|
|
||||||
MP_TYPE_FLAG_NONE,
|
|
||||||
make_new, network_ppp_make_new,
|
|
||||||
locals_dict, &network_ppp_locals_dict
|
|
||||||
);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -58,11 +58,9 @@
|
|||||||
#include "shared/netutils/netutils.h"
|
#include "shared/netutils/netutils.h"
|
||||||
#include "lib/wiznet5k/Ethernet/wizchip_conf.h"
|
#include "lib/wiznet5k/Ethernet/wizchip_conf.h"
|
||||||
#include "lib/wiznet5k/Ethernet/socket.h"
|
#include "lib/wiznet5k/Ethernet/socket.h"
|
||||||
#include "lwip/apps/mdns.h"
|
|
||||||
#include "lwip/err.h"
|
#include "lwip/err.h"
|
||||||
#include "lwip/dns.h"
|
#include "lwip/dns.h"
|
||||||
#include "lwip/dhcp.h"
|
#include "lwip/dhcp.h"
|
||||||
#include "lwip/ethip6.h"
|
|
||||||
#include "netif/etharp.h"
|
#include "netif/etharp.h"
|
||||||
|
|
||||||
#define TRACE_ETH_TX (0x0002)
|
#define TRACE_ETH_TX (0x0002)
|
||||||
@@ -202,9 +200,6 @@ static void wiznet5k_config_interrupt(bool enabled) {
|
|||||||
void wiznet5k_deinit(void) {
|
void wiznet5k_deinit(void) {
|
||||||
for (struct netif *netif = netif_list; netif != NULL; netif = netif->next) {
|
for (struct netif *netif = netif_list; netif != NULL; netif = netif->next) {
|
||||||
if (netif == &wiznet5k_obj.netif) {
|
if (netif == &wiznet5k_obj.netif) {
|
||||||
#if LWIP_MDNS_RESPONDER
|
|
||||||
mdns_resp_remove_netif(&wiznet5k_obj.netif);
|
|
||||||
#endif
|
|
||||||
netif_remove(netif);
|
netif_remove(netif);
|
||||||
netif->flags = 0;
|
netif->flags = 0;
|
||||||
break;
|
break;
|
||||||
@@ -302,21 +297,13 @@ static err_t wiznet5k_netif_init(struct netif *netif) {
|
|||||||
netif->hwaddr_len = sizeof(netif->hwaddr);
|
netif->hwaddr_len = sizeof(netif->hwaddr);
|
||||||
int ret = WIZCHIP_EXPORT(socket)(0, Sn_MR_MACRAW, 0, 0);
|
int ret = WIZCHIP_EXPORT(socket)(0, Sn_MR_MACRAW, 0, 0);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
printf("WIZNET fatal error in netif_init: %d\n", ret);
|
printf("WIZNET fatal error in netifinit: %d\n", ret);
|
||||||
return ERR_IF;
|
return ERR_IF;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable MAC filtering so we only get frames destined for us, to reduce load on lwIP
|
// Enable MAC filtering so we only get frames destined for us, to reduce load on lwIP
|
||||||
setSn_MR(0, getSn_MR(0) | Sn_MR_MFEN);
|
setSn_MR(0, getSn_MR(0) | Sn_MR_MFEN);
|
||||||
|
|
||||||
#if LWIP_IPV6
|
|
||||||
netif->output_ip6 = ethip6_output;
|
|
||||||
netif->flags |= NETIF_FLAG_MLD6;
|
|
||||||
#else
|
|
||||||
// Drop IPv6 packets if firmware does not support it
|
|
||||||
setSn_MR(0, getSn_MR(0) | Sn_MR_MIP6B);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,12 +325,6 @@ static void wiznet5k_lwip_init(wiznet5k_obj_t *self) {
|
|||||||
self->netif.flags |= NETIF_FLAG_UP;
|
self->netif.flags |= NETIF_FLAG_UP;
|
||||||
dhcp_start(&self->netif);
|
dhcp_start(&self->netif);
|
||||||
self->netif.flags &= ~NETIF_FLAG_UP;
|
self->netif.flags &= ~NETIF_FLAG_UP;
|
||||||
|
|
||||||
#if LWIP_MDNS_RESPONDER
|
|
||||||
// NOTE: interface is removed in ::wiznet5k_deinit(), which is called as
|
|
||||||
// part of the init sequence.
|
|
||||||
mdns_resp_add_netif(&self->netif, mod_network_hostname_data);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wiznet5k_poll(void) {
|
void wiznet5k_poll(void) {
|
||||||
@@ -866,10 +847,6 @@ static mp_obj_t wiznet5k_active(size_t n_args, const mp_obj_t *args) {
|
|||||||
setSHAR(mac);
|
setSHAR(mac);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WIZNET5K_WITH_LWIP_STACK && LWIP_IPV6
|
|
||||||
netif_create_ip6_linklocal_address(&self->netif, 1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// seems we need a small delay after init
|
// seems we need a small delay after init
|
||||||
mp_hal_delay_ms(250);
|
mp_hal_delay_ms(250);
|
||||||
|
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ mp_import_stat_t mp_vfs_import_stat(const char *path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// delegate to vfs.stat() method
|
// delegate to vfs.stat() method
|
||||||
mp_obj_t path_o = mp_obj_new_str_from_cstr(path_out);
|
mp_obj_t path_o = mp_obj_new_str(path_out, strlen(path_out));
|
||||||
mp_obj_t stat;
|
mp_obj_t stat;
|
||||||
nlr_buf_t nlr;
|
nlr_buf_t nlr;
|
||||||
if (nlr_push(&nlr) == 0) {
|
if (nlr_push(&nlr) == 0) {
|
||||||
@@ -273,7 +273,7 @@ mp_obj_t mp_vfs_umount(mp_obj_t mnt_in) {
|
|||||||
mnt_str = mp_obj_str_get_data(mnt_in, &mnt_len);
|
mnt_str = mp_obj_str_get_data(mnt_in, &mnt_len);
|
||||||
}
|
}
|
||||||
for (mp_vfs_mount_t **vfsp = &MP_STATE_VM(vfs_mount_table); *vfsp != NULL; vfsp = &(*vfsp)->next) {
|
for (mp_vfs_mount_t **vfsp = &MP_STATE_VM(vfs_mount_table); *vfsp != NULL; vfsp = &(*vfsp)->next) {
|
||||||
if ((mnt_str != NULL && mnt_len == (*vfsp)->len && !memcmp(mnt_str, (*vfsp)->str, mnt_len)) || (*vfsp)->obj == mnt_in) {
|
if ((mnt_str != NULL && !memcmp(mnt_str, (*vfsp)->str, mnt_len + 1)) || (*vfsp)->obj == mnt_in) {
|
||||||
vfs = *vfsp;
|
vfs = *vfsp;
|
||||||
*vfsp = (*vfsp)->next;
|
*vfsp = (*vfsp)->next;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -46,45 +46,31 @@ void mp_vfs_blockdev_init(mp_vfs_blockdev_t *self, mp_obj_t bdev) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to minimise code size of read/write functions
|
|
||||||
// note the n_args argument is moved to the end for further code size reduction (args keep same position in caller and callee).
|
|
||||||
static int mp_vfs_blockdev_call_rw(mp_obj_t *args, size_t block_num, size_t block_off, size_t len, void *buf, size_t n_args) {
|
|
||||||
mp_obj_array_t ar = {{&mp_type_bytearray}, BYTEARRAY_TYPECODE, 0, len, buf};
|
|
||||||
args[2] = MP_OBJ_NEW_SMALL_INT(block_num);
|
|
||||||
args[3] = MP_OBJ_FROM_PTR(&ar);
|
|
||||||
args[4] = MP_OBJ_NEW_SMALL_INT(block_off); // ignored for n_args == 2
|
|
||||||
mp_obj_t ret = mp_call_method_n_kw(n_args, 0, args);
|
|
||||||
|
|
||||||
if (ret == mp_const_none) {
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
// Some block devices return a bool indicating success, so
|
|
||||||
// convert those to an errno integer code.
|
|
||||||
if (ret == mp_const_true) {
|
|
||||||
return 0;
|
|
||||||
} else if (ret == mp_const_false) {
|
|
||||||
return -MP_EIO;
|
|
||||||
}
|
|
||||||
// Block device functions are expected to return 0 on success
|
|
||||||
// and negative integer on errors. Check for positive integer
|
|
||||||
// results as some callers (i.e. littlefs) will produce corrupt
|
|
||||||
// results from these.
|
|
||||||
int i = MP_OBJ_SMALL_INT_VALUE(ret);
|
|
||||||
return i > 0 ? (-MP_EINVAL) : i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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];
|
mp_uint_t (*f)(uint8_t *, uint32_t, uint32_t) = (void *)(uintptr_t)self->readblocks[2];
|
||||||
return f(buf, block_num, num_blocks);
|
return f(buf, block_num, num_blocks);
|
||||||
} else {
|
} else {
|
||||||
return mp_vfs_blockdev_call_rw(self->readblocks, block_num, 0, num_blocks * self->block_size, buf, 2);
|
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[3] = MP_OBJ_FROM_PTR(&ar);
|
||||||
|
mp_call_method_n_kw(2, 0, self->readblocks);
|
||||||
|
// TODO handle error return
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int mp_vfs_blockdev_read_ext(mp_vfs_blockdev_t *self, size_t block_num, size_t block_off, size_t len, uint8_t *buf) {
|
int mp_vfs_blockdev_read_ext(mp_vfs_blockdev_t *self, size_t block_num, size_t block_off, size_t len, uint8_t *buf) {
|
||||||
return mp_vfs_blockdev_call_rw(self->readblocks, block_num, block_off, len, buf, 3);
|
mp_obj_array_t ar = {{&mp_type_bytearray}, BYTEARRAY_TYPECODE, 0, len, buf};
|
||||||
|
self->readblocks[2] = MP_OBJ_NEW_SMALL_INT(block_num);
|
||||||
|
self->readblocks[3] = MP_OBJ_FROM_PTR(&ar);
|
||||||
|
self->readblocks[4] = MP_OBJ_NEW_SMALL_INT(block_off);
|
||||||
|
mp_obj_t ret = mp_call_method_n_kw(3, 0, self->readblocks);
|
||||||
|
if (ret == mp_const_none) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return MP_OBJ_SMALL_INT_VALUE(ret);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int mp_vfs_blockdev_write(mp_vfs_blockdev_t *self, size_t block_num, size_t num_blocks, const uint8_t *buf) {
|
int mp_vfs_blockdev_write(mp_vfs_blockdev_t *self, size_t block_num, size_t num_blocks, const uint8_t *buf) {
|
||||||
@@ -97,7 +83,12 @@ int mp_vfs_blockdev_write(mp_vfs_blockdev_t *self, size_t block_num, size_t num_
|
|||||||
mp_uint_t (*f)(const uint8_t *, uint32_t, uint32_t) = (void *)(uintptr_t)self->writeblocks[2];
|
mp_uint_t (*f)(const uint8_t *, uint32_t, uint32_t) = (void *)(uintptr_t)self->writeblocks[2];
|
||||||
return f(buf, block_num, num_blocks);
|
return f(buf, block_num, num_blocks);
|
||||||
} else {
|
} else {
|
||||||
return mp_vfs_blockdev_call_rw(self->writeblocks, block_num, 0, num_blocks * self->block_size, (void *)buf, 2);
|
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[3] = MP_OBJ_FROM_PTR(&ar);
|
||||||
|
mp_call_method_n_kw(2, 0, self->writeblocks);
|
||||||
|
// TODO handle error return
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,7 +97,17 @@ int mp_vfs_blockdev_write_ext(mp_vfs_blockdev_t *self, size_t block_num, size_t
|
|||||||
// read-only block device
|
// read-only block device
|
||||||
return -MP_EROFS;
|
return -MP_EROFS;
|
||||||
}
|
}
|
||||||
return mp_vfs_blockdev_call_rw(self->writeblocks, block_num, block_off, len, (void *)buf, 3);
|
|
||||||
|
mp_obj_array_t ar = {{&mp_type_bytearray}, BYTEARRAY_TYPECODE, 0, len, (void *)buf};
|
||||||
|
self->writeblocks[2] = MP_OBJ_NEW_SMALL_INT(block_num);
|
||||||
|
self->writeblocks[3] = MP_OBJ_FROM_PTR(&ar);
|
||||||
|
self->writeblocks[4] = MP_OBJ_NEW_SMALL_INT(block_off);
|
||||||
|
mp_obj_t ret = mp_call_method_n_kw(3, 0, self->writeblocks);
|
||||||
|
if (ret == mp_const_none) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return MP_OBJ_SMALL_INT_VALUE(ret);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
|
|||||||
@@ -114,11 +114,6 @@ static mp_obj_t fat_vfs_mkfs(mp_obj_t bdev_in) {
|
|||||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the filesystem label if it's configured
|
|
||||||
#ifdef MICROPY_HW_FLASH_FS_LABEL
|
|
||||||
f_setlabel(&vfs->fatfs, MICROPY_HW_FLASH_FS_LABEL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
static MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_mkfs_fun_obj, fat_vfs_mkfs);
|
static MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_mkfs_fun_obj, fat_vfs_mkfs);
|
||||||
@@ -149,7 +144,7 @@ static mp_obj_t mp_vfs_fat_ilistdir_it_iternext(mp_obj_t self_in) {
|
|||||||
// make 4-tuple with info about this entry
|
// make 4-tuple with info about this entry
|
||||||
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(4, NULL));
|
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(4, NULL));
|
||||||
if (self->is_str) {
|
if (self->is_str) {
|
||||||
t->items[0] = mp_obj_new_str_from_cstr(fn);
|
t->items[0] = mp_obj_new_str(fn, strlen(fn));
|
||||||
} else {
|
} else {
|
||||||
t->items[0] = mp_obj_new_bytes((const byte *)fn, strlen(fn));
|
t->items[0] = mp_obj_new_bytes((const byte *)fn, strlen(fn));
|
||||||
}
|
}
|
||||||
@@ -296,7 +291,7 @@ static mp_obj_t fat_vfs_getcwd(mp_obj_t vfs_in) {
|
|||||||
if (res != FR_OK) {
|
if (res != FR_OK) {
|
||||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||||
}
|
}
|
||||||
return mp_obj_new_str_from_cstr(buf);
|
return mp_obj_new_str(buf, strlen(buf));
|
||||||
}
|
}
|
||||||
static MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_getcwd_obj, fat_vfs_getcwd);
|
static MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_getcwd_obj, fat_vfs_getcwd);
|
||||||
|
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ static mp_obj_t MP_VFS_LFSx(ilistdir_it_iternext)(mp_obj_t self_in) {
|
|||||||
// make 4-tuple with info about this entry
|
// make 4-tuple with info about this entry
|
||||||
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(4, NULL));
|
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(4, NULL));
|
||||||
if (self->is_str) {
|
if (self->is_str) {
|
||||||
t->items[0] = mp_obj_new_str_from_cstr(info.name);
|
t->items[0] = mp_obj_new_str(info.name, strlen(info.name));
|
||||||
} else {
|
} else {
|
||||||
t->items[0] = mp_obj_new_bytes((const byte *)info.name, strlen(info.name));
|
t->items[0] = mp_obj_new_bytes((const byte *)info.name, strlen(info.name));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ static mp_obj_t vfs_posix_getcwd(mp_obj_t self_in) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return mp_obj_new_str_from_cstr(ret);
|
return mp_obj_new_str(ret, strlen(ret));
|
||||||
}
|
}
|
||||||
static MP_DEFINE_CONST_FUN_OBJ_1(vfs_posix_getcwd_obj, vfs_posix_getcwd);
|
static MP_DEFINE_CONST_FUN_OBJ_1(vfs_posix_getcwd_obj, vfs_posix_getcwd);
|
||||||
|
|
||||||
@@ -234,7 +234,7 @@ static mp_obj_t vfs_posix_ilistdir_it_iternext(mp_obj_t self_in) {
|
|||||||
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(3, NULL));
|
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(3, NULL));
|
||||||
|
|
||||||
if (self->is_str) {
|
if (self->is_str) {
|
||||||
t->items[0] = mp_obj_new_str_from_cstr(fn);
|
t->items[0] = mp_obj_new_str(fn, strlen(fn));
|
||||||
} else {
|
} else {
|
||||||
t->items[0] = mp_obj_new_bytes((const byte *)fn, strlen(fn));
|
t->items[0] = mp_obj_new_bytes((const byte *)fn, strlen(fn));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,27 +160,12 @@ static mp_uint_t vfs_posix_file_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_
|
|||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
#define VFS_POSIX_STREAM_STDIO_ERR_CATCH (err == EINVAL || err == ENOTSUP)
|
#define VFS_POSIX_STREAM_STDIO_ERR_CATCH (err == EINVAL || err == ENOTSUP)
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
// In debug builds fsync (i.e. _commit on windows) will generate a debug report via _ASSERTE when
|
|
||||||
// called with non-redirected stdin/stdout/stderr (i.e. _isatty) handles because FlushFileBuffers,
|
|
||||||
// which it calls internally, will fail since console output is not buffered.
|
|
||||||
// In release builds it also fails, but merely returns an error which is handled appropriately below.
|
|
||||||
// The check for the handle being stdin/stdout/stderr is added explicitly because according to
|
|
||||||
// the documentation _isatty is also true for serial ports for instance.
|
|
||||||
#ifdef _DEBUG
|
|
||||||
if ((o->fd == STDIN_FILENO || o->fd == STDOUT_FILENO || o->fd == STDERR_FILENO) && _isatty(o->fd)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#define VFS_POSIX_STREAM_STDIO_ERR_CATCH (err == EINVAL || err == EBADF)
|
#define VFS_POSIX_STREAM_STDIO_ERR_CATCH (err == EINVAL || err == EBADF)
|
||||||
#else
|
#else
|
||||||
#define VFS_POSIX_STREAM_STDIO_ERR_CATCH (err == EINVAL)
|
#define VFS_POSIX_STREAM_STDIO_ERR_CATCH (err == EINVAL)
|
||||||
#endif
|
#endif
|
||||||
MP_HAL_RETRY_SYSCALL(ret, fsync(o->fd), {
|
MP_HAL_RETRY_SYSCALL(ret, fsync(o->fd), {
|
||||||
if (VFS_POSIX_STREAM_STDIO_ERR_CATCH
|
if (VFS_POSIX_STREAM_STDIO_ERR_CATCH
|
||||||
// Note: comparing fd against the standard FILENOs is technically not correct, for example:
|
|
||||||
// sys.stderr.close() in Python code results in close(STDERR_FILENO) here, but because
|
|
||||||
// open() uses the next available file descriptor, opening an arbitrary file with
|
|
||||||
// fd = open('/some/file') means that fd becomes STDERR_FILENO.
|
|
||||||
&& (o->fd == STDIN_FILENO || o->fd == STDOUT_FILENO || o->fd == STDERR_FILENO)) {
|
&& (o->fd == STDIN_FILENO || o->fd == STDOUT_FILENO || o->fd == STDERR_FILENO)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Submodule lib/arduino-lib updated: 8312406d6c...89424753e1
Submodule lib/libffi updated: 3d0ce1e6fc...e9de7e35f2
@@ -19,10 +19,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
// These lines verify that FLT_EVAL_METHOD==0, MicroPython's libm requires this.
|
#define FLT_EVAL_METHOD 0
|
||||||
// If compilation fails here then check the host compiler's FLT_EVAL_METHOD.
|
|
||||||
typedef float float_t;
|
|
||||||
typedef double double_t;
|
|
||||||
|
|
||||||
#define FORCE_EVAL(x) do { \
|
#define FORCE_EVAL(x) do { \
|
||||||
if (sizeof(x) == sizeof(float)) { \
|
if (sizeof(x) == sizeof(float)) { \
|
||||||
|
|||||||
@@ -24,9 +24,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "fdlibm.h"
|
#include "fdlibm.h"
|
||||||
#ifndef _IEEE_LIBM
|
|
||||||
#define _IEEE_LIBM 1
|
#define _IEEE_LIBM 1
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __STDC__
|
#ifdef __STDC__
|
||||||
float lgammaf(float x)
|
float lgammaf(float x)
|
||||||
|
|||||||
@@ -24,9 +24,7 @@
|
|||||||
|
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
#include "fdlibm.h"
|
#include "fdlibm.h"
|
||||||
#ifndef _IEEE_LIBM
|
|
||||||
#define _IEEE_LIBM 1
|
#define _IEEE_LIBM 1
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __STDC__
|
#ifdef __STDC__
|
||||||
float tgammaf(float x)
|
float tgammaf(float x)
|
||||||
|
|||||||
@@ -15,10 +15,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
// These lines verify that FLT_EVAL_METHOD==0, MicroPython's libm requires this.
|
#define FLT_EVAL_METHOD 0
|
||||||
// If compilation fails here then check the host compiler's FLT_EVAL_METHOD.
|
|
||||||
typedef float float_t;
|
|
||||||
typedef double double_t;
|
|
||||||
|
|
||||||
#define FORCE_EVAL(x) do { \
|
#define FORCE_EVAL(x) do { \
|
||||||
if (sizeof(x) == sizeof(float)) { \
|
if (sizeof(x) == sizeof(float)) { \
|
||||||
|
|||||||
2
lib/lwip
2
lib/lwip
Submodule lib/lwip updated: 0a0452b2c3...6ca936f6b5
Submodule lib/micropython-lib updated: 68e3e07bc7...50ed36fbeb
Submodule lib/pico-sdk updated: bddd20f928...6a7db34ff6
18
lib/tinytest/README
Normal file
18
lib/tinytest/README
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
Tinytest is a tiny little test framework written in C by Nick Mathewson.
|
||||||
|
|
||||||
|
It is distributed under the 3-clause BSD license. You can use it in
|
||||||
|
your own programs so long as you follow the license's conditions.
|
||||||
|
|
||||||
|
It's been tested on Windows, Mac, and many of the free Unixes.
|
||||||
|
|
||||||
|
It knows how to fork before running certain tests, and it makes
|
||||||
|
text-mode output in a format I like.
|
||||||
|
|
||||||
|
For info on how to use it, check out tinytest_demo.c.
|
||||||
|
|
||||||
|
You can get the latest version using Git, by pulling from
|
||||||
|
git://github.com/nmathewson/tinytest.git
|
||||||
|
|
||||||
|
Patches are welcome. Patches that turn this from tinytest to hugetest
|
||||||
|
will not be applied. If you want a huge test framework, use CUnit.
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user